Good character controller searched

Hi, maybe you know fall guys (PS4, etc) or wobble man (Android, etc)? I would need a identical character controller.

I have coded one but if I have learned one thing in my life that others can do much better, is there something you know? Mine is not so clean in movement for me, too choppy for a game.

regards

using UnityEngine;

[RequireComponent(typeof(Rigidbody))]
public class Movement : MonoBehaviour
{
    //Values setted at inspector
    [SerializeField] float speed;
    [SerializeField] float rotationSpeed;

    Rigidbody rb;

    void Awake() => rb = GetComponent<Rigidbody>();

    private void FixedUpdate()
    {
        //the direction we're asking character to move ==> thats the common one Input method but use what you preff
        Vector3 desiredDir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

        //if input is empty, it has no sense to calculate nothing cause we don't need to rotate nor apply forces to our character.
        //Also if we try to turn our character to Vector3.zero, code will break :)
        if (desiredDir != Vector3.zero)
        {
            //the direction the character is facing, generaly forward is "forward" but if your game is turned 90º it might be Vector3.left or in a 2D game Vector3.up
            //this is not the same than transform.eulerAngles, remember it
            Vector3 currentDir = transform.rotation * Vector3.forward;

            //we smooth turn our character to the desired rotation we got from input
            transform.LookAt(Vector3.Lerp(currentDir, desiredDir, rotationSpeed * Time.fixedDeltaTime) + transform.position);

            //If desiredDir = currentDir just we get 1 (the max) if the angle between them is 90º we get 0, so player can't move till he rotates.
            //If were facing the opposite direction we desire to go, we get -1
            //remember to normalize desiredDir since if you're in a keyBoard pressing left and up at same time, desiredDir = (1,0,1)
            //and we want always a magnitude 1 vector in order to not get a forceMultiplier > 1
            //the max multiplier we want to get is 1 (100)
            float forceMultiplier = Vector3.Dot(desiredDir.normalized, currentDir);
            //since we never want to apply a negative force if the character is facing opposite to the direction we will move it
            //we make sure forceMultipler is not negative.
            if (forceMultiplier < 0) forceMultiplier = 0;
            //we add the force in the direction character is facing
            rb.AddForce(currentDir * forceMultiplier * speed * Time.fixedDeltaTime);
        }
    }
}

The code is easy, just so much comments in order to explain why it does each calc it does.

Now you’ve to play with rigidbody drag, speed and rotationSpeed values and PhysicsMaterial.
Remember also to freeze rotation at x and z axis at your Rigidbody.
If the collider is a Capsule, Sphere or Cylinder, this will work fine, but if your collider has corners when you’re at top view (a cube, for example) rotate the transform will give you some issues when it interacts with other colliders. Just do it at RigidBody.AddTorque();

2 Likes

Oh wow thank you!