簡體   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