繁体   English   中英

2D完美的抛射物反射与旋转

[英]2D Perfect projectile reflection with rotation

我正在拍摄射弹并将它们从墙壁上剥离 - 我想要一些不真实的完美反弹 - 物体不会失去速度并且不会在碰撞时开始旋转 - 只旋转一次以“匹配”反射方向。

我使用物理材料,因为它在墙壁和弹丸上有0摩擦力和1个弹性,我在弹丸0上使用重力刻度并且它的质量为0,0001 - 尽可能低的量和弹丸刚体已禁用旋转。

一切都工作正常,但我不能正确地使弹丸反弹旋转,我通过这种方式旋转它的变换:

public class Laser : MonoBehaviour {

    private new Rigidbody2D rigidbody2D;
    private Vector3 oldVelocity;

    private void Start() {
        rigidbody2D = GetComponent<Rigidbody2D>();
        boxCollider2D = GetComponent<BoxCollider2D>();
    }

    void FixedUpdate () {
        oldVelocity = rigidbody2D.velocity;
        rigidbody2D.freezeRotation = true;
    }

    void OnCollisionEnter2D (Collision2D collision) {
        ContactPoint2D contact = collision.contacts[0];

        Vector3 reflectedVelocity = Vector3.Reflect(oldVelocity, contact.normal);

        rigidbody2D.velocity = reflectedVelocity;

        Quaternion rotation = Quaternion.FromToRotation(oldVelocity, reflectedVelocity);
        transform.rotation = rotation * transform.rotation;

    }

}

目前看起来像这样 - 帧后踩帧 在此输入图像描述

我希望它在右边的碰撞点周围旋转:

在此输入图像描述

试试这个没有运气:

transform.RotateAround(contact.point, new Vector3(0f, 0f, 1f), Vector2.Angle(oldVelocity, reflectedVelocity));

这是修复原始代码的一种方法:将中心移动到接触点,在那里旋转并在本地坐标中再移动一次。 这是对此的尝试,它可能会起作用:

void OnCollisionEnter2D (Collision2D collision) {
    ContactPoint2D contact = collision.contacts[0];

    Vector3 reflectedVelocity = Vector3.Reflect(oldVelocity, contact.normal);

    rigidbody2D.velocity = reflectedVelocity;

    Quaternion rotation = Quaternion.FromToRotation(oldVelocity, reflectedVelocity);

    Vector3 toContact = transform.InverseTransformPoint(contact.normal); // Added
    transform.Translate(toContact); // Added
    transform.rotation = rotation * transform.rotation;
    transform.Translate(toContact); // Added
}

编辑:以下是如何计算与您正在寻找的RotateAround一起使用的“正确”角度:

float angle = Mathf.atan2(Vector3.dot(Vector3.Cross(v1, v2), Vector3.forwards), Vector3.Dot(v1, v2)) * Mathf.Rad2Deg;

无论是那个还是这个(使用Vector3.backwards而不是Vector3.forwards )。 左撇子的团结会让这些东西变得混乱。

float angle = Mathf.atan2(Vector3.dot(Vector3.Cross(v1, v2), Vector3.backwards), Vector3.Dot(v1, v2)) * Mathf.Rad2Deg;

就是这样

Vector3 v1 = oldVelocity;
Vector3 v2 = -reflectedVelocity;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM