Transform.Translate snaps back in FixedUpdate
I am currently toying with movement solutions in C#. I am seeking instantaneous velocity increases with no friction against walls, and transform.Translate produces the most desirable results.
I have a Capsule with a rigidbody and the script as the player. The world consists of a plane and a box with static colliders.
Moving my code from Update to FixedUpdate solved most of the jitteriness, but there is a persistent snapping back whenever the forward key is released.
Here is the code:
public float speed = 10.0f;
public float rotationSpeed = 100.0f;
private Vector3 translation = new Vector3();
void FixedUpdate()
{
translation = Vector3.zero;
if (Input.GetKey(KeyCode.W))
translation += Vector3.forward;
if (Input.GetKey(KeyCode.S))
translation += Vector3.back;
if (Input.GetKey(KeyCode.Q))
translation += Vector3.left;
if (Input.GetKey(KeyCode.E))
translation += Vector3.right;
if (Input.GetKey(KeyCode.A))
transform.Rotate(0, -rotationSpeed * Time.deltaTime, 0);
if (Input.GetKey(KeyCode.D))
transform.Rotate(0, rotationSpeed * Time.deltaTime, 0);
translation = translation.normalized * speed;
transform.Translate(translation * Time.fixedDeltaTime);
}
This produces the exact result I am looking for aside from the snapback upon key release. The capsule has an instant acceleration and moves smoothly against the box, regardless of the angle. The Rigidbody Velocity solutions result in an undesirable level of "stick" to the box collider.
Any insight to helping me achieve a resolution would be greatly appreciated :)
What do you mean by snapback? Only upon releasing forward key?
@hexagonius - Yes. In the frame immediately after releasing the movement keys the physics engine bumps the capsule's collider back a single frame worth of movement.
You'll often get weird results when using transform.Translate/Rotate and rigidbodies together. I'd highly recommend using Rigidbody.$$anonymous$$ovePosition and Rigidbody.$$anonymous$$oveRotation ins$$anonymous$$d. They do almost the same thing as translate and rotate, but within the physics engine. You should be able to achieve identical results without the bugginess.
@conman79 - I got identical results using the RigidBody.$$anonymous$$ovePosition function, while changing the vector maths to use transform.forward and transform.right.
This is my solution with your suggestion. Again, identical results. I am bumping back upon releasing W
void FixedUpdate()
{
translation = Vector3.zero;
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.W))
translation += transform.forward;
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.S))
translation += -transform.forward;
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.Q))
translation += -transform.right;
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.E))
translation += transform.right;
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.A))
transform.Rotate(0, -rotationSpeed * Time.deltaTime, 0);
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.D))
transform.Rotate(0, rotationSpeed * Time.deltaTime, 0);
translation = translation.normalized * speed;
//transform.Translate(translation * Time.fixedDeltaTime);
GetComponent<Rigidbody>().$$anonymous$$ovePosition(transform.position + translation *Time.fixedDeltaTime);
}
I ran into this problem in DarkBASIC, and the solution was simply to run the physics-collision calculations immediately before the screen synced via a frame render.
I am thinking the solution may lie in running the movement in another $$anonymous$$onoBehavior function... I have tried OnPreRender() but the Ridigbody.$$anonymous$$ovePosition and transform.Translate functions don't seem to work within that function.
A way to disable the friction against the wall object would allow me to avoid this syncing problem altogether. The physics engine does things that I don't want it to do, which is why RigidBody.SetVelocity is producing undesirable results. I am still new and not incredibly proficient with the nuances of manipulation Rigidbody settings beyond the inspector settings.
I guess a better description of the issue is this:
While holding the forward key, the character is moving after the screen sync and appearing deeper in the wall than he should. When you stop holding forward, the character is no longer constantly being pressed into the wall and comes to rest against the wall where he should be appearing the whole time. This appears as the character being bumped out away from the wall, but is actually a lack of appearing closer than he should.