【问题标题】:Unity. How to turn the player in the direction of movement统一。如何使玩家转向运动方向
【发布时间】:2020-10-29 11:23:11
【问题描述】:

正如您在此视频中看到的那样,对象向任何方向移动,但其模型不会沿移动方向旋转。怎么解决??

视频链接

https://youtu.be/n4FDFDlsXK4

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

public class MoveController : MonoBehaviour
{
    private CharacterController controller = null;
    private Animator animator = null;
    private float speed = 5f;


    void Start()
    {
        controller = gameObject.GetComponent<CharacterController>();
        animator = gameObject.GetComponent<Animator>();
    }

    void Update()
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

        Vector3 move = (transform.right * x) + (transform.forward * z);
        controller.Move(move * speed * Time.deltaTime);

        var angle = Mathf.Atan2(move.z, move.x) * Mathf.Rad2Deg;

        if (x != 0 || z != 0) animator.SetTrigger("run");
        if (x == 0 && z == 0) animator.SetTrigger("idle");
    }
}

【问题讨论】:

  • 没有代码,不可能知道你做了什么让它转动或没有做什么
  • 试试这个:Vector3 move = new Vector3(x, 0f, z);transform.forward = move;controller.Move(move * speed * Time.deltaTime);
  • 一切都很好。你可以创建一个答案,我会接受它

标签: c# unity3d game-engine


【解决方案1】:

不要使用transform.forwardtransform.right 来制作您的移动矢量,只需在世界空间中制作即可。然后,您可以将transform.forward设置为移动方向。

另外,正如derHugo 在下面的评论中提到的,你应该

  1. 避免使用完全相等来比较浮点数。而是使用Mathf.Approximately 或使用您自己的阈值,如下所示

  2. 避免每帧设置触发器。相反,您可以使用一个标志来确定您是否已经空闲或已经在运行,并且仅在您尚未执行此操作时才设置触发器。

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

public class MoveController : MonoBehaviour
{
    private CharacterController controller = null;
    private Animator animator = null;
    private float speed = 5f;
    bool isIdle;

    void Start()
    {
        controller = gameObject.GetComponent<CharacterController>();
        animator = gameObject.GetComponent<Animator>();
        isIdle = true;
    }

    void Update()
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

        Vector3 move = new Vector3(x, 0f, z);
        controller.Move(move * speed * Time.deltaTime);

        var angle = Mathf.Atan2(move.z, move.x) * Mathf.Rad2Deg;

        if (move.magnitude > idleThreshold)
        {
            transform.forward = move;
            if (isIdle) 
            {
                animator.SetTrigger("run");
                isIdle = false;
            }
        } 
        else if (!isIdle)
        {
            animator.SetTrigger("idle");
            isIdle = true;
        }
    }
}

【讨论】:

  • 你仍然不应该像if (x != 0 || z != 0)if (x == 0 &amp;&amp; z == 0)那样直接比较float的值......如果你想设置一个触发器每帧,这通常是有问题的...但除此之外,它应该是if(Mathf.Approxiamtely(x, 0) &amp;&amp; Mathf.Approximately(z, 0)) { animator.SetTrigger("idle"); } else { animator.SetTrigger("run"); } 或直接animator.SetTrigger(Mathf.Approxiamtely(x, 0) &amp;&amp; Mathf.Approximately(z, 0) ? "idle" : "run");
  • @derHugo 啊,这就是我在不阅读所有内容的情况下复制和粘贴问题代码的结果。很好的建议,我将它们包含在答案中
  • 告诉我为什么不保存旋转角度。它总是重置为零
  • @Саске 我将transform.forward = move; 行放入空闲检查中,并更改了空闲的确定方式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多