오늘은 기획부분은 짧게로도 안하고 넘기고 코드로 바로 들어가겠다.
작일에 만들었던 Entity System과 Unit System,Animation System에서의 Entity와 GameObject,Animator 의 매핑 부분을 추가적으로 채워넣었다.
고민했던게 Animation System도 Entity에서 바로 엔티티를 만들때 Unit System(즉 GameObject)에서 독립적으로 Entity와의 매핑을 할수 없을까 고민했었다.
하지만 Unity에서 제공하는 Animator는 GameObject에 종속적임으로 그 둘의 의존성을 없애는데는 한계가 있다고 생각되었다. 해당 양보하고 UnitSystem에서 Animation System을 호출해 매핑하였다.
public class AnimatorMappingSystem{ private Dictionary<Entity,Animator>AnimatorMap=new Dictionary<Entity,Animator>(); public void RegisterUnit(GameUnit unit,Entity e){ if(!AnimatorMap.ContainKey(e))return; var animator=unit.GetComponent<Animator>(); //이상황에선 그냥 Animator만 만들면 Animation controller 문제가 된다 //해당 상황이 prefab으로 유닛을 Instantiate로 할 예정이지만 //해당 상황이 발생하게 되면 어떻게 조치할지 추후 수정할 예정이다. if(animator==null)animator = unit.AddComponent<Animator>(); AnimatorMap[e]=animator; } ... 후략 } public class UnitSystem : IEntityComponent{ private Dictionary<entity,GameUnit>UnitMap=new Dictionary<entity,GameUnit>(); private Queue<GameUnit>UnitPool=new Queue<GameUnit>(); public void OnEntityCreated(Entity entity){ if(!UnitMap.ContainKey(entity))return; var unit = GetUnit(); //아래 위치값을 EntitySystem에서 TranslateComponent(위치정보를 갖는 요소)를 //엔티티 만들때 넣을테니 그곳에 넣고 여기 부분에서 EntityManager에서 Query해서 //위치값을 가져올지, 아니면 IEntityComponent를 그냥 여러 시스템에 쓰이는게 아닌 //유닛시스템에만 쓰일 인터페이스로 해서 함수의 parameter에 float3(Vector3)를 추 //가 할지는 결정해야한다. unit.SpawnUnit(위치값); UnitMap[entity]=unit; } private GameUnit GetUnit(){ if(UnitPool.TryDequeue(out var unit)) return unit; return Instantiate(prefab); } ... 후략 } //애니메이터를 필수로 들어가게 해서 방지를 하자 //렌더링만 담당하기때문에 많은 메서드가 있지는 않을것. [RequireComponent(typeof(Animator))] public class GameUnit : MonoBehaviour{ public void SpawnUnit(Vector3 pos){ gameObject.SetActive(true); transform.SetActive(true); } public void ReleaseUnit(){ //혹여나 setActive가 false가 안되고 화면에 남아버리는 경우 방지 transform.Position=Vector3.one * 99999; gameObject.SetActive(false); } }
아직 수정할게 많은 코드들이다.
그리고 시스템적으로 계속 고민을 했는데 어제까지는 ECS에 Animation State Component 등과 같이 렌더링 상태에 대해 독립적으로 담당하게 만들 생각이였다. 왜냐하면 AI의 행동에 대해 이벤트 발생이 많게 되면 성능에 문제가 발생 되지 않을까 하는 생각에서였다.(물론 내가 지금 만드려는 오토체스류 게임에는 많은 수의 AI가 생성되지 않기에 상관은 없는 부분이긴 하다.)
하지만 코드를 계속 구상할수록 너무 직관적이지 못하게 흘러가고 연계하는 부분에 불편함이 크게 느껴졌다.
그래서 이벤트의 발생을 상태에 따라 이전과 같으면 발생을 시키지 않는다거나 하는 식의 방식으로 이벤트 부분을 가져가 애니메이션이라던가 사운드,파티클 등의 효과들과의 직관적이고 확장성 좋은 장점을 챙겨가기로 생각했다.
오늘은 위의 고민때문에 이렇게 저렇게 코드를 작성해보다가 진행이 그리 많이 되지 못해 아쉽다.