Start() 는 게임오브젝트가 활성화 될때 Awake()이후에 한번 실행되는 함수이다.
Init은 클래스가 모노비헤이버를 상속받을 때 기본적으로 생성자를 사용하지 못하기 때문에 직접 생성자의 역할을 하는
메서드를 구현해준 것이다. (암묵적으로 이름은 Init이다)
그럼 초기화할때 Start()에 초기화할 코드를 넣어주면되지 왜 Init()이라는 함수를 따로 만들어 생성자처럼 활용할까?
Awake,Start등등은 기본적으로 게임오브젝트가 활성화 될때 실행된다
게임시작할때 비활성화되어있다가 SetActive()를 해주면 그때 비로소 실행된다는 말
그렇다면 프리팹을 인스턴스화할 때 활성화되었으니 Start()가 먼저 실행될까
아니면 인스턴스화하면서 같이 호출한 Init()이 먼저 실행될까?
Init() 의 구현부가 먼저 실행되고 그 다음 Start()가 실행된다.
이 실행순서를 고려해주지 않으면 실제로 오류가 나기 쉽다
public class MonsterFactory : MonoBehaviour
{
//singleton
public static MonsterFactory Instance { get; private set; }
[SerializeField] BasicMonster basicMonster;
[SerializeField] GameObject spawnPoint;
private void Awake()
{
Instance = this;
}
public void SpawnMonster(MonsterType monsterType)
{
BasicMonster bm = Instantiate(basicMonster, spawnPoint.transform).GetComponent<BasicMonster>();
switch (monsterType)
{
case MonsterType.Goblin:
bm.BasicMonsterInit(MonsterType.Goblin, 10, 1f);
break;
case MonsterType.Mushroom:
bm.BasicMonsterInit(MonsterType.Mushroom, 20, 2f);
break;
}
}
}
BasicMonsterInit()을 인스턴스화할때 같이 호출하였다.
public class BasicMonster : MonoBehaviour
{
public string ID { get; set; }
public int Hp { get; set; }
public float MoveSpeed { get; set; }
public Sprite mushroomImage;
private Image currentImage;
private void Start()
{
Debug.Log("Start()");
//currentImage = GetComponent<Image>();
}
//초기화함수
public void BasicMonsterInit(MonsterType monsterType, int hp, float moveSpeed)
{
Debug.Log("Init()");
Hp = hp;
MoveSpeed = moveSpeed;
currentImage = GetComponent<Image>();
//몬스터타입에따라 이미지변경
switch (monsterType)
{
case MonsterType.Goblin:
break;
case
MonsterType.Mushroom: //몬스터타입이 Mushroom이면
currentImage.sprite = mushroomImage; //현재이미지를 머쉬룸이미지로변경
break;
}
}
}
public enum MonsterType
{
Goblin = 0,
Mushroom = 1
}
호출된 BasicMonsterInit()에 있는 "Init()"로그가 Start() 로그보다 먼저 뜨는 것을 확인할 수 있다
실제로 오류가 난 사례 :
몬스터타입이 mushroom이면 이미지를 바뀌게 해주기 위해 currentImage에 현재 Image컴포넌트를 가져와 넣어주어야 하는데 - currenImage = GetComponent<Image>();
이 코드를 Start()함수에 집어넣으면 BasicMonsterInit() 에서 currentImage.sprite = mushroomImage; 코드를 실행하는 시점에 컴포넌트를 가져오지 못한 상태이기 때문에
같은 BasicMonsterInit() 함수에서 먼저 이미지컴포넌트를 가져와 currentImage에 넣어주어야 한다.