(대가리 함몰)
오늘은 플레이어 유닛에게 콜라이더를 주려고 했다!
적 유닛 충돌 콜라이더 그-대로 플레이어 유닛 충돌 스크립트를 짰는데..
동작은 잘 되는데.. 무시 못할 에러가 뜨는거..!
적이 발사한 탄막과 플레이어가 충돌할 때,
아래의 에러를 내뱉었다.
Errors related to missing dependencies on previously scheduled jobs InvalidOperationException: The previously scheduled job <JOB NAME> writes to the <OBJECT TYPE> <FIELD IN JOB>. You are trying to schedule a new job <OTHER JOB NAME>, which writes to the same <OBJECT TYPE> (via <FIELD IN OTHER JOB>). To guarantee safety, you must include <JOB NAME> as a dependency of the newly scheduled job. |
Docs 왈,
Job 관련 Safety 시스템은 동일한 컴포넌트 타입을 여러개의 Job이 동시에 사용할 때, 안전하게 쓰고읽기가 가능한지 보장되어 있지
않기 떄문에 실제로 해당 컴포넌트 타입에 변화가 없었다 하더라도 내뱉는 에러다.
먼 개소린가 했는데.
막연하게 성능 좋아지겠지 ㅎㅎ 하고, 플레이어를 향해서 쏘는 탄막 시스템은 Job으로 이루어지고
플레이어 충돌 시스템도 Job으로 되어있는.. Multiple Job Shcedhiling 상황인 것이다..!
위의 코드는 단순히 회전 방향을 향해 나아가는 단순한 스크립트인데..
EnemyBulletTag 라는, 적의 탄막임을 알려주는 Tag 컴포넌트가 문제의 원인이였다.
열심히 서칭 해 본 결과
제안된 방법은 3가지 정도가 있었는데..
1번. EnemyBulletTag를 쓰지말고, 유니크한 Tag를 또 추가해서 쓰자
플레이어 충돌 스크립트에서, ComponentLookUp을 위한 EnemyBulletTag를 쓰고 있으니..
다른 Job에서 다른 컴포넌트를 쓰는 방식이다.
이러면.. 탄막 패턴마다 Tag를 계속 붙여야하는 미친 방식이니 스킵했다..
근데 이딴게 유니티 공식 스태프의 답변이냐 ㅅㅂ것..
2번. Schedule한 Job의 Retrun값, 즉 JobHandle을 Combine 하세요.
JobHandle을 NativeContainer로 묶어서 Combine하는 방식이다.
처음엔 딱 보고, 오.. 그럴싸한데 생각했는데
두 JobHandle을 묶어줄 MonoBehavior 클래스를 만들어야 한단다.
하지만, 두 Job은 서로 다른 시스템에서 사용하고 있어서.. 이걸 NativeContainer로 만들어 보낼 생각을 한다면...
3번. Depandancy를 명확하게 Ensure하자!
두 Job이 사용되는 순서를 명확하게 정해주고, Job의 사용을 Complete 해주는 방식이다.
어떻게보면, 제일 쉽고도 명확한 일을 삥 돌아서 왔다.
충돌 시스템을 감지하면, 더 이상 탄막 이동 Job이 돌 이유는 없으니까
순서를 충돌 시스템이 먼저 동작하도록 쥐어주었다.
[UpdateInGroup(typeof(PhysicsSystemGroup))]
[UpdateAfter(typeof(PhysicsSimulationGroup))]
[UpdateBefore(typeof(AfterPhysicsSystemGroup))]
public partial struct PlayerHitSystem : ISystem
가 먼저 진행된 다음.
[UpdateInGroup(typeof(PhysicsSystemGroup))]
[UpdateAfter(typeof(PlayerHitSystem))]
public partial struct TestEnemyBulletSystem : ISystem
탄막 이동 잡을 실행 시켜주는 시스템에 넘겨주면 끝!
글을 쓰고보니 진도가 너무 느리게 나가는 느낌인데...
ECS 참 쉽지 않다..!
그냥 병렬스케줄 뒤에 job.complete()해도 됨