问一个游戏小白的问题

怎么知道两个碰撞事件由谁触发呢,
比如子弹和敌人碰撞,是在子弹的碰撞回调去调用敌人脚本里的扣血方法,还是在敌人的碰撞回调里调用子弹的伤害去扣血
怎么写才能使得整个的逻辑通顺呢,现在在尝试自己写一个割草小游戏,很多碰撞触发的方法不知道该写在哪里,
求大佬指点

碰撞的回调里面有明确两个对象的,打印出来看一下就明白了。

双分派的方式,例如AB碰撞,总是有一些逻辑不知道归类到A还是B。方式有几种
1.分别处理
碰撞 = A.onCollision(B) + B.onCollision(A)
一般来说,如果不想提取,把和非常相关的放自己逻辑里面,例如A受到伤害放A.onCollision(B)里面,B销毁放到B.onCollision(A) 里面。双方都有依赖的逻辑,可以任意放在A,B。但是需要对比一下放哪个类里面到时候变化的时候方便变更。

2.提取逻辑
另外还有一种方式,是提取,把双分派的逻辑全部提取,走矩阵式调用
碰撞 =CollisionHandler.OnColllsion(A,B).
这种的话,预先注册好(A,B) 作为key,handler函数作为value。碰撞的时候走handler。这样双方就都没有直接依赖了。很多游戏工具通过表格也做了类似的方式。

3.逻辑系统
第二种方式还有一个变体,是系统式的。通常在ecs里面作为一个系统。在简单小游戏里面可能是一个函数。
全体碰撞 = handleAllCollisionBetweenAB(A_List,B_List) ,里面直接用循环判断处理和优化
这种其实和第二种差不多,不过某些需要性能的地方,会比较容易优化。也可以作为较小游戏中GameController.update中间的一个流程。

一般来说,我倾向于第二种,C#的dynamic 参数也可以支持动态双分派到重载函数,参数类型不一样就可以,表都不需要定义了。第一种比较OO,第三种比较适合ecs,看情况都可以使用。

编辑:
由于大量游戏都使用内置物理,内置物理的collision一般是在脚本里面给onCollision的事件,这种内置物理的事件本身就是第一种形式,如果要转换成第二种,就在onCollision的时候传到CollisionHandler表里面,通过类型顺序避免2次调用。如果要转换成第三种,就把对应的碰撞对记录到队列里面,后面统一进行处理。
我一般是不太使用内置物理的,都自己手搓碰撞系统,所以用哪一种形式都比较方便。

大佬 第二种方法中的CollisionHandler是ccc自带的组件 还是我自己创建一个类去监听呢

我这里说的是比较通用的,相当于就是你自己抽出来一个类,专门处理碰撞反应,这样就不需要苦恼哪些逻辑在A的部分,哪些逻辑在B的部分了。逻辑都在一个函数里面比较清晰。

不是ccc的组件,要自己抽,抽了一个类以后所有物体的碰撞都走这个中间类就可以。

明白了,感谢大佬指点