2D идеальное отражение снаряда с вращением - PullRequest
0 голосов
/ 22 апреля 2019

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

Я использую физический материал, у которого 0 и трение на стенах и снарядах, я использую гравитационную шкалу для снаряда 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;

    }

}

В настоящее время выглядит так - шаг за кадром enter image description here

Я хочу, чтобы он вращался вокруг точки столкновения, как показано справа:

enter image description here

пробовал без удачи:

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

1 Ответ

0 голосов
/ 22 апреля 2019

Вот один из способов исправить исходный код: переместить центр в точку контакта, повернуть туда и еще раз переместиться в локальные координаты. Вот попытка, вероятно, это сработает:

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