统一。如何使玩家转向运动方向

Posted

技术标签:

【中文标题】统一。如何使玩家转向运动方向【英文标题】: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); 一切都很好。你可以创建一个答案,我会接受它 【参考方案1】:

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

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

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

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

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; 行放入空闲检查中,并更改了空闲的确定方式

以上是关于统一。如何使玩家转向运动方向的主要内容,如果未能解决你的问题,请参考以下文章

如何将此统一运动脚本转换为刚体?

如何使跟踪渲染器不受统一 3d 中 z 轴运动的影响

使用基于相机朝向的操纵杆的玩家运动

C# Unity 2D 自上而下的运动脚本不起作用

玩家运动的python类问题[关闭]

如何区分方向键运动和操纵杆运动?