ObjectManager

Eunho Bae·2022년 5월 21일

맵 Creature 관리

public class ObjectManager
{
    //Dictionary<int, GameObject> _objects = new Dictionary<int, GameObject> ();

    List<GameObject> _objects = new List<GameObject>();
    public void Add(GameObject go)
    {
        _objects.Add(go);
    }
    public void Remove(GameObject go)
    {
        _objects.Remove(go);
    }
    public GameObject Find(Vector3Int cellPos)
    {
        foreach(GameObject go in _objects)
        {
            CreatureController cc = go.GetComponent<CreatureController>();
            if (cc == null)
                continue;

            if (cc.CellPos == cellPos)
                return go;
        }

        return null;
    }
    public void Clear()
    {
        _objects.Clear();
    }
}

맵 상에 존재하는 크리쳐(몬스터, 플레이어 등)들도 플레이어가 갈 수 있는 곳에 존재하는지 체크하기 위해 ObjectManager클래스를 만들고 그 안에 List 자료구조를 사용해 넣어주었다.

이렇게 하면 CreatureController의 UpdateMoving() 함수에서 갈 수 있는지 여부를 판단하기 위해 코드를 추가로 넣어줄 수 있다.

void UpdateMoving()
    {
        if (State == CreatureState.Idle && _dir != MoveDir.None) // 유닛 한칸 이동 끝날때까지 입력 못받게
        {
            Vector3Int destPos = CellPos;
            switch (Dir)
            {
                case MoveDir.Up:
                    destPos += Vector3Int.up;
                    break;
                case MoveDir.Down:
                    destPos += Vector3Int.down;
                    break;
                case MoveDir.Left: 
                    destPos += Vector3Int.left;
                    break;
                case MoveDir.Right:
                    destPos += Vector3Int.right;
                    break;
            }

            State = CreatureState.Moving;

            if (Managers.Map.CanGo(destPos))
            {
                if (Managers.Obj.Find(destPos) == null)
                {
                    CellPos = destPos;
                }
            }
        }
    }

그리고 Player와 Monster 게임 오브젝트를 프리팹화 시킨 후 게임씬을 로드할 때 불러와서 넣어주면 끝~

protected override void Init()
    {
        base.Init();

        SceneType = Define.Scene.Game;

        Managers.Map.LoadMap(1);

        GameObject player = Managers.Resource.Instantiate("Creature/Player");
        player.name = "Player";
        Managers.Obj.Add(player);

        for(int i=0; i<5;i++)
        {
            GameObject monster = Managers.Resource.Instantiate("Creature/Monster");
            monster.name = $"Monster_{i + 1}";

            Vector3Int pos = new Vector3Int()
            {
                x = Random.Range(-20, 20),
                y = Random.Range(-10, 10),
            };

            MonsterController mc = monster.GetComponent<MonsterController>();
            mc.CellPos = pos;

            Managers.Obj.Add(monster);
        }
    }

추가 정보

  • 서버쪽에서는 모든 객체를 id로 관리를 하게된다. 따라서 플레이어든 몬스터든 id를 부여받게 되는데 그렇다면 플레이어가 id를 1번을 받았고 몬스터 A가 id를 2번 받았을 때 플레이어가 A를 공격하면 1번이 2번을 공격하였다라고 서버 측에서 인식하게 된다.
  • 오브젝트가 별로 없다면 List에 넣어서 순회하면서 체크하는 방법을 쓰고, 오브젝트가 많다면 GameObject 타입의 2차원 배열을 만들어 주는 것도 좋다.
profile
개인 공부 정리

0개의 댓글