- Home /
Smooth out character movement?
Hi everyone,
I've done a bunch of searching for an answer, and can't seem to find anything that has helped. In a nutshell, my character's movement is jagged/jittery and I'm trying to smooth it out. However, there is a slight wrinkle compared to other answers I've researched: the character is currently being moved in 2 ways: 1) with a transform.Translate using a speed variable in the local z direction, and 2) when the user presses a button, I am calling rigidbody.AddForce in the y direction (resulting in a jump). Both of these forms of movement are occurring in the Update function in my character controller script. The character is a prefab, instantiated at run-time. The character moves smoothly in the z direction, but when it jumps or falls in the y direction the movement appears jagged and not smooth (sort of like a sawtooth, up/forward/up/forward/up/forward really fast... appears to be each frame from my guess).
At first, I thought the issue was my camera follow script, which uses a Vector3.Lerp to follow the character. However, when I disable the camera follow script so the camera doesn't move, the character's movement still appears jittery/jagged when moving up or down (same as when the camera follow script is enabled).
Any ideas how to fix? I was thinking of using a Lerp to move the character, but unsure how to determine what my target position would be. Maybe there's a better way. I've also tried using interpolate/extrapolate on the character's rigidbody, but this did not change anything.
-pete
Here's my code for movement:
//Player move forward
transform.Translate (0.0f, 0.0f, zSpeed * Time.deltaTime);
//Player jump - rb is the rigidbody of player
rb.AddForce(0.0f, jumpYVelocity, 0.0f, Force$$anonymous$$ode.VelocityChange);
These commands are both in Update - would it really make a difference to move to FixedUpdate? I have the AddForce command in Update since it happens after input is received - was thinking that input needs to be received in the Update function, so the AddForce happens when input received in Update.
Answer by Warren933 · Aug 07, 2015 at 12:05 PM
Why dont you add the camera as a child to the player, then freeze the undesired rotation to allow it to face only the direction you want it to?
Answer by anubhavsd · Apr 30, 2015 at 06:40 PM
Try FixedUpdate instead of update and sync movement accordingly.
Answer by JayFitz91 · Apr 30, 2015 at 06:48 PM
Try using this, It's what I use for forward character movement, you should also post your code in the future so we can see what you're working with
transform.Translate(Vector3.forward * speed * Time.fixedDeltaTime, Space.Self);
Ok, so I have moved the transform.Translate to FixedUpdate, as well as the rb.AddForce. The code for player movement is below. However, now ins$$anonymous$$d of the jagged sawtooth movement, it now appears that the player is lurching forward as it moves (camera movement script is disabled). Any more ideas I can try?
void FixedUpdate()
{
transform.Translate (0.0f, 0.0f, zSpeed / 50, Space.Self);
if (jumpInputReceived == true) {
rb.AddForce (0.0f, jumpYVelocity, 0.0f, Force$$anonymous$$ode.VelocityChange);
jumpInputReceived = false;
}
}
This code will move your character forward in the direction he is facing, just make your camera a child of your character.
I have just tested this myself and everything works, movement in all directions and jumping, and everything runs smoothly.
There is a reference to this script in the unity documentation here
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(CharacterController))]
public class movement : $$anonymous$$onoBehaviour
{
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
public float rotateSpeed = 6;
private Vector3 moveDirection = Vector3.zero;
CharacterController controller;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
if (controller.isGrounded)
{
moveDirection = new Vector3(0,0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
transform.Rotate(0, Input.GetAxis("Horizontal") * rotateSpeed, 0);
if (Input.GetButton("Jump"))
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.$$anonymous$$ove(moveDirection * Time.deltaTime);
}
}
Answer by petediddy · May 01, 2015 at 04:07 AM
Thanks JayFitz91 ! That code has made the character movement really smooth now. Unfortunately, when I turn on the camera follow script, it still looks jittery. I tried making the camera a child of the player, but I don't want the camera to rotate like the player does, so I have used the below script on the camera to help it follow the player, but there is still some jitter. Any help? My camera follow script code is below:
using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour {
public float smoothing = 1.0f;
public Transform target;
private Vector3 offset;
void Start()
{
//Assign offset for camera
offset = transform.position - target.transform.position;
}
void LateUpdate()
{
//If target is still valid, it means the player has not been destroyed yet, so move camera
if (target != null)
{
Vector3 targetCamPos = target.transform.position + offset;
transform.position = Vector3.Lerp (transform.position, targetCamPos, smoothing);
}
}
}
Have you tried moving the camera script into FixedUpdate() Camera movement, sway, etc. is usually jerky for me until i put it in fixed update.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Move 3D Cubes with mouse 1 Answer
Distribute terrain in zones 3 Answers
destroying game object in a specific transform 2 Answers
Inconsistent jump height 1 Answer