【发布时间】:2021-01-18 19:28:57
【问题描述】:
所以我正在制作一个以海军方式处理战斗的 2D 空间 shmup。所以你射出船的舷侧,你的盾牌和船体分为 4 个部分:前、右、左和后。我不是最擅长数学的人,但我设法找到了一个脚本来检测我的多边形对撞机被碰撞或抛射物击中的一侧。这一切都很好。
问题是我的精灵在 2D 空间中旋转。因此,当我与某物相撞时,例如与我的船头相撞,如果我的船头向上,则可以正确检测到碰撞。但是如果船旋转并且机头现在在左侧并且我与机头上的东西发生碰撞,脚本会将机头碰撞检测为左舷碰撞。有人可以帮我纠正数学以解释我的船的旋转吗?
Collision2DExtension.cs
using UnityEngine;
namespace PixelsoftGames
{
public static class Collision2DExtensions
{
public static Collision2DSideType GetContactSide(Vector2 max, Vector2 center, Vector2 contact)
{
Collision2DSideType side = Collision2DSideType.None;
float diagonalAngle = Mathf.Atan2(max.y - center.y, max.x - center.x) * 180 / Mathf.PI;
float contactAngle = Mathf.Atan2(contact.y - center.y, contact.x - center.x) * 180 / Mathf.PI;
if (contactAngle < 0)
{
contactAngle = 360 + contactAngle;
}
if (diagonalAngle < 0)
{
diagonalAngle = 360 + diagonalAngle;
}
if (
((contactAngle >= 360 - diagonalAngle) && (contactAngle <= 360)) ||
((contactAngle <= diagonalAngle) && (contactAngle >= 0))
)
{
side = Collision2DSideType.Starboard;
}
else if (
((contactAngle >= 180 - diagonalAngle) && (contactAngle <= 180)) ||
((contactAngle >= 180) && (contactAngle <= 180 + diagonalAngle))
)
{
side = Collision2DSideType.Port;
}
else if (
((contactAngle >= diagonalAngle) && (contactAngle <= 90)) ||
((contactAngle >= 90) && (contactAngle <= 180 - diagonalAngle))
)
{
side = Collision2DSideType.Forward;
}
else if (
((contactAngle >= 180 + diagonalAngle) && (contactAngle <= 270)) ||
((contactAngle >= 270) && (contactAngle <= 360 - diagonalAngle))
)
{
side = Collision2DSideType.Rear;
}
return side.Opposite();
}
static bool ranOnce = false;
public static Collision2DSideType GetContactSide(this Collision2D collision)
{
Vector2 max = collision.collider.bounds.max;
Vector2 center = collision.collider.bounds.center;
Vector2 contact = collision.GetContact(0).point;
if (!ranOnce)
{
ranOnce = true;
Debug.Log("Max: " + max);
Debug.Log("Center: " + center);
Debug.Log("Contact: " + contact);
}
return GetContactSide(max, center, contact);
}
}
}
Collision2DSideTypeExtensions.cs
namespace PixelsoftGames
{
public static class Collision2DSideTypeExtensions
{
public static Collision2DSideType Opposite(this Collision2DSideType sideType)
{
Collision2DSideType opposite;
if (sideType == Collision2DSideType.Port)
{
opposite = Collision2DSideType.Starboard;
}
else if (sideType == Collision2DSideType.Starboard)
{
opposite = Collision2DSideType.Port;
}
else if (sideType == Collision2DSideType.Forward)
{
opposite = Collision2DSideType.Rear;
}
else if (sideType == Collision2DSideType.Rear)
{
opposite = Collision2DSideType.Forward;
}
else
{
opposite = Collision2DSideType.None;
}
return opposite;
}
}
}
Collision2DSideType
public enum Collision2DSideType { None, Port, Starboard, Forward, Rear }
【问题讨论】: