Unity Game Engine 有这个很好的方法来检测碰撞:
它们都采用一个 Collision 对象来实现所有这些情况的逻辑。为了实现这些方法,我采用了一个可碰撞对象(AKA Player)和“listen”它的碰撞来实现一些逻辑。 示例:
public class PlayerController : MonoBehaviour
{
...
private void OnCollisionEnter(Collision collision)
{
Debug.Log("Colission detected with object");
}
...
}
但是,有一些问题可能需要使用嵌套 switch case(丑陋)或者可能需要一些 多态性 或 字典 - 委托 或其他东西。
第一个问题:玩家可以与任何对象存在或待创建发生碰撞。
碰撞的“state”可以是“enter”或“stay”或“exit”;因此,我需要能够管理 3 个“states”次 x 数量的“objects”进行碰撞。
为了“引用”“与碰撞”GameObjectUnity提出了一些建议AWFUL:通过“TAG”或“NAME”来引用对象:
private void OnCollisionEnter(Collision collision){
if (collision.gameObject.tag == "Ball"){
Debug.Log("Player collided with an object with TAG 'Ball'");
}
}
请想象一下,当我考虑为 30 个对象实现 3 种状态(进入、停留、退出)时。 Switch/cases 或嵌套 ifs 将成为一场噩梦,并打破所有良好的代码约定。
我这样做的原因是因为我想要某种“事件监听器”,但我不知道如何在 C# 中实现,其中:
public class PlayerController : MonoBehaviour
{
...
private enum CollisionState { ENTER, STAY, EXIT }
private enum CollisionableGameObject { COUNTER, SINK }
private Dictionary<CollisionableGameObject, Func<CollisionState, Collision, bool>> collisionEvent;
private void Start()
{
this.collisionEvent = new Dictionary<CollisionableGameObject, Func<CollisionState, Collision, bool>>
{
[CollisionableGameObject.COUNTER] = new Func<CollisionState, Collision, bool>(CollideCounter),
[CollisionableGameObject.SINK] = new Func<CollisionState, Collision, bool>(CollideSink)
};
}
private void OnCollisionEnter(Collision collision)
{
this.CollisionManager(collision, CollisionState.ENTER);
if (collision.gameObject.TryGetComponent(out ClearCounterController clearCounter))
{
Debug.Log("Colission detected with clear counter");
}
}
private void CollisionManager(Collision collision, CollisionState state)
{
if (this.collisionEvent.TryGetValue("")) {
//BY THIS POINT NO IDEA WHAT AM I DOING
}
}
private bool CollideCounter(CollisionState state, Collision collision)
{
return true;
}
第一次使用字典和委托,现在我什至不理解我自己的代码。也许我在尝试归档良好的编程实践时增加了复杂性。但由于我是 Unity 和 C# 的新手,我知道我需要什么,但不知道如何去做,入门级 Unity 教程让我热血沸腾。如果有任何具有 C# 经验的高级工程师,我希望得到你们的意见。
提前非常感谢。
但这会带来一个像你所说的问题;很多 if 控制。你不应该用这种方式控制 30 个物体。但你可以控制一个界面。
例如创建一个名为“ICollideable”的接口
public interface ICollideable{
public void OnCollide();
}
并尝试在 PlayerController 类中获取 ICollideable 接口。然后调用OnCollide函数。
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.TryGetComponent(out ICollideable collideable))
{
collideable.OnCollide();
}
}
不要忘记在您的类中实现我们的接口。
public class ClearCounterController : ICollideable{
public void OnCollide(){
// Do whatever you want here.
}
}
您也可以通过这种方式创建停留和退出功能。