通過閱讀Unity ECS Samples 里的物理碰撞的范例谓媒,發(fā)現(xiàn)里面的好玩的實現(xiàn)方式。
首先Unity 的 DOTS Physic 本身的碰撞事件 只提供了 某兩個Entity 碰撞類似回調的接口寸痢。
并不像原來是直接在GameObject 上掛接的腳本上返回停士。
這就造成了提供的功能與易用性存在一定的差距舅柜。
直觀的方式應該是在Entity 的組件內自動填充碰撞事件迟隅,邏輯系統(tǒng) 甚至是碰撞特效等System
可以直接在Component 里讀取碰撞的事件即可
為了簡化問題但骨,這里可以拆分成兩個問題
- 如何在ECS里面處理事件
- 如何在兩個列表中將
如何在ECS里面處理事件 方法如下:
- 產生的事件使用鏈表或數組先保存在System中
- 給需要接受事件的Entity 添加 特定的 BufferComponent 類型 用于接受事件
- 在System 處理數據的時候, 將之前所有 Buffer Component 內容清空智袭,
然后將符合條件的事件 放入 上面的Buffer Component 中 - 其他System 查詢 該Buffer Component 并進行處理
根據項目需求奔缠,上面的方案很容易做成通用的代碼
在兩個列表中 將 進入,保持吼野,離開 的狀態(tài)計算出來的算法如下:
該問題可以再簡化成校哎,把數據分成兩個整形數組,一個表示過去B瞳步,一個表示現(xiàn)在A
如何 知道數組A 相對于 數組B闷哆, 如何區(qū)分哪個數字是 新加的,已有的单起,刪除的 這3個狀態(tài)抱怔。
具體算法如下:
- 將A , B 兩個數組 都按小到大排序
- 給A馏臭, B 分配兩個 游標 ia野蝇, ib 分別代表A 讼稚,B 兩個數組的當前下標
- 對 ia 于 ib 指向的數組內容進行比較括儒, 如果 A[ia] == B[ib] 表示已有的,并且ia锐想,ib兩個游標同時累加1
- 如果A[ia] < B[ib] 就是說A[ia] 指向的 數字是新加的帮寻, ia 游標 +1, ib 游標不變
- 如果A[ia] > B[ib] 就說明B[ib] 指向的 數字是被刪除的赠摇,ia 游標不變固逗, ib 游標加1
- 如果ib 游標 先到頂浅蚪, 那么ia 后面所有的數字都是新加的
- 如果ia 游標 先到頂, 那么ib 后面素有的數字都是要被刪除的
- 反復執(zhí)行 步驟3 - 5烫罩, 知道所有數字都 有一個狀態(tài)
下面分析上面算法為什么有效: