Destory #1

jinsuk·2023년 10월 3일
  • 나중에 게임규모가 커지거나 온라인 게임으로 만들어 진다고 가정했을때 서버와 통신할때 모든것을 ID로 통신하게 된다.
  • 플레이어와 몬스터 모두 ID를 하나씩 부여 받는다.
  • 플레이어가 101번이고 몬스터가 202번이라 했을 때 ID로 모두 보내주게 된다. 그 정보를 받은 서버는 모든 유저에게 뿌려 주게 된다.
  • 다른사람들이 볼 때도 자기만의 게임 화면에서 볼 수 있도록 101번과 202번을 찾아서 움직여 주게 된다.
  • 결국 ID를 이용해서 관리한다.

참조타입

  • c#에서 클래스는 참조타입인데 데이터 본체가 실제 변수에 있는 것이 아닌 변수에는 주소값만 들어가 있고 그 주소를 따라가면 실제 데이터가 저장되어 있는 개념
  • player객체를 만들어주면 힙영역에 player객체가 생성되고 p라는 변수에는 주소값이 들어가 있다.
  • Destory를 했을때 기존에 참조를 물고 있던 애들이 어떻게 동작을 하느냐?
    • 참조를 물고 있던 녀석 한명이 Destory를 할경우 나머지 애들은 null체크를 통해 실제로 파괴된 객체 인지 판별 할 수 있다.
    • 혹시라도 파괴된 녀석의 컴포넌트를 물고 있던 애들도 그 컴포넌트에 접근할려고 하는 순간 프로그램이 crash난다.
    • 모든 레퍼런스가 다 끊겼을때 그제서야 메모리에서 해제하는 것이 정석

몬스터와 플레이어를 관리하기 위한 매니저

  • GameManagerEx
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManagerEx
{
    GameObject _player;
    //Dictionary<int, GameObject> _players = new Dictionary<int, GameObject>();
    HashSet<GameObject> _monsters = new HashSet<GameObject>();

    public Action<int> OnSpawnEvent;

    public GameObject GetPlayer() { return _player; }

    public GameObject Spawn(Define.WorldObject type, string path, Transform parent = null)
    {
        GameObject go = Managers.Resource.Instantiate(path, parent);

        switch (type)
        {
            case Define.WorldObject.Monster:
                _monsters.Add(go);
                if (OnSpawnEvent != null)
                    OnSpawnEvent.Invoke(1);
                break;
            case Define.WorldObject.Player:
                _player = go;
                break;
        }

        return go;
    }

    public Define.WorldObject GetWorldObjectType(GameObject go)
    {
        BaseController bc = go.GetComponent<BaseController>();
        if (bc == null)
            return Define.WorldObject.Unknown;

        return bc.WorldObjectType;
    }

    public void Despawn(GameObject go)
    {
        Define.WorldObject type = GetWorldObjectType(go);

        switch (type)
        {
            case Define.WorldObject.Monster:
                {
                    if (_monsters.Contains(go))
                    {
                        _monsters.Remove(go);
                        if (OnSpawnEvent != null)
							OnSpawnEvent.Invoke(-1);
					}   
                }
                break;
            case Define.WorldObject.Player:
                {
					if (_player == go)
						_player = null;
				}
                break;
        }

        Managers.Resource.Destroy(go);
    }
}
  • 실험

  • pooling 을 할 경우 널체크만으로 부족

  • 개선 사항

초기화(initialization)란 프로그래밍에서 데이터 오브젝트나 변수의 초깃값 할당을 의미한다.

profile
공부기록용

0개의 댓글