Home > Blockchain >  The run speed doesn't change in my unity script
The run speed doesn't change in my unity script

Time:11-03

I am a starter and I am trying to make a simple unity top-down game in 2d, so i made a player controller script and tried to make my character walk, run, and crawl. But while executing it I can't make my character run speed change while everything else works.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    SpriteRenderer rend;
    public float movementSpeed = 3.0f;
    Vector2 movement = new Vector2();
    Rigidbody2D rigidbody2D;
    [SerializeField] float normalSpeed, runSpeed, crouchSpeed;

    Animator animator;

    void Start()
    {
        rend = GetComponent<SpriteRenderer>();
        animator = GetComponent<Animator>();
        rigidbody2D = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        UpdateState();
    }

    private void FixedUpdate()
    {
        MoveCharacter();
    }

    private void MoveCharacter()
    {
        movement.x = Input.GetAxisRaw("Horizontal");
        movement.y = Input.GetAxisRaw("Vertical");

        if (movement.x > 0)
        {
            rend.flipX = true;
        }
        else if (movement.x < 0)
        {
            rend.flipX = false;
        }
        
        rigidbody2D.velocity  = movement * movementSpeed;
    }

    private void UpdateState()
    {
        //걷기
        if (Mathf.Approximately(movement.x, 0) && Mathf.Approximately(movement.y, 0))
        {
            animator.SetBool("isMove", false);
        }
        else
        {
            animator.SetBool("isMove", true);
        }


        //달리기
        if (Input.GetKey(KeyCode.LeftShift)){
            movementSpeed = runSpeed;
            animator.SetBool("isRun", true);
        }
        else{
            movementSpeed = normalSpeed;
            animator.SetBool("isRun", false);
        }


        //웅크리기
        if (Input.GetKey(KeyCode.LeftControl))
        {
            movementSpeed = crouchSpeed;
            animator.SetBool("isCrouch", true);
        }
        else
        {
            movementSpeed = normalSpeed;
            animator.SetBool("isCrouch", false);
        }


        //대기상태 x방향 설정
        if (movement.x > 0)
        {
            animator.SetFloat("horIdle", 1);
            animator.SetFloat("verIdle", 0);
        }
        else if (movement.x < 0)
        {
            animator.SetFloat("horIdle", -1);
            animator.SetFloat("verIdle", 0);
        }


        //대기상태 y방향 설정
        if (movement.y > 0)
        {
            animator.SetFloat("verIdle", 1);
            animator.SetFloat("horIdle", 0);
        }
        else if (movement.y < 0)
        {
            animator.SetFloat("verIdle", -1);
            animator.SetFloat("horIdle", 0);
        }

        animator.SetFloat("horizontal", movement.x);
        animator.SetFloat("vertical", movement.y);
    }

    
}

This is the code I wrote for the Player's momvement and I can't find any problems here.

CodePudding user response:

Modify your if else statements that check for the user input, into this:

if (Input.GetKey(KeyCode.LeftShift))
{
    movementSpeed = runSpeed;
    animator.SetBool("isRun", true);
}
else if (Input.GetKey(KeyCode.LeftControl))
{
    movementSpeed = crouchSpeed;
    animator.SetBool("isCrouch", true);
}
else
{
    movementSpeed = normalSpeed;
    animator.SetBool("isRun", false);

    movementSpeed = normalSpeed;
    animator.SetBool("isCrouch", false);
}

You are using two if-else statements to check for the user input. For every if, there is an else, hence it's ambiguous which else has to be executed when there is no user input.

CodePudding user response:

I generally like to keep my if statements as simple as possible. That way, there's less likelihood of introducing a logic error.

public class PlayerController : MonoBehaviour
{
    [SerializeField] private float movementSpeed = 3.0f;
    [SerializeField] private float normalSpeed, runSpeed, crouchSpeed;

    private Vector2 movement;
    private SpriteRenderer rend;
    private Rigidbody2D rigidbody2D;

    Animator animator;

    void Start ( )
    {
        movement = Vector2.zero;
        rend = GetComponent<SpriteRenderer> ( );
        animator = GetComponent<Animator> ( );
        rigidbody2D = GetComponent<Rigidbody2D> ( );
    }

    private void FixedUpdate ( )
    {
        rigidbody2D.velocity = movement * movementSpeed;
    }

    private void Update ( )
    {
        movement.x = Input.GetAxisRaw ( "Horizontal" );
        movement.y = Input.GetAxisRaw ( "Vertical" );

        if ( movement.x > 0 )
            rend.flipX = true;
        else if ( movement.x < 0 )
            rend.flipX = false;

        //걷기
        animator.SetBool ( "isMove", movement != Vector2.zero );
        movementSpeed = normalSpeed;

        // We can check the key codes in one place, outside of any conditional code.
        var isRun = Input.GetKey ( KeyCode.LeftShift );
        var isCrouch = Input.GetKey ( KeyCode.LeftControl );

        //달리기
        animator.SetBool ( "isRun", isRun );
        if ( isRun ) movementSpeed = runSpeed;

        //웅크리기
        // Crouch is checked after Run. This makes crouch override run if both keys are pressed.
        animator.SetBool ( "isCrouch", isCrouch );
        if ( isCrouch ) movementSpeed = crouchSpeed;

        // Here we assume that idle will be zero when there is no 'movement'
        Vector2 idle = Vector2.zero;

        // If there is movement then we update the idle value.
        //대기상태 x방향 설정
        if ( movement.x > 0 )
            idle.x = 1;
        else if ( movement.x < 0 )
            idle.x = -1;

        //대기상태 y방향 설정
        if ( movement.y > 0 )
            idle.y = 1;
        else if ( movement.y < 0 )
            idle.y = -1;

        animator.SetFloat ( "verIdle", idle.x );
        animator.SetFloat ( "horIdle", idle.y );

        animator.SetFloat ( "horizontal", movement.x );
        animator.SetFloat ( "vertical", movement.y );
    }
}
  • Related