【问题标题】:Orbiting body constantly spinning while over southern hemisphere在南半球上空不断旋转的轨道体
【发布时间】:2019-06-10 18:02:08
【问题描述】:

我正试图让我的身体自行在地球上行走,但当身体到达地球的“下”半球时就会出现问题。
每当身体到达那里时,它就会疯狂地旋转,直到身体回到地球的“上”半球才会停止。
吸引子

public class Attractor : MonoBehaviour
{
    [SerializeField] private float _gravity = -10;

    public void Attract(Body body)
    {
        Vector3 targetDir = (body.transform.position - transform.position).normalized;
        Vector3 bodyUp = body.transform.up;

        body.transform.rotation *= Quaternion.FromToRotation(bodyUp, targetDir);
        body.GetComponent<Rigidbody>().AddForce(targetDir * _gravity);
    }
}  

身体

public class Body : MonoBehaviour
{
    [SerializeField] private Attractor _curAttractor;

    private Rigidbody _rb;

    private void Awake()
    {
        _rb = GetComponent<Rigidbody>();
        _rb.useGravity = false;
        _rb.constraints = RigidbodyConstraints.FreezeRotation;
    }

    private void FixedUpdate()
    {
        _curAttractor.Attract(this);
    }
}  

路径追随者

public class PathFollower : MonoBehaviour
{
    [SerializeField] private float _moveSpeed;
    [SerializeField] private float _reach;
    private Path _curPath;
    private Rigidbody _rb;

    private void Awake()
    {
        _rb = GetComponent<Rigidbody>();
    }

    public void FollowPath(Path p)
    {
        StopAllCoroutines();
        _curPath = p;
        StartCoroutine(FollowCtn());
    }

    private IEnumerator FollowCtn()
    {
        int i = 0;
        Vector3 target;

        while (i < _curPath.Nodes.Length)
        {
            target = PathfindingData.NodeToWorldPosition(_curPath.Nodes[i]);
            Vector3 dir;

            while (Vector3.Distance(transform.position, target) > _reach)
            {
                dir = target - transform.position;
                dir.Normalize();
                _rb.MovePosition(_rb.position + dir * _moveSpeed * Time.deltaTime);
                yield return null;
            }

            i++;
        }

        _rb.velocity = Vector3.zero;
        _curPath = null;
    }
}  

关于可能导致这种奇怪行为的任何想法?

这就是我所说的疯狂旋转的意思:

【问题讨论】:

    标签: c# unity3d rotation quaternions


    【解决方案1】:

    FromToRotation 最适合您关心只有一个轴指向的位置,因为它会以任何方式改变其他轴的方向,从而最小化两个旋转之间的角度。换句话说,FromToRotation 将改变对象的偏航,前提是这样做会减少俯仰或滚动所需的变化。

    因为您关心变换的up(始终指向远离吸引子)和forward(在FixedUpdate 调用之间尽可能少地改变),所以最好使用另一条路线。

    使用Vector3.OrthoNormalizeQuaternion.LookRotation指定targetDir方向为向上,并尽可能保持body的transform.forward不变(如果它们是共线的,则使用forward的任意方向):

    Vector3 targetDir = (body.transform.position - transform.position).normalized;
    Vector3 bodyForward = body.transform.forward; 
    Vector3.OrthoNormalize(ref targetDir, ref bodyForward); 
    
    body.transform.rotation = Quaternion.LookRotation(bodyForward, targetDir);     
    body.GetComponent<Rigidbody>().AddForce(targetDir * _gravity);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-11
      • 1970-01-01
      • 2015-07-18
      • 2011-05-01
      • 2016-03-02
      • 2014-12-24
      • 2019-05-03
      • 1970-01-01
      相关资源
      最近更新 更多