刚体圆周运动 [英] Rigidbody circular movement

查看:118
本文介绍了刚体圆周运动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个2D球,该球具有一定的力并沿不确定的方向移动,所以我需要使用户在触摸屏幕时,球相对于当前方向相对于当前方向向右或向左或向右圆形移动.我该怎么办?

I have a 2D ball that has a force and moves in indeterminate direction, i need to make ball moves circular to right or left when user touches the screen, in relative to current direction without changing speed. How can i do that?

我尝试了这段代码,但是其他物理学无法影响球,因为我们直接更改了转换:

I tried this code, but other physics cannot affect the ball, because we are changing transform directly :

float angle = 0;
float radius = 1;

void FixedUpdate()
{
    angle += speed * Time.deltaTime;
    float x = center.x + Mathf.Cos(angle) * radius;
    float y = center.y + Mathf.Sin(angle) * radius;

    rigidbody.transform.position = new Vector3(x, y, 3);
}

推荐答案

就像物理学一样:

您的触摸位置有点像引力中心→以相同的幅度但以新的方向连续分配一个新方向,该方向与从中心到运动物体和旋转轴的矢量成90°角.

Your touch position is kind of a gravitation center → Continuously assign a new direction using the same magnitude but in a new direction which stands in a 90° angle to the vector from center to the moving object and the rotation axis.

在代码中看起来像

public class Example : MonoBehaviour
{
    [SerializeField] private Rigidbody2D rb;
    [SerializeField] private Camera _camera;

    [SerializeField] private Vector2 initialVelocity;    

    private bool doGravitation;
    private Vector2 centerPos;

    private void Awake()
    {
        if(!rb) rb = GetComponent<Rigidbody2D>();
        if(!_camera) _camera = Camera.main;

        rb.velocity = initialVelocity;
    }

    private void Update()
    {
        // check for touch support otherwise use mouse as fallback
        // (for debugging on PC)
        if (Input.touchSupported)
        {
            // not touching or too many -> do nothing
            if (Input.touchCount != 1)
            {
                doGravitation = false;
                return;
            }

            var touchPosition = Input.GetTouch(0).position;
            centerPos = _camera.ScreenToWorldPoint(touchPosition);
            doGravitation = true;
        }
        else
        {
            // mouse not pressed -> do nothing
            if (!Input.GetMouseButton(0))
            {
                doGravitation = false;
                return;
            }

            centerPos = _camera.ScreenToWorldPoint(Input.mousePosition);
            doGravitation = true;
        }
    }

    private void FixedUpdate()
    {
        if(!doGravitation) return;

        // get current magnitude
        var magnitude = rb.velocity.magnitude;

        // get vector center <- obj
        var gravityVector = centerPos - rb.position;

        // check whether left or right of target
        var left = Vector2.SignedAngle(rb.velocity, gravityVector) > 0;

        // get new vector which is 90° on gravityDirection 
        // and world Z (since 2D game)
        // normalize so it has magnitude = 1
        var newDirection = Vector3.Cross(gravityVector, Vector3.forward).normalized;

        // invert the newDirection in case user is touching right of movement direction
        if (!left) newDirection *= -1;

        // set new direction but keep speed(previously stored magnitude)
        rb.velocity = newDirection * magnitude;
    }
}

另请参阅:

  • Input.GetTouch
  • Touch.position
  • Camera.ScreenToWorldPoint
  • Vector2.SignedAngle
  • Vector3.Cross

请注意,这有时看起来很奇怪,尤其是在碰到球的前面时,因为我们将其逼到可能与当前运动成奇怪角度的圆曲线上.您可以解决这个问题,但这取决于您;)

Note that this sometimes looks strange especially when touching in front of the ball since we force it onto a circle curve that might have a strange angle to the current movement. You can smooth that out but that's up to you ;)

这篇关于刚体圆周运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆