我在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),所以我怀疑动画相关部分出了问题。
或者看起来计算机无法处理,因为协程相关部分的计算量很大。 我对其中任何一个都不满意。
首先,您遇到的问题可能是由于协程的使用造成的。每次按下按钮时都会调用协程,这就像创建一个新的计时器,里面发生很多事情。另一方面:
Update()
函数(将读取输入代码放在这里以最大化输入响应延迟)考虑到这一点,这是相应使用
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 函数的使用方式。