Орбитальное тело постоянно вращается над южным полушарием - PullRequest
1 голос
/ 10 июня 2019

Я пытаюсь заставить свои тела обходить планету самостоятельно, но возникают проблемы, когда тело попадает в «нижнее» полушарие планеты.
Всякий раз, когда тело попадает туда, оно вращается как сумасшедший и побеждаетне останавливайтесь, пока тело не вернется в «верхнее» полушарие планеты.
Аттрактор

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

PathFollower

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

Есть идеи о том, что может быть причиной этого странного поведения?

Вот что я подразумеваю под спинами как сумасшедшие:
body spins on yaw axis while it is over southern hemisphere

1 Ответ

2 голосов
/ 10 июня 2019

FromToRotation лучше всего, когда вас интересует, куда указывает только одна ось, потому что это изменит направления других осей любым способом, который минимизирует угол между двумя поворотами. Другими словами, FromToRotation изменит рыскание вашего объекта, если это уменьшит изменения, необходимые для подачи или крена.

Поскольку вас интересуют up преобразования (всегда указывающие в сторону от аттрактора) и forward (изменяющиеся как можно меньше между вызовами FixedUpdate), предпочтителен другой маршрут.

Используйте Vector3.OrthoNormalize и Quaternion.LookRotation, чтобы указать направление targetDir как вверх, и сохраняйте 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...