0

I wrote the code in Unity hoping that the character can move in all directions in two dimensions if I press the direction key. (If I press the shift key, it moves fast.) However, after writing the code related to the animation, the character gets a bug that doesn't move even if I press the direction key. I hope you can tell me a solution or a solution for someone with a similar problem.

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

public class PlayerManager : MonoBehaviour
{
    public float speed;

    protected Vector3 vector;

    public float runSpeed;
    private float applyRunSpeed;

    private Animator anim;
   


    private void Start()
    {
        anim = GetComponent<Animator>();
        
    }

    IEnumerator MoveCoroutine()
    {
        

        while (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
        {
            if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
            {
                applyRunSpeed = runSpeed;
            }
            else
            {
                applyRunSpeed = 0;
            }

            vector.Set(Input.GetAxisRaw("Horizontal"),
                Input.GetAxisRaw("Vertical"), transform.position.z);


            anim.SetFloat("DirX", vector.x);
            anim.SetFloat("DirY", vector.y);
            anim.SetBool("Idle", false);

            if (vector.x != 0 || vector.y != 0)
            {
                transform.Translate(vector.x * (speed + applyRunSpeed) * Time.deltaTime,
                    vector.y * (speed + applyRunSpeed) * Time.deltaTime, 0);
            }
            yield return null;
        }
        anim.SetBool("Idle", true);
        

    }
    private void Update()
    {
        if (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
        {
            StartCoroutine(MoveCoroutine());
        }
    }
}

I've heard from chat GPT that this code does a lot of running unnecessarily because of the Corutine, and I've heard back that there's no code that actually moves the Sprite. But it worked well until I wrote the code related to animation (SetFloat, SetBool), so I suspect there's been a problem in the animation-related part.

Or it seems that the computer couldn't handle it because the amount of computation was high in the corutine-related part. I am not satisfied with any of them.

1 Answer 1

1

First of all, the issue you're experiencing is likely due to the usage of coroutines. The coroutine will be called every time you press the button and it's like creating a new timer with a lot of things going on inside. On the other hand:

  • The Update() function is being called every frame by Unity (put the reading Input code here to maximize the input respond latency)
  • The FixedUpdate() function is being called at every fixed time interval (this is to ensure that the physics-related code is being calculated consistently, so put the movement vector calculation here)
  • The LateUpdate() function is being called every time after the Update() function is finished (use this to update the animation since you only want to show the character position visually after finishing calculating all things)

With that in mind, this is the code using Update(),FixedUpdate() and LateUpdate() accordingly:

using UnityEngine;

public class PlayerManager : MonoBehaviour
{
    public float speed = 5f;
    public float runSpeed = 2f;

    private Vector2 movement;
    private bool isRunning;
    private Animator anim;
    private Rigidbody2D rb;

    private void Start()
    {
        anim = GetComponent<Animator>();
        rb = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {
        // Get input
        movement.x = Input.GetAxisRaw("Horizontal");
        movement.y = Input.GetAxisRaw("Vertical");
        isRunning = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
    }

    private void FixedUpdate()
    {
        // Move the character
        float currentSpeed = isRunning ? speed * runSpeed : speed;
        Vector2 velocity = movement.normalized * currentSpeed;
        rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime);
    }

    private void LateUpdate()
    {
        // Update animator
        anim.SetFloat("DirX", movement.x);
        anim.SetFloat("DirY", movement.y);
        anim.SetBool("Idle", movement.magnitude == 0);
    }
}

This approach separates concerns, improves performance, and ensures more consistent behavior across different frame rates and physics update intervals. Also note that, for easier movement control and collision detection, a Rigidbody2D should be attached to the player to apply physics to it. Hope this can help you better understand how each Update function is used.

5
  • This is really nice written and clean answer. Well done!! Commented Jul 8 at 6:27
  • The problem hasn't been solved. I think the problem that suddenly came to mind is probably caused by specifying the character's movement as a position value when creating an animation. Do you know how to create an animation that moves up and down with just one png file when creating an animation? When I press the arrow keys at the same time, it has to move to both sides. Commented Jul 8 at 13:00
  • I only recorded the values of transform, rotation, and scale in one png file (pressing the red button) to create an animation. Is that what caused the problem when I tried to move the character through the script? Commented Jul 8 at 13:12
  • Animation of unity is not a coding related area, but is it possible to ask questions? I'm afraid my account will be suspended if I ask the wrong question. Commented Jul 8 at 13:34
  • You helped me understand the coding system, thank you so much. I found another post related to the animation, so I'll try again. Commented Jul 8 at 13:48

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