I'm developing a 2.5D mobile game with Unity. In order to move the character back and forward I'm using a piece of code inside the update function:
void Update () {
if (shouldMove==true){
transform.Translate(Vector3.forward * 3 * Time.deltaTime);
}
}
So that code works pretty well when the game is running at 60 fps, but when the fps go down to 30 or less, the character starts to vibrate while moving. I've tried to test the same code with a plane terrain and it worked well, so maybe the problem is the collision between the character's and the terrain's colliders. However, I don't understand why if the fps are high it works well. I've tried both capsule collider and a mesh collider but no one has worked. What do you think? Should I try to use another code?
Edit 1: I'm using a capsule collider and a rigidbody. Should I use a Character Controller?
Sam Bauwens is absolutely right in his response, however, this issue normally is caused due to an excess of objects (specially those which are animated). This can worsen the performance a lot.
You should try to delete some of the objects and try if your character still vibrates. If it doesn't, that means that I'm right. Of course, you won't want to delete objects of your scene, so, you can add an asset such as SmartLOD that deletes the geometry of those objects that are not shown on screen and thus enhances your game's performance.
Hope it helps.
I had a similar problem with a ball that vibrates on the ground. It was caused by gravity which is pulling the gameobject towards the ground, then it collides on the ground and bounces. If your problem is the same as me, you have to either tune the Fixed Timestep (Edit => Project settings => time) and/or Bounce Threshold (Edit => Project Settings => Physics).
By increasing Bounce Threshold, you're going to increase the minimum speed below which an object won't bounce, so that the force of gravity won't be big enough to make the ball's velocity exceed the bounce threshold.
By reducing Physics time step, you reduce the impact of gravity for each time step because the time steps are smaller and therefore the amount of velocity added to the gameobject for each timestep is smaller.
EDIT: you can also look at sleep velocity (Edit => Project Settings => Physics), because if it is higher that the gravity velocity, the object shouldn't vibrate.
Related
When in the game editor the game runs as intended and we can pick-up each object selected and move it from point A to point B. When building the game the game starts as intended but after a few moments, we noticed that the collider triggers for the object we want to be picked up are moving upwards indefinitely. There is an animation attached to the floor which will move the player and objects up when activated but the player has to complete a task for the animation to start.
We noticed this because we have an indicator which shows when the RayCast hovers over the collider to pick up the object, and it moves upwards after start.
This issue occurs on every object intended to be picked up in the scene that the player is currently in.
In editor the colliders don't move and the items can be picked up as intended but the issue came about ONLY when trying to build the game.
Tried:
Adding kinematics
Removing gravity
Removing every animation attached in the scene
Changing each part of the objects RigidBody
Changing the Awake() on pick-up script
Running in developer mode
Is this an issue where you're not accounting for the framerate? In other words, do you need to incorporate Time.deltaTime in your Update loop somewhere? This feels like that because I'm thinking the frame rates could differ drastically between the unoptimized editor environment, and a full build.
For example, if I'm moving an object 10 units each frame like this:
Update()
{
// Move to the right
transform.Position.x += 10;
}
Then that is frame rate dependent. On a device with a low framerate, the object will move slower than on a device with a high frame rate. On a 30 average fps device the object will move 300 units per second. On a 120 fps device the object will move 1,200 units!
That code should look something like this to account for frame rate changes:
Update()
{
// Move to the right
transform.Position.x += 10 * Time.deltaTime;
}
You may need to adjust the "10" value because now it's related to how fast the object is moving per second. Each Update will move the object a proportional amount of time for that frame.
(The above implementation probably isn't perfect, and introducing things like networking/multiplayer could require additional changes.)
See the docs for more information about Time.deltaTime
I'm currently trying to make a game to put my relatively new coding knowledge to test. I figured I learn a lot quicker by just doing things and seeing what happens. I'm currently working on a plane and the last couple of days I made a functional camera system (to rotate around the player based on the mouse) and some animations of the plane. I'm currently trying to create a movement system in which the down key rotates the player up. I noticed however that my AddForce function doesn't do what I want it to do. I'd like the plane to move in the Z axis depending on the current rotation of said plane instead of it just heading into the Z angle of the world.
I'm currently working on this snippet:
//Acceleration
if (gameObject.CompareTag("Player") && playerRb.velocity.z > -349)
{
playerRb.AddRelativeForce(0, 0, -playerSpeed, ForceMode.Acceleration);
}
else if (gameObject.CompareTag("Player") && playerRb.velocity.z < -349)
{
playerRb.velocity = new Vector3(playerRb.velocity.x, playerRb.velocity.y, -350);
}
//
//Movement
//Up/down controls
if (gameObject.CompareTag("Player") && Input.GetKey(KeyCode.DownArrow))
{
transform.Rotate((0.07f * playerSpeed) * Time.deltaTime, 0, 0);
}
As you can see I already tried AddRelativeForce as another topic mentioned but that doesn't seem to work for me. The moment it hits an edge it just falls down into the abyss regardless of it's rotation.
Additionally, I was considering using another AddForce function on the rotate as it doesn't leave the ground (considering it keeps hitting the floor with its tail), is there any way to apply a force on an object from a specific position/angle? (such as the front of the plane).
Thanks in advance!
I think the reason your plane is acting strange is not because of your addrelative force call -- it's because you are setting velocity. playerRb.velocity = new Vector3(playerRb.velocity.x, playerRb.velocity.y, -350); assigns the velocity to push you -350 in the world's z axis, which probably isn't what you want. Velocity is in the global space. Remove that and see what happens.
On a more general note, If you're using physics, try to use only forces and torquees. Using transform.Rotate to change a rigidbody's rotation while physics is active will just make your life difficult, and make the rigidbody do strange things. I do change the velocity of rigidbodies sometimes, but not in every frame. I just don't know enough about physics to mess with velocities that way.
Also, make sure you're doing these things in a FixedUpdate function, since that is where input that affects physics is supposed to be checked.
I am working on a Unity game in a 2D environment. The player GameObject has a Rigidbody2D attached. It moves horizontally when swiping. When swipe is too fast, it does not collide with the Colliders. Maybe it changes its transform position before detecting collision? It does not happen when the swipe is slow.
Based upon your problem I am assuming you are moving your object in the Update() function (please correct me if not). This means you are moving the object a certain amount every frame. However, Unity checks colliders and does physics calculations on a different time interval (Fixed Timestep, https://docs.unity3d.com/Manual/class-TimeManager.html).
Just before the objects collide, the colliders are checked. Unity calculates colliders every Fixed Timestep (default 0.02 times a second). If unity does not detect a collision it means your objects intersect for less time than the Fixed Timestep, or in other words, they are moving very fast (like you describe your situation). One (bad) way to fix this would be to decrease the amount of time in between physics calculations. However, this would greatly decrease your programs efficiency.
Instead, consider moving your object in the function FixedUpdate() so that the object only moves every time the physics checks for a collision. This should fix your problem.
Take a look at the 3rd answer (by Garth-Smith):
https://forum.unity3d.com/threads/rigidbody-2d-wont-collide-with-another-object-when-its-moving-really-fast.248786/
I particularly want to highlight the part:
If you have a Rigidbody2D, you should be moving it in FixedUpdate()
using rigidbody2D.MovePosition(Vector2). This will move the
Rigidbody2D through space, instead of teleporting it from point A to
point B.
The second part about Raycasts should not be necessary for your problem, but if you continue to experience problems your can use them to check a range as jdweng stated in his comment.
Here are a couple places to learn about Raycasts if you are unfamiliar with them:
https://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html
https://unity3d.com/learn/tutorials/topics/physics/raycasting
If the movement of your object is too fast it will simply ignore the collision since it never touches the actual collider - it just skips it.
In order to fix this you need to predict when that collision will happen and trigger it at correct moment.
Setting collision detection to Continuous as pixlark said might help if the swipe is not too fast.
Make sure that the collision detection mode for your Rigidbody2D is set to Continuous or Continuous Dynamic.
simple
go to the rigidbody of the object and change the c
So I am making a simple 2d endless mobile game. In the game, the player object (spaceship) moves upwards continuously and then the player can use either left or right to move the player to avoid obstacles.
As a newbie I am finding it very difficult to achieve a very smooth motion in the player movement. I have watched many tutorials including the unity official tutorials about moving an object. They all use simple techniques like:
rigidbody.velocity = (new Vector2 (0.0f, 1.0f)) * speed in the fixedupdate function
or transform.Translate (velocity * Time.deltaTime * speed) in the update function
or rigidBody.MovePosition (rigidbody.position + velocity * Time.fixedDeltaTime) in the fixed update or
just just changing the transform.position over time in the update function.
But none of these techniques or code that I have used have helped me to achieve that very smooth motion in the player movement that I want. No matter what I try I still get lags in the player movement. I have also tried switching the rigidbody.iskinematic on and of and changing the rigidbody interpolation but I am still not able to achieve a smooth movement in in 2d games that we see such as ios games shredd or split the dot. I thought that it might be my computer that was very slow or something that is why I am not getting a smooth movement but I transported my project onto my friends computer which is twice as fast and I still have the same results. I also striped all that decided to erase all the code that is in the player controller scripts and just focus on the code for moving the player but the results has not changed.
I am thinking that it is because I am just using a very simple and inefficient code to move the player or it might have something to do with changing some settings in unity. So the question is what is the most efficient way to achieve a very smooth player movement in unity. (Codebase and unity settings.)
Currently I am just using rigidbody.velocity = (new Vector2 (0.0f, 1.0f)) * speed to move the player and I have made the camera a child object of the player for simplicity.
Thank you.
I would use Vector3.Lerp to interpolate the transform.position. This essentially mathematically smooths out the translation between the two positions.
Something else I've experienced is that the editor is sometimes more laggy than the end product, so I recommend building the game and testing it out to see if that is the case.
Finally, if you are using transform.position to move the object, ensure that the numbers are fairly small. Big numbers obviously make the object jump around a lot more.
I am playing around with Unity3D and adding physics to the objects in my scene. I currently have a sphere (planet) in the center of the screen, and I have another sphere (moon) positioned outside of it that is not moving. When I run the game I want the moon to orbit the planet by applying a force to it. I have been able to get the force added by calling rigidbody.AddForce() and that will move it in the specified direction but it won't orbit. I'm not sure how to add force to it so that it will continuously orbit the sphere at a constant velocity.
I've tried some examples using a ConfigurableJoint and it orbits, but it starts out bouncing a little and then starts the orbit. My goal is to have a bunch of orbiting moons orbiting at their own speed that are able to bounce off eachother but not lose their velocity.
Any ideas?
Generally speaking you will fail, eventually, because rounding errors in your integration method will slowly throw you out of orbit. You can get very close in the ways suggested, but you could consider doing something more like the Kerbal Space Program, which seems to precalculate the orbit as an ellipse and then follow that ellipse until it has a reason to believe it should stop, rather than strictly "simulating" the orbit ...
If a collision occurs, allow normal physics to resolve the collision, and then recalculate your new orbit based on the result and start following that.
For the moon to orbit you would need to give the moon an initial velocity. Then have it accelerate towards the planet, that is a constant force.
gameObject.rigidbody.AddForce(1, 0, 0);
gameObject.constantForce.relativeForce = Vector3(0, 1, 0);