Skip to main content
Simplified my example code
Source Link
Bunabyte
  • 331
  • 2
  • 7

Relevant to this issue are two MonoBehaviour scripts: Actor and Player. Actor handles velocity, movement, things like that. Player uses inputs to control an Actor component. This is the code (note that functionality unrelated to movement has been removed for clarity):

// Actor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(CharacterController))]
public class Actor : MonoBehaviour
{
// *snip*

    //public UpdateVector3 isDirection
 called once per frame{
    void Update()   get
        {
        if (controller.isGrounded)   return _direction;
        {}
        set
    Vector3 planarTarget = new Vector3(_direction.x,{
 0,           _direction = value.z);normalized;
        }
    if}
 (planarTarget.sqrMagnitude > 0.01f) public Vector3 Velocity
    {
        {get
        {
        Quaternion targetRot = Quaternion.LookRotation(planarTarget); return _velocity;
        }
        transform.rotationset
 = Quaternion.RotateTowards(transform.rotation, targetRot, 600.0f * Time.deltaTime);  {
            }_velocity = value;
        }
 
    }

    Accelerate(refpublic _velocity.x,float refacceleration _direction.x);= 48;
    public float deceleration = Accelerate(ref56;
 _velocity.z, ref _direction.z);
 public float skidAcceleration = 72;
    public float topSpeed = Decelerate(ref5;

 _velocity.x, ref _direction.x); private CharacterController controller;

    private Vector3 _direction;
  Decelerate(ref _velocity.z, refprivate _direction.z);Vector3 _velocity;

    // Start is called ifbefore the first frame update
    void Start(!controller.isGrounded)
    {
        {controller = gameObject.GetComponent<CharacterController>();
    }

    // Update is called ifonce (IsJumpingper &&frame
 _velocity.y > extendedJumpThreshold void Update()
    {
        if (controller.isGrounded)
   _velocity.y -= jumpingGravity * Time.deltaTime; {
            else
Vector3 planarTarget = new Vector3(_direction.x, 0, _direction.z);
          _velocity.y -= gravityif *(planarTarget.sqrMagnitude Time> 0.deltaTime;01f)
        }
    {
        if        Quaternion targetRot = Quaternion.LookRotation(IsCrouchingplanarTarget);
            Height    transform.rotation = DefaultHeightQuaternion.RotateTowards(transform.rotation, *targetRot, crouchHeight;
600.0f * Time.deltaTime);
      else
      }
      Height = DefaultHeight;}

        Accelerate(ref _velocity.yx, =ref Mathf_direction.Clampx);
        Accelerate(ref _velocity.yz, -terminalVelocity,ref terminalVelocity_direction.z);

        controller.MoveDecelerate(ref _velocity.x, *ref Time_direction.deltaTimex);
    }

    void FixedUpdateDecelerate(ref _velocity.z, ref _direction.z);

    {
    controller.Move(_velocity * Time.deltaTime);
    }

    void Accelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (moving)
        {
            float absMotion = Mathf.Abs(velComponent);
            float crouchFactor = IsCrouching ? crouchSpeed : 1.0f;

            if ((velComponent > 0 && dirComponent < 0) ||
                (velComponent < 0 && dirComponent > 0))
            {
                velComponent += dirComponent * skidAcceleration * Time.deltaTime;
            }
            else if (absMotion < topSpeed * crouchFactor)
            {
                velComponent += dirComponent * acceleration * Time.deltaTime;
            }
            else if (absMotion > topSpeed * crouchFactor)
            {
                velComponent -= dirComponent * deceleration * Time.deltaTime;
            }
        }
    }

    void Decelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (!moving)
        {
            if (velComponent < 0)
            {
                velComponent += deceleration * Time.deltaTime;
                if (velComponent > 0)
                    velComponent = 0;
            }
            else if (velComponent > 0)
            {
                velComponent -= deceleration * Time.deltaTime;
                if (velComponent < 0)
                    velComponent = 0;
            }
        }    
    }
}

// Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
    public Transform camTransform;

    private Actor actor;

    private InputAction moveAction;
    private InputAction jumpAction;
    private InputAction crouchAction;

    // *snip*Start is called before the first frame update
    void Start()
    {
        actor = gameObject.GetComponent<Actor>();

        moveAction = InputSystem.actions.FindAction("move");
        jumpAction = InputSystem.actions.FindAction("jump");
        crouchAction = InputSystem.actions.FindAction("crouch");
    }

    // Update is called once per frame
    void Update()
    {
        float oldCamPitch = camTransform.eulerAngles.x;
        float oldCamRoll = camTransform.eulerAngles.z;

        Vector2 moveInput = moveAction.ReadValue<Vector2>();

        Vector3 camForward = camTransform.forward;
        Vector3 camRight = camTransform.right;

        camForward.y = 0;
        camRight.y = 0;

        camForward.Normalize();
        camRight.Normalize();

        Vector3 moveDir = camForward * moveInput.y + camRight * moveInput.x;
 
        actor.Direction = moveDir.normalized;

        if (jumpAction.WasPressedThisFrame())
            actor.Jump();

        actor.IsJumping = jumpAction.IsPressed();
        actor.IsCrouching = crouchAction.IsPressed();
    }
}

EDIT: an example project demonstrating this system in an isolated environment was requested, so I uploaded one here: https://www.mediafire.com/file/i076ubl7pgnlj6x/PlatformerExample.zip/file.

Relevant to this issue are two MonoBehaviour scripts: Actor and Player. Actor handles velocity, movement, things like that. Player uses inputs to control an Actor component. This is the code:

[RequireComponent(typeof(CharacterController))]
public class Actor : MonoBehaviour
{
// *snip*

    // Update is called once per frame
    void Update()
    {
        if (controller.isGrounded)
        {
            Vector3 planarTarget = new Vector3(_direction.x, 0, _direction.z);
            if (planarTarget.sqrMagnitude > 0.01f)
            {
                Quaternion targetRot = Quaternion.LookRotation(planarTarget);
                transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRot, 600.0f * Time.deltaTime);
            }
        }
 
        Accelerate(ref _velocity.x, ref _direction.x);
        Accelerate(ref _velocity.z, ref _direction.z);

        Decelerate(ref _velocity.x, ref _direction.x);
        Decelerate(ref _velocity.z, ref _direction.z);

        if (!controller.isGrounded)
        {
            if (IsJumping && _velocity.y > extendedJumpThreshold)
                _velocity.y -= jumpingGravity * Time.deltaTime;
            else
                _velocity.y -= gravity * Time.deltaTime;
        }

        if (IsCrouching)
            Height = DefaultHeight * crouchHeight;
        else
            Height = DefaultHeight;

        _velocity.y = Mathf.Clamp(_velocity.y, -terminalVelocity, terminalVelocity);

        controller.Move(_velocity * Time.deltaTime);
    }

    void FixedUpdate()
    {

    }

    void Accelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (moving)
        {
            float absMotion = Mathf.Abs(velComponent);
            float crouchFactor = IsCrouching ? crouchSpeed : 1.0f;

            if ((velComponent > 0 && dirComponent < 0) ||
                (velComponent < 0 && dirComponent > 0))
            {
                velComponent += dirComponent * skidAcceleration * Time.deltaTime;
            }
            else if (absMotion < topSpeed * crouchFactor)
            {
                velComponent += dirComponent * acceleration * Time.deltaTime;
            }
            else if (absMotion > topSpeed * crouchFactor)
            {
                velComponent -= dirComponent * deceleration * Time.deltaTime;
            }
        }
    }

    void Decelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (!moving)
        {
            if (velComponent < 0)
            {
                velComponent += deceleration * Time.deltaTime;
                if (velComponent > 0)
                    velComponent = 0;
            }
            else if (velComponent > 0)
            {
                velComponent -= deceleration * Time.deltaTime;
                if (velComponent < 0)
                    velComponent = 0;
            }
        }    
    }
}

// Player.cs
public class Player : MonoBehaviour
{
// *snip*
    // Update is called once per frame
    void Update()
    {
        float oldCamPitch = camTransform.eulerAngles.x;
        float oldCamRoll = camTransform.eulerAngles.z;

        Vector2 moveInput = moveAction.ReadValue<Vector2>();

        Vector3 camForward = camTransform.forward;
        Vector3 camRight = camTransform.right;

        camForward.y = 0;
        camRight.y = 0;

        camForward.Normalize();
        camRight.Normalize();

        Vector3 moveDir = camForward * moveInput.y + camRight * moveInput.x;
 
        actor.Direction = moveDir.normalized;

        if (jumpAction.WasPressedThisFrame())
            actor.Jump();

        actor.IsJumping = jumpAction.IsPressed();
        actor.IsCrouching = crouchAction.IsPressed();
    }
}

EDIT: an example project demonstrating this system in an isolated environment was requested, so I uploaded one here: https://www.mediafire.com/file/i076ubl7pgnlj6x/PlatformerExample.zip/file.

Relevant to this issue are two MonoBehaviour scripts: Actor and Player. Actor handles velocity, movement, things like that. Player uses inputs to control an Actor component. This is the code (note that functionality unrelated to movement has been removed for clarity):

// Actor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(CharacterController))]
public class Actor : MonoBehaviour
{
    public Vector3 Direction
    {
        get
        {
            return _direction;
        }
        set
        {
            _direction = value.normalized;
        }
    }
    public Vector3 Velocity
    {
        get
        {
            return _velocity;
        }
        set
        {
            _velocity = value;
        }
    }

    public float acceleration = 48;
    public float deceleration = 56;
    public float skidAcceleration = 72;
    public float topSpeed = 5;

    private CharacterController controller;

    private Vector3 _direction;
    private Vector3 _velocity;

    // Start is called before the first frame update
    void Start()
    {
        controller = gameObject.GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {
        if (controller.isGrounded)
        {
            Vector3 planarTarget = new Vector3(_direction.x, 0, _direction.z);
            if (planarTarget.sqrMagnitude > 0.01f)
            {
                Quaternion targetRot = Quaternion.LookRotation(planarTarget);
                transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRot, 600.0f * Time.deltaTime);
            }
        }

        Accelerate(ref _velocity.x, ref _direction.x);
        Accelerate(ref _velocity.z, ref _direction.z);

        Decelerate(ref _velocity.x, ref _direction.x);
        Decelerate(ref _velocity.z, ref _direction.z);

        controller.Move(_velocity * Time.deltaTime);
    }

    void Accelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (moving)
        {
            float absMotion = Mathf.Abs(velComponent);

            if ((velComponent > 0 && dirComponent < 0) ||
                (velComponent < 0 && dirComponent > 0))
            {
                velComponent += dirComponent * skidAcceleration * Time.deltaTime;
            }
            else if (absMotion < topSpeed)
            {
                velComponent += dirComponent * acceleration * Time.deltaTime;
            }
            else if (absMotion > topSpeed)
            {
                velComponent -= dirComponent * deceleration * Time.deltaTime;
            }
        }
    }

    void Decelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (!moving)
        {
            if (velComponent < 0)
            {
                velComponent += deceleration * Time.deltaTime;
                if (velComponent > 0)
                    velComponent = 0;
            }
            else if (velComponent > 0)
            {
                velComponent -= deceleration * Time.deltaTime;
                if (velComponent < 0)
                    velComponent = 0;
            }
        }    
    }
}

// Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
    public Transform camTransform;

    private Actor actor;

    private InputAction moveAction;
    private InputAction jumpAction;
    private InputAction crouchAction;

    // Start is called before the first frame update
    void Start()
    {
        actor = gameObject.GetComponent<Actor>();

        moveAction = InputSystem.actions.FindAction("move");
        jumpAction = InputSystem.actions.FindAction("jump");
        crouchAction = InputSystem.actions.FindAction("crouch");
    }

    // Update is called once per frame
    void Update()
    {
        float oldCamPitch = camTransform.eulerAngles.x;
        float oldCamRoll = camTransform.eulerAngles.z;

        Vector2 moveInput = moveAction.ReadValue<Vector2>();

        Vector3 camForward = camTransform.forward;
        Vector3 camRight = camTransform.right;

        camForward.y = 0;
        camRight.y = 0;

        camForward.Normalize();
        camRight.Normalize();

        Vector3 moveDir = camForward * moveInput.y + camRight * moveInput.x;
        actor.Direction = moveDir.normalized;
    }
}
Add link to example project
Source Link
Bunabyte
  • 331
  • 2
  • 7

EDIT: an example project demonstrating this system in an isolated environment was requested, so I uploaded one here: https://www.mediafire.com/file/i076ubl7pgnlj6x/PlatformerExample.zip/file.

EDIT: an example project demonstrating this system in an isolated environment was requested, so I uploaded one here: https://www.mediafire.com/file/i076ubl7pgnlj6x/PlatformerExample.zip/file.

Only show important code snippets
Source Link
Bunabyte
  • 331
  • 2
  • 7
// Actor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(CharacterController))]
public class Actor : MonoBehaviour
{
    enum MovementAxis
    {
        Horizontal,
        Vertical
    }

    public Vector3 Direction
    {
        get
        {
            return _direction;
        }
        set
        {
            if (controller.isGrounded)
                _direction = value.normalized;
            else
                _direction = Vector3.Lerp(_direction, value, airControl * Time.deltaTime).normalized;
        }
    }
    public Vector3 Velocity
    {
        get
        {
            return _velocity;
        }
        set
        {
            _velocity = value;
        }
    }

    public bool IsJumping { get; set; }

    public float Height
    {
        get
        {
            return _height;
        }
        set
        {
            _height = value;
            controller.height = value;
        }
    }

    public float DefaultHeight { get; private set; }

    public bool IsCrouching { get; set; }

    public float acceleration = 48;
    public float deceleration = 56;
    public float skidAcceleration = 72;
    public float topSpeed = 5;

    public float jumpHeight = 8.0f;
    public float airControl = 35.0f;
    public float gravity = 35.0f;
    public float jumpingGravity = 15.0f;
    public float extendedJumpThreshold = 6.0f;
    public float terminalVelocity = 50.0f;

    public float crouchHeight = 0.5f;
    public float crouchSpeed = 0.375f;

    private CharacterController controller;

    private Vector3 _direction;
    private Vector3 _velocity;

    private float _height;
    private float _defaultHeight;

    public void Jump()
    {
        if (controller.isGrounded)
        {
            _velocity.y = jumpHeight;
            _velocity += transform.forward * acceleration * Time.deltaTime;
        }
    }

    // Start is called before the first frame update
    void Start()
    {
        controller = gameObject.GetComponent<CharacterController>();

        DefaultHeight = controller.height;
        _height = DefaultHeight;
    }*snip*

    // Update is called once per frame
    void Update()
    {
        if (controller.isGrounded)
        {
            Vector3 planarTarget = new Vector3(_direction.x, 0, _direction.z);
            if (planarTarget.sqrMagnitude > 0.01f)
            {
                Quaternion targetRot = Quaternion.LookRotation(planarTarget);
                transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRot, 600.0f * Time.deltaTime);
            }
        }

        Accelerate(ref _velocity.x, ref _direction.x);
        Accelerate(ref _velocity.z, ref _direction.z);

        Decelerate(ref _velocity.x, ref _direction.x);
        Decelerate(ref _velocity.z, ref _direction.z);

        if (!controller.isGrounded)
        {
            if (IsJumping && _velocity.y > extendedJumpThreshold)
                _velocity.y -= jumpingGravity * Time.deltaTime;
            else
                _velocity.y -= gravity * Time.deltaTime;
        }

        if (IsCrouching)
            Height = DefaultHeight * crouchHeight;
        else
            Height = DefaultHeight;

        _velocity.y = Mathf.Clamp(_velocity.y, -terminalVelocity, terminalVelocity);

        controller.Move(_velocity * Time.deltaTime);
    }

    void FixedUpdate()
    {

    }

    void Accelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (moving)
        {
            float absMotion = Mathf.Abs(velComponent);
            float crouchFactor = IsCrouching ? crouchSpeed : 1.0f;

            if ((velComponent > 0 && dirComponent < 0) ||
                (velComponent < 0 && dirComponent > 0))
            {
                velComponent += dirComponent * skidAcceleration * Time.deltaTime;
            }
            else if (absMotion < topSpeed * crouchFactor)
            {
                velComponent += dirComponent * acceleration * Time.deltaTime;
            }
            else if (absMotion > topSpeed * crouchFactor)
            {
                velComponent -= dirComponent * deceleration * Time.deltaTime;
            }
        }
    }

    void Decelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (!moving)
        {
            if (velComponent < 0)
            {
                velComponent += deceleration * Time.deltaTime;
                if (velComponent > 0)
                    velComponent = 0;
            }
            else if (velComponent > 0)
            {
                velComponent -= deceleration * Time.deltaTime;
                if (velComponent < 0)
                    velComponent = 0;
            }
        }    
    }
}

// Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
    public Transform camTransform;

    private Actor actor;

    private InputAction moveAction;
    private InputAction jumpAction;
    private InputAction crouchAction;

    // Start is called before the first frame update
    void Start()
    {
        actor = gameObject.GetComponent<Actor>();

        moveAction = InputSystem.actions.FindAction("move");
        jumpAction = InputSystem.actions.FindAction("jump");
        crouchAction = InputSystem.actions.FindAction("crouch");
    }
*snip*
    // Update is called once per frame
    void Update()
    {
        float oldCamPitch = camTransform.eulerAngles.x;
        float oldCamRoll = camTransform.eulerAngles.z;

        Vector2 moveInput = moveAction.ReadValue<Vector2>();

        Vector3 camForward = camTransform.forward;
        Vector3 camRight = camTransform.right;

        camForward.y = 0;
        camRight.y = 0;

        camForward.Normalize();
        camRight.Normalize();

        Vector3 moveDir = camForward * moveInput.y + camRight * moveInput.x;

        actor.Direction = moveDir.normalized;

        if (jumpAction.WasPressedThisFrame())
            actor.Jump();

        actor.IsJumping = jumpAction.IsPressed();
        actor.IsCrouching = crouchAction.IsPressed();
    }
}
// Actor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(CharacterController))]
public class Actor : MonoBehaviour
{
    enum MovementAxis
    {
        Horizontal,
        Vertical
    }

    public Vector3 Direction
    {
        get
        {
            return _direction;
        }
        set
        {
            if (controller.isGrounded)
                _direction = value.normalized;
            else
                _direction = Vector3.Lerp(_direction, value, airControl * Time.deltaTime).normalized;
        }
    }
    public Vector3 Velocity
    {
        get
        {
            return _velocity;
        }
        set
        {
            _velocity = value;
        }
    }

    public bool IsJumping { get; set; }

    public float Height
    {
        get
        {
            return _height;
        }
        set
        {
            _height = value;
            controller.height = value;
        }
    }

    public float DefaultHeight { get; private set; }

    public bool IsCrouching { get; set; }

    public float acceleration = 48;
    public float deceleration = 56;
    public float skidAcceleration = 72;
    public float topSpeed = 5;

    public float jumpHeight = 8.0f;
    public float airControl = 35.0f;
    public float gravity = 35.0f;
    public float jumpingGravity = 15.0f;
    public float extendedJumpThreshold = 6.0f;
    public float terminalVelocity = 50.0f;

    public float crouchHeight = 0.5f;
    public float crouchSpeed = 0.375f;

    private CharacterController controller;

    private Vector3 _direction;
    private Vector3 _velocity;

    private float _height;
    private float _defaultHeight;

    public void Jump()
    {
        if (controller.isGrounded)
        {
            _velocity.y = jumpHeight;
            _velocity += transform.forward * acceleration * Time.deltaTime;
        }
    }

    // Start is called before the first frame update
    void Start()
    {
        controller = gameObject.GetComponent<CharacterController>();

        DefaultHeight = controller.height;
        _height = DefaultHeight;
    }

    // Update is called once per frame
    void Update()
    {
        if (controller.isGrounded)
        {
            Vector3 planarTarget = new Vector3(_direction.x, 0, _direction.z);
            if (planarTarget.sqrMagnitude > 0.01f)
            {
                Quaternion targetRot = Quaternion.LookRotation(planarTarget);
                transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRot, 600.0f * Time.deltaTime);
            }
        }

        Accelerate(ref _velocity.x, ref _direction.x);
        Accelerate(ref _velocity.z, ref _direction.z);

        Decelerate(ref _velocity.x, ref _direction.x);
        Decelerate(ref _velocity.z, ref _direction.z);

        if (!controller.isGrounded)
        {
            if (IsJumping && _velocity.y > extendedJumpThreshold)
                _velocity.y -= jumpingGravity * Time.deltaTime;
            else
                _velocity.y -= gravity * Time.deltaTime;
        }

        if (IsCrouching)
            Height = DefaultHeight * crouchHeight;
        else
            Height = DefaultHeight;

        _velocity.y = Mathf.Clamp(_velocity.y, -terminalVelocity, terminalVelocity);

        controller.Move(_velocity * Time.deltaTime);
    }

    void FixedUpdate()
    {

    }

    void Accelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (moving)
        {
            float absMotion = Mathf.Abs(velComponent);
            float crouchFactor = IsCrouching ? crouchSpeed : 1.0f;

            if ((velComponent > 0 && dirComponent < 0) ||
                (velComponent < 0 && dirComponent > 0))
            {
                velComponent += dirComponent * skidAcceleration * Time.deltaTime;
            }
            else if (absMotion < topSpeed * crouchFactor)
            {
                velComponent += dirComponent * acceleration * Time.deltaTime;
            }
            else if (absMotion > topSpeed * crouchFactor)
            {
                velComponent -= dirComponent * deceleration * Time.deltaTime;
            }
        }
    }

    void Decelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (!moving)
        {
            if (velComponent < 0)
            {
                velComponent += deceleration * Time.deltaTime;
                if (velComponent > 0)
                    velComponent = 0;
            }
            else if (velComponent > 0)
            {
                velComponent -= deceleration * Time.deltaTime;
                if (velComponent < 0)
                    velComponent = 0;
            }
        }    
    }
}

// Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
    public Transform camTransform;

    private Actor actor;

    private InputAction moveAction;
    private InputAction jumpAction;
    private InputAction crouchAction;

    // Start is called before the first frame update
    void Start()
    {
        actor = gameObject.GetComponent<Actor>();

        moveAction = InputSystem.actions.FindAction("move");
        jumpAction = InputSystem.actions.FindAction("jump");
        crouchAction = InputSystem.actions.FindAction("crouch");
    }

    // Update is called once per frame
    void Update()
    {
        float oldCamPitch = camTransform.eulerAngles.x;
        float oldCamRoll = camTransform.eulerAngles.z;

        Vector2 moveInput = moveAction.ReadValue<Vector2>();

        Vector3 camForward = camTransform.forward;
        Vector3 camRight = camTransform.right;

        camForward.y = 0;
        camRight.y = 0;

        camForward.Normalize();
        camRight.Normalize();

        Vector3 moveDir = camForward * moveInput.y + camRight * moveInput.x;

        actor.Direction = moveDir.normalized;

        if (jumpAction.WasPressedThisFrame())
            actor.Jump();

        actor.IsJumping = jumpAction.IsPressed();
        actor.IsCrouching = crouchAction.IsPressed();
    }
}
[RequireComponent(typeof(CharacterController))]
public class Actor : MonoBehaviour
{
// *snip*

    // Update is called once per frame
    void Update()
    {
        if (controller.isGrounded)
        {
            Vector3 planarTarget = new Vector3(_direction.x, 0, _direction.z);
            if (planarTarget.sqrMagnitude > 0.01f)
            {
                Quaternion targetRot = Quaternion.LookRotation(planarTarget);
                transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRot, 600.0f * Time.deltaTime);
            }
        }

        Accelerate(ref _velocity.x, ref _direction.x);
        Accelerate(ref _velocity.z, ref _direction.z);

        Decelerate(ref _velocity.x, ref _direction.x);
        Decelerate(ref _velocity.z, ref _direction.z);

        if (!controller.isGrounded)
        {
            if (IsJumping && _velocity.y > extendedJumpThreshold)
                _velocity.y -= jumpingGravity * Time.deltaTime;
            else
                _velocity.y -= gravity * Time.deltaTime;
        }

        if (IsCrouching)
            Height = DefaultHeight * crouchHeight;
        else
            Height = DefaultHeight;

        _velocity.y = Mathf.Clamp(_velocity.y, -terminalVelocity, terminalVelocity);

        controller.Move(_velocity * Time.deltaTime);
    }

    void FixedUpdate()
    {

    }

    void Accelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (moving)
        {
            float absMotion = Mathf.Abs(velComponent);
            float crouchFactor = IsCrouching ? crouchSpeed : 1.0f;

            if ((velComponent > 0 && dirComponent < 0) ||
                (velComponent < 0 && dirComponent > 0))
            {
                velComponent += dirComponent * skidAcceleration * Time.deltaTime;
            }
            else if (absMotion < topSpeed * crouchFactor)
            {
                velComponent += dirComponent * acceleration * Time.deltaTime;
            }
            else if (absMotion > topSpeed * crouchFactor)
            {
                velComponent -= dirComponent * deceleration * Time.deltaTime;
            }
        }
    }

    void Decelerate(ref float velComponent, ref float dirComponent)
    {
        bool moving = Mathf.Abs(dirComponent) > 0.0f;
        if (!moving)
        {
            if (velComponent < 0)
            {
                velComponent += deceleration * Time.deltaTime;
                if (velComponent > 0)
                    velComponent = 0;
            }
            else if (velComponent > 0)
            {
                velComponent -= deceleration * Time.deltaTime;
                if (velComponent < 0)
                    velComponent = 0;
            }
        }    
    }
}

// Player.cs
public class Player : MonoBehaviour
{
// *snip*
    // Update is called once per frame
    void Update()
    {
        float oldCamPitch = camTransform.eulerAngles.x;
        float oldCamRoll = camTransform.eulerAngles.z;

        Vector2 moveInput = moveAction.ReadValue<Vector2>();

        Vector3 camForward = camTransform.forward;
        Vector3 camRight = camTransform.right;

        camForward.y = 0;
        camRight.y = 0;

        camForward.Normalize();
        camRight.Normalize();

        Vector3 moveDir = camForward * moveInput.y + camRight * moveInput.x;

        actor.Direction = moveDir.normalized;

        if (jumpAction.WasPressedThisFrame())
            actor.Jump();

        actor.IsJumping = jumpAction.IsPressed();
        actor.IsCrouching = crouchAction.IsPressed();
    }
}
Source Link
Bunabyte
  • 331
  • 2
  • 7
Loading