Moving GameObject without transform.position through a touchscreen? (In Unity3d) - performance

I'm developing a mobile game in Unity3d which the player needs to move a stick that is placed just a little bit higher then the finger with transform.position and block a ball that is moved with Force.Mode2D.impulse. The problem is that the ball goes through the stick if the stick is moved too fast. Could anyone please teach me how to code the stick movement with Force (or any other way that works) that still moves according to the finger position on touch screen ( A.K.A Input.mousePosition) instead of using buttons?
The code goes as such if anyone needs the info;
Stick:
float defencePosX = Mathf.Clamp( Input.mousePosition.x / Screen.width * 5.6f - 2.8f , -2.8f, 2.8f);
float defencePosY = Mathf.Clamp( Input.mousePosition.y / Screen.height * 10 - 4f, -3.3f, -0.5f);
this.transform.position = new Vector3 (defencePosX, defencePosY, 0);
Ball:
projectileSpeed = Random.Range (maxSpeed, minSpeed);
projectileSwing = Random.Range (-0.001f, 0.001f);
rb.AddForce (new Vector2 (projectileSwing * 1000, 0), ForceMode2D.Impulse);
rb.AddForce (new Vector2 (0, projectileSpeed), ForceMode2D.Impulse);
a video of the bug:
https://youtu.be/cr2LVBlP2O0
basicly if i dont move the stick it hits but if i move it fast the ball goes right through. (the bouncing sound effect doesnt work if itss too fast as well)

When working with physics objects, you'll want to use just the Rigidbody component when moving them. Otherwise, it's interpreted as a teleport and no physics is applied and no movement is calculated.
Try using Rigidbody.MovePosition instead of transform.position.
Also, make sure the Rigidbody components on your stick AND ball both have collisionDetectionMode set to 'Continuous Dynamic'. That's how you get small fast-moving physics objects to hit one another in between frames.
float defencePosX = Mathf.Clamp( Input.mousePosition.x / Screen.width * 5.6f - 2.8f , -2.8f, 2.8f);
float defencePosY = Mathf.Clamp( Input.mousePosition.y / Screen.height * 10 - 4f, -3.3f, -0.5f);
rb.MovePosition(new Vector3 (defencePosX, defencePosY, 0));

Id recommend that you set the balls force to Vector3.zero before adding force to it, or that you use the collider of your blocking movement as a bounce pad for the ball.
Please remember to check that your colliders are scaled correctly according to the blocker.
A video displaying your issue would be helpful to understand it better.

Related

How to invert the sprite position in GameMaker Studio 2 code?

I put this code for my sprite to reverse the position according to its direction but it reverses the position and it looks skinny. How to fix this?
key_left = keyboard_check(ord("A"))
key_right = keyboard_check(ord("D"))
key_jump = keyboard_check(vk_space)
var move = key_right - key_left
hspd = move * spd;
vspd = vspd + grv;
if (hspd != 0) {
image_xscale = sign(hspd)
}
The code's correct. You must have resized the sprite in the room editor, delete the instance and put it in again and don't resize it, it should work.
Also if you need it a little bigger you can (If 1.5 doesn't satisfy you, feel free to use a bigger number).
image_xscale = sign(hspd) * 1.5;
The code seem to be correct, have you tried setting the origin point at the center? By default the origin point is on the top-left, and once it's set at the center of your sprite, it won't change positions when turning around.
You can set the origin point at the sprite window.

Animate (walk) gltf clone objects from one position to another

I am working on a project where I imported a gltf humanoid that has animations. I am creating clones of the imported model to display in the scene, rather than creating a new one every time.
I have walk and idle animations for the loaded model. How can I animate the cloned in such a way that it appears like they are walking from one location to another another. For example, if the cloned model is at position (10, 20, 0) at time = 1s and it will be at position (13, 20, 0) at time = 2s, I would like it to appear that the model is walking between the positions. I read the new Animation System documentation and did a lot of searching but it didn't help.
Thanks for your help.
P.S: I cannot share the code from the project due to restrictions.
You can get the direction by subtracting both vectors and then normalizing it.
let direction = new THREE.Vector3().subVectors(destination.position, object.position).normalize();
Then in your render function update object position on each frame in that direction. Speed variable value is up to you (default 1).
object.position.x += direction.x * speed;
object.position.y += direction.y * speed;
object.position.z += direction.z * speed;
You would need a boolean value like isMoving or distance between objects to know when to start and stop.
object.position.distanceTo( destination.position );
https://threejs.org/docs/#api/en/math/Vector3.distanceTo
As for the animation I think you just want to call animation.play() on start and animation.stop() when you reach the destination.

threejs camera movement lags

I'm playing around with threejs and want to create an rts game. So currently i want to create my own camera controller in order to move around the terrain. The problem is, that the movement lags, even though my fps is always between 35-50 FPS (60FPS works fine). I thought, the human eye shouldn't see something like lags with this framerate, am i wrong?
I've also calculated the movement in dependence of the delta time.
var translation = new Vector3();
// Move camera with keys.
if (Keyboard.IsKeyDown(Key.W))
translation.z -= (deltaTime * 200);
if (Keyboard.IsKeyDown(Key.S))
translation.z += (deltaTime * 200);
if (Keyboard.IsKeyDown(Key.D))
translation.x += (deltaTime * 200);
if (Keyboard.IsKeyDown(Key.A))
translation.x -= (deltaTime * 200);
Game.Camera.position.add(translation);
For testing purposes (But with 60 FPS everything works fine):
http://app.lypster.net
Is it possible to solve the problem or is it a WebGL thing? I can't remember this behavior in XNA.
Kind Regards
Chris

How to use Transformation Matrix for SpriteBatch correctly?

I'm new to XNA and would like to develop a light-weight 2D engine over it, with the entities organized into parent-child hierarchy. I think of matrix when drawing children, because their position, rotation and scale are depend on their parent.
If I use SpriteBatch.Begin(), my rectangles can be drawn on the screen, but when I change them into:
this.DrawingMatrix = Matrix.Identity;
this.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullClockwise, null, this.DrawingMatrix);
nothing is drawn anymore. I even tried new Matrix() or Matrix.CreateTranslation(0, 0, 0) for DrawingMatrix.
My first question is: why doesn't it work? I'm not working with any camera or viewport.
Secondly, before drawing an entity, I call the PreDraw to transform the matrix (I will then reset to original state at PostDraw):
protected virtual void PreDraw(Engine pEngine)
{
pEngine.DrawingMatrix *=
Matrix.CreateTranslation(this.X, this.Y, 0) *
Matrix.CreateScale(this.ScaleX, this.ScaleY, 1) *
Matrix.CreateRotationZ(this.Rotation);
}
Please clarify the correction of above code. And I need to scale not at the origin, but at ScaleCenterX and ScaleCenterY, how can I achieve this?
ADDED: Here is an example of my engine's draw process:
Call these code:
this.DrawingMatrix = Matrix.CreateTranslation(0, 0, 0);
this.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullClockwise, null, this.DrawingMatrix);
Call PreDraw(), with is:
protected virtual void PreDraw(Engine pEngine)
{
pEngine.DrawingMatrix *=
Matrix.CreateTranslation(this.X, this.Y, 0) *
Matrix.CreateScale(this.ScaleX, this.ScaleY, 1) *
Matrix.CreateRotationZ(this.Rotation);
}
Call Draw(), for example, in my Rect class:
protected override void Draw(Engine pEngine)
{
pEngine.SpriteBatch.Draw(pEngine.RectangleTexture, new Rectangle(0, 0, (int)this.Width, (int)this.Height), new Rectangle(0, 0, 1, 1), this.Color);
}
If I replace above Begin code with this.SpriteBatch.Begin(), the rectangle is drawn correctly, so I guess it is because of the matrix.
First issue is a simple bug: The default for SpriteBatch is CullCounterClockwise, but you have specified CullClockwise causing all your sprites to get back-face-culled. You can pass null if you just want to use the default render states - you don't need to specify them explicitly.
(You would need to change the cull mode if you used a negative scale.)
To answer your second question: You need to translate "back" to place the scaling origin (your ScaleCenterX and ScaleCenterY) at the world origin (0,0). Transformations always happen around (0,0). So normally the order is: translate sprite origin back to the world origin, scale, rotate, translate to place sprite origin at desired world position.
Also, I hope that your PostDraw is not applying the reverse transformations (you made it sound like it does). That is very likely to cause precision problems. You should save and restore the matrix instead.

Zoom toward mouse (eg. Google maps)

I've written a home-brew view_port class for a 2D strategy game. The panning (with arrow keys) and zooming (with mouse wheel) work fine, but I'd like the view to also home towards wherever the cursor is placed, as in Google Maps or Supreme Commander
I'll spare you the specifics of how the zoom is implemented and even what language I'm using: this is all irrelevant. What's important is the zoom function, which modifies the rectangle structure (x,y,w,h) that represents the view. So far the code looks like this:
void zoom(float delta, float mouse_x, float mouse_y)
{
zoom += delta;
view.w = window.w/zoom;
view.h = window.h/zoom;
// view.x = ???
// view.y = ???
}
Before somebody suggests it, the following will not work:
view.x = mouse_x - view.w/2;
view.y = mouse_y - view.h/2;
This picture illustrates why, as I attempt to zoom towards the smiley face:
As you can see when the object underneath the mouse is placed in the centre of the screen it stops being under the mouse, so we stop zooming towards it!
If you've got a head for maths (you'll need one) any help on this would be most appreciated!
I managed to figure out the solution, thanks to a lot of head-scratching a lot of little picture: I'll post the algorithm here in case anybody else needs it.
Vect2f mouse_true(mouse_position.x/zoom + view.x, mouse_position.y/zoom + view.y);
Vect2f mouse_relative(window_size.x/mouse_pos.x, window_size.y/mouse_pos.y);
view.x = mouse_true.x - view.w/mouse_relative.x;
view.y = mouse_true.y - view.h/mouse_relative.y;
This ensures that objects placed under the mouse stay under the mouse. You can check out the code over on github, and I also made a showcase demo for youtube.
In my concept there is a camera and a screen.
The camera is the moving part. The screen is the scalable part.
I made an example script including a live demo.
The problem is reduced to only one dimension in order to keep it simple.
https://www.khanacademy.org/cs/cam-positioning/4772921545326592
var a = (mouse.x + camera.x) / zoom;
// now increase the zoom e.g.: like that:
zoom = zoom + 1;
var newPosition = a * zoom - mouse.x;
camera.setX(newPosition);
screen.setWidth(originalWidth * zoom);
For a 2D example you can simply add the same code for the height and y positions.

Resources