统一:如何在向方向旋转后强制旋转?

发布于 2025-02-08 20:04:20 字数 2327 浏览 1 评论 0原文

在询问 for shere for solution ,我的领域有效, “步行”到列表的每个点。现在,我试图“强制”围绕X轴旋转,以伪造球是“滚动”。我提出了以下代码,但它不起作用(这使我俩都不想要并且……不明白的X轴上的旋转逐渐加速了)。

创建一个新项目,添加一个球体并添加此小脚本。然后在点列表中添加2分。该脚本除了移动对象(球形)列表的每个点外,什么也无能为力,然后在X轴周围进行简单的旋转。

围绕X轴的简单旋转是不现实的(只要球体不改变方向,它就可以工作,但是在这种情况下,它应该在z上旋转x +,但我也不知道该怎么做。 。

using UnityEngine;

public class MoveAlongPath : MonoBehaviour
{
    public Vector3[] points;
    public float speed = 1.0f;
    public float rotateSpeed = 200.0f;
    public float minDistance = Vector3.kEpsilon;
    private SphereCollider _c;
    [SerializeField] private Vector3 _posStart;
    [SerializeField] private Vector3 _posEnd;
    [SerializeField] private int _currentIndex;
    [SerializeField] private Rigidbody _rigidbody;
    [SerializeField] private Vector3 _direction;
    [SerializeField] private Vector3 _directionNormalized;
    [SerializeField] private float _xRotation;

    private void NextPoint()
    {
        _posStart = points[_currentIndex];
        transform.position = _posStart;
        _currentIndex = ++_currentIndex % points.Length;
        _posEnd = points[_currentIndex];
        _direction = _posEnd - _posStart;
        _directionNormalized = _direction.normalized;
    }

    private void Start()
    {
        _rigidbody = GetComponent<Rigidbody>();
        NextPoint();
    }

    private void FixedUpdate()
    {
        _xRotation = (_xRotation + -10 * Time.fixedDeltaTime) % 360;
        Quaternion q = Quaternion.LookRotation(
            _directionNormalized, Vector3.up
        );
        
        transform.rotation = Quaternion.RotateTowards(
            transform.rotation, q, rotateSpeed * Time.fixedDeltaTime
        ) * Quaternion.AngleAxis(_xRotation, Vector3.left);
        
        Vector3 step = speed * Time.fixedDeltaTime * _directionNormalized;
        if (step.magnitude > _direction.magnitude) {
            step = _direction; // don't overshoot
        } 
        Vector3 newPos = transform.position + step;
        _rigidbody.MovePosition(newPos);
        if (Vector3.Distance(_posEnd, transform.position) < minDistance) {
            /* close enough -> next point: */
            NextPoint();
        }
    }
}

After asking here for a solution, which worked, my sphere "walks" to each point of a list. Now, I'm trying to "force" a rotation around the x axis, to fake the ball is "rolling". I came up with the following code, but it doesn't work (it makes a progressive acceleration of the rotation on the x-axis, which I both dont want and... dont understand).

Create a new project, add a sphere and add this small script. Then add 2 points in the points list. This script does nothing but moving the object (the sphere) each points of the list, and make a simple rotation around the x-axis.

Simple rotation around the x-axis is not realistic (it's working as long as the sphere doesn't change its direction, but in this case, it should rotate on x + on z, but I dont know how to do this too...) so if you have a more realistic idea its even more welcome.

using UnityEngine;

public class MoveAlongPath : MonoBehaviour
{
    public Vector3[] points;
    public float speed = 1.0f;
    public float rotateSpeed = 200.0f;
    public float minDistance = Vector3.kEpsilon;
    private SphereCollider _c;
    [SerializeField] private Vector3 _posStart;
    [SerializeField] private Vector3 _posEnd;
    [SerializeField] private int _currentIndex;
    [SerializeField] private Rigidbody _rigidbody;
    [SerializeField] private Vector3 _direction;
    [SerializeField] private Vector3 _directionNormalized;
    [SerializeField] private float _xRotation;

    private void NextPoint()
    {
        _posStart = points[_currentIndex];
        transform.position = _posStart;
        _currentIndex = ++_currentIndex % points.Length;
        _posEnd = points[_currentIndex];
        _direction = _posEnd - _posStart;
        _directionNormalized = _direction.normalized;
    }

    private void Start()
    {
        _rigidbody = GetComponent<Rigidbody>();
        NextPoint();
    }

    private void FixedUpdate()
    {
        _xRotation = (_xRotation + -10 * Time.fixedDeltaTime) % 360;
        Quaternion q = Quaternion.LookRotation(
            _directionNormalized, Vector3.up
        );
        
        transform.rotation = Quaternion.RotateTowards(
            transform.rotation, q, rotateSpeed * Time.fixedDeltaTime
        ) * Quaternion.AngleAxis(_xRotation, Vector3.left);
        
        Vector3 step = speed * Time.fixedDeltaTime * _directionNormalized;
        if (step.magnitude > _direction.magnitude) {
            step = _direction; // don't overshoot
        } 
        Vector3 newPos = transform.position + step;
        _rigidbody.MovePosition(newPos);
        if (Vector3.Distance(_posEnd, transform.position) < minDistance) {
            /* close enough -> next point: */
            NextPoint();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文