0
\$\begingroup\$

What I'm trying to do

I have a character - prefab. For this prefab I have one animation (idle), which works fine - I hit "Play" button and my character is in idle state. What I want is to try to move this character without implementing an animation (for now, only for test). So I wrote two scripts - one is the "engine" for movement and one is the controller for the character itself.

What is wrong

The thing is, that my character is not moving at all. I tried to debug the keyboards in the console and that works fine, so I assume that the inputs are good. I checked that twice in the Project Settings. I tried with two Unity versions and also I tried to start whole new project only with cubes, because I thought that maybe is something wrong with my character. That doesn't work either.

MovementMotor.cs

using UnityEngine;

public class MovementMotor : MonoBehaviour
{
    public float gravityMultiplier = 1f;
    public float lerpTime = 10f;

    [HideInInspector]
    public CharacterController characterController;

    private Vector3 moveDirection = Vector3.zero;
    private Vector3 targetDirection = Vector3.zero;
    private float fallVelocity = 0f;

    public float distanceToGround = 0.1f;

    private bool isGrounded;
    private Collider myCollider;

    void Awake()
    {
        characterController = GetComponent<CharacterController>();
        myCollider = GetComponent<Collider>();
    }

    void Start()
    {
        distanceToGround = myCollider.bounds.extents.y;
    }

    void Update()
    {
        isGrounded = OnGroundCheck();
        moveDirection = Vector3.Lerp(moveDirection, targetDirection, Time.deltaTime * lerpTime);
        moveDirection.y = fallVelocity;

        characterController.Move(moveDirection * Time.deltaTime);

        if (!isGrounded)
        {
            fallVelocity -= 90f * gravityMultiplier * Time.deltaTime;
        }
    }

    public bool OnGroundCheck()
    {
        RaycastHit hit;

        if (characterController.isGrounded)
        {
            return true;
        }

        if (Physics.Raycast(myCollider.bounds.center, -Vector3.up, out hit, distanceToGround + 0.1f))
        {
            return true;
        }
        return false;
    }

    public void Move(Vector3 direction)
    {
        targetDirection = direction;
    }

    public void Stop()
    {
        moveDirection = Vector3.zero;
        targetDirection = Vector3.zero;
    }

    public void Jump(float jumpPower)
    {
        if (isGrounded)
        {
            fallVelocity = jumpPower;
        }
    }
}

CharacterMovement.cs

using UnityEngine;

public class CharacterMovement : MonoBehaviour
{
    private MovementMotor motor;

    public float moveMagnitude = 0.05f;
    public float speed = 0.7f;
    public float speedMoveWhileAttack = 0.1f;
    public float speedAttack = 1.5f;
    public float turnSpeed = 10f;
    public float jumpPower = 20f;

    private float speedMoveMultiplier = 1f;

    private Vector3 direction;
    private Animator animator;
    private Camera mainCamera;

    private string PARAMETER_STATE = "State";

    void Awake()
    {
        motor = GetComponent<MovementMotor>();
        animator = GetComponent<Animator>();
    }

    void Start()
    {
        animator.applyRootMotion = false;
        mainCamera = Camera.main;
    }

    void Update()
    {

    }

    private Vector3 MoveDirection
    {
        get
        {
            return direction;
        }

        set
        {
            direction = value * speedMoveMultiplier;

            if (direction.magnitude > 0.1f)
            {
                var newRotation = Quaternion.LookRotation(direction);
                transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * turnSpeed);
            }
            direction *= speed * (Vector3.Dot(transform.forward, direction) + 1f) * 5f;
            motor.Move(direction);

            // AnimationMove(motor.characterController.velocity.magnitude * 0.1f);
        }
    }

    void Moving(Vector3 direction, float multiplier)
    {
        speedMoveMultiplier = 1 * multiplier;
        MoveDirection = direction;
    }

    void Jump()
    {
        motor.Jump(jumpPower);
    }

    void MovementAndJumping()
    {
        Vector3 moveInput = Vector3.zero;
        Vector3 forward = Quaternion.AngleAxis(-90, Vector3.up) * mainCamera.transform.right;

        moveInput += forward * Input.GetAxis("Vertical");
        moveInput += mainCamera.transform.right * Input.GetAxis("Horizontal");

        moveInput.Normalize();
        Moving(moveInput.normalized, 1f);

        if (Input.GetKey(KeyCode.Space))
        {
            Jump();
        }
    }
}

Question

Does the problem lies within the code or maybe I should look somewhere else?

Unity version: 2019.2.9f1

System: MacOS Mojave 10.14.6

\$\endgroup\$
1
\$\begingroup\$

Currently, in MovementMotor.cs moveDirection is always zero unless distanceToGround is greater than 0.1f. This is because in CharacterMovement.cs MovementAndJumping() is never called. Calling this Method in Update() should fix the problem.

CharacterMovement.cs

void Update()
{
    MovementAndJumping();
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You're brilliant:) I didn't think about it, I searched everywhere but now it works like a charm. Thank you very much:) \$\endgroup\$ – Sylwester Pilarz Oct 17 '19 at 17:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.