Unity 中角色不移动

问题描述 投票:0回答:1

我在Unity中编写了代码,希望如果按下方向键,角色可以在二维方向上向各个方向移动。 (如果我按下shift键,它会移动得很快。)但是,在编写了与动画相关的代码后,角色出现了即使我按下方向键也不会移动的错误。希望您能告诉我解决方案或有类似问题的人的解决方案。

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());
        }
    }
}

我从 GPT 聊天中听说,由于 Coroutine,这段代码执行了大量不必要的运行,而且我听说没有任何代码可以真正移动 Sprite。 但一直运行良好,直到我写了动画相关的代码(SetFloat、SetBool),所以我怀疑动画相关部分出了问题。

或者看起来计算机无法处理,因为协程相关部分的计算量很大。 我对其中任何一个都不满意。

c# unity-game-engine animation
1个回答
0
投票

首先,您遇到的问题可能是由于协程的使用造成的。每次按下按钮时都会调用协程,这就像创建一个新的计时器,里面发生很多事情。另一方面:

  • Unity 每帧都会调用
    Update()
    函数(将读取输入代码放在这里以最大化输入响应延迟)
  • FixedUpdate()函数在每个固定的时间间隔被调用(这是为了确保物理相关的代码计算一致,所以把运动向量计算放在这里)
  • 每次`Update()函数完成后都会调用LateUpdate()函数(使用它来更新动画,因为您只想在完成所有计算后直观地显示角色位置)

考虑到这一点,这是相应使用

Update()
FixedUpdate()
LateUpdate()
的代码:

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);
    }
}

这种方法可以分离问题,提高性能,并确保在不同帧速率和物理更新间隔之间具有更一致的行为。希望这可以帮助您更好地了解每个 Update 函数的使用方式。

© www.soinside.com 2019 - 2024. All rights reserved.