일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- FSM
- c#
- skybox
- 유니티
- InputManager
- soundmanager
- 메서드
- 프로그래머스
- unity
- UI
- 코루틴
- 비선형자료구조
- 스택
- LINQ
- script
- 배열
- 직렬화
- 효과음
- 장애물달리기
- 람다식
- 유한상태머신
- Generic
- 인터페이스
- inputsystem
- 자료구조
- invokec#events
- 스파르타내일배움캠프
- ObjectPool
- delegate
- BGM
- Today
- Total
Unity 개발일지
[Unity] MonoBehaviour와 Unity 생명주기 실습하기 본문
[확인문제]
1. Time.timeScale을 0으로 하면 Update와 FixedUpdate는 모두 호출이 되지 않을까요? 그 이유는 무엇일까요?
Update와 FixedUpdate 모두 호출되지 않는다.
Time.timeScale은 게임의 시간 흐름을 제어하며, 0으로 설정하면 일반적인 프레임 업데이트가 멈춘다.
따라서, Time.timeScale을 0으로 사용하면 게임을 일시정지하거나 특정 이펙트를 구현하는 데 유용할 수 있으나 게임 오브젝트의 로직을 제어하는데 사용해서는 안된다. 로직 제어에는 Start, Awake, OnEnable, OnDisable과 같은 MonoBehaviour 생명주기 메서드를 사용해야한다.
2. Update의 호출주기에 영향을 주는 것은 무엇일까요?
프레임 레이트
Update는 매 프레임마다 호출되며, 프레임 레이트에 따라 호출 주기가 달라진다.
고프레임일수록 더 자주 호출된다. 예를 들면, 60fps로 게임을 실행하면 Update는 초당 60번 호출된다.
3. FixedUpdate의 호출주기에 영향을 주는 것은 무엇일까요?
Time.fixedDeltaTime
FixedUpdate는 고정된 시간 간격마다 호출되며, 이 간격은 Time.fixedDeltaTime으로 설정된다.
이는 물리 연산의 일관성을 유지하기 위해 고정된 주기로 호출된다.
4. Awake와 Start, OnEnable의 호출순서는 어떻게 될까요?
Awake : 오브젝트가 활성화될 때 처음으로 호출
OnEnable : 오브젝트가 활성화될 때 Awake 이후에 호출. 이미 활성화된 상태라면 Awake 전에 호출될 수 있다.
Start : 오브젝트가 활성화된 후, 첫 Update 호출 전에 한 번만 호출. Awake와 OnEnable이 모두 호출된 후에 호출
[설명문제]
1. Unity 생명주기 (Unity Life Cycle)에 대해서 설명해주세요.
게임 오브젝트가 생성되고, 활성화되고, 업데이트되고, 삭제되는 과정을 정의하는 일련의 단계이다.
2. MonoBehaviour 클래스의 주요 메서드와 그 기능에 대해 설명해주세요.
* MonoBehaviour 클래스에서 Start와 Awake의 차이점은 무엇이며, 이를 적절히 사용하는 방법에 대해 설명해주세요.
Awake : 스크립트 인스턴스가 로드될 때 호출, 초기화 작업 수행 가능
Start : 오브젝트가 활성화된 후 첫 번째 Update 전에 한 번 호출, 초기화 작업 수행 가능
OnEnable : 오브젝트가 활성화될 때 호출
OnDisabl e: 오브젝트가 비활성화될 때 호출
Update : 매 프레임마다 호출, 주로 게임 로직을 처리
FixedUpdate : 고정된 시간 간격마다 호출, 주로 물리 연산을 처리
LateUpdate : 모든 Update가 호출된 후 매 프레임마다 호출, 주로 카메라 움직임 등 후처리 작업을 수행
OnDestroy : 오브젝트가 파괴될 때 호출
Start와 Awake의 차이점
<Awake>
스크립트 인스턴스가 로드될 때 즉시 호출되며, 종속성 초기화를 포함한 초기화 작업에 적합
<Start>
오브젝트가 활성화된 후 첫 번째 Update 전에 호출되며, 다른 오브젝트와의 상호작용이 필요한 초기화 작업에 적합
3. Update, FixedUpdate, LateUpdate의 차이점에 대해 설명해주세요.
Update
매 프레임마다 호출되며, 주로 게임 로직을 처리. 프레임 레이트에 따라 호출 주기가 달라진다.
FixedUpdate
고정된 시간 간격마다 호출되며, 주로 물리 연산을 처리. Time.fixedDeltaTime에 따라 호출 주기가 고정
LateUpdate
모든 Update가 호출된 후 매 프레임마다 호출되며, 주로 카메라 움직임 등 후처리 작업을 수행
4. Time.deltaTime이란 무엇이며, 사용하는 이유에 대해 설명해주세요.
이전 프레임과 현재 프레임 사이의 시간 간격을 나타낸다. 이를 사용하여 프레임 레이트에 독립적인 움직임과 애니메이션을 구현할 수 있다. 예를 들어, 오브젝트의 이동을 Time.deltaTime을 곱하여 프레임 레이트에 상관없이 일정한 속도로 이동하도록 할 수 있다.
[실습문제]
💡 [JobQueue 만들기]
Awake 호출 순서에 상관 없이 작동하는 JobQueue를 만들어봅시다.
여러분은 현재 스테이지의 모든 적이 죽었을 경우 다음 스테이지로 넘어가는 기능을 만들고 싶습니다. 먼저 싱글톤 패턴의 StageManager를 선언하여 적들의 정보를 한 군데에 모으려 합니다.
그런데 문제가 있습니다! 씬에 StageManager와 Enemy 오브젝트가 있는데,
StageManager의 초기화 전에 Enemy 오브젝트의 Awake가 먼저 호출되어버려
NullReferenceException 오류가 발생합니다!
그래서 StageManager에 JobQueue를 추가하여 Enemy의 Awake가 먼저 불려도 그 작업을 Queue에 저장해놓고 StageManager 초기화 시 차례대로 불러오려고 합니다.
JobQueue를 이용한 StageManager의 코드를 완성해주세요.
StageManager 클래스
using System;
using System.Collections.Generic;
using UnityEngine;
public class StageManager : MonoBehaviour
{
public static StageManager Instance { get; private set; }
[SerializeField] private List<GameObject> enemies = new List<GameObject>();
private static Queue<Action> jobQueue = new Queue<Action>();
private void Awake()
{
Debug.Log("StageManager Awake");
if (Instance == null)
{
Instance = this;
ProcessJobQueue();
}
else
{
Destroy(gameObject);
}
}
public static void AddEnemy(GameObject enemy)
{
//TODO: Awake가 호출되기 전에 함수가 호출된 경우 Job Queue에 추가하는 코드를 작성하세요.
}
private void AddEnemyInternal(GameObject enemy)
{
enemies.Add(enemy);
}
public void RemoveEnemy(GameObject enemy)
{
enemies.Remove(enemy);
}
private void ProcessJobQueue()
{
// TODO: Job Queue를 처리하는 코드를 작성하세요.
// JobQueue가 빌 때까지 JobQueue에 있는 작업을 빼내서 실행
}
public bool IsStageClear()
{
return enemies.Count == 0;
}
}
Enemy 클래스
using UnityEngine;
public class Enemy : MonoBehaviour
{
private void Awake()
{
Debug.Log("Enemy Awake");
// 적을 StageManager에 등록
StageManager.AddEnemy(gameObject);
}
// 적이 죽었을 때 호출되는 메서드
public void OnEnemyDeath()
{
// 적이 죽었을 때 StageManager에서 적을 제거
StageManager.Instance.RemoveEnemy(gameObject);
}
}
public static void AddEnemy(GameObject enemy)
{
if (Instance == null)
{
// Instance가 아직 초기화되지 않은 경우 Job Queue에 추가
jobQueue.Enqueue(() => Instance.AddEnemyInternal(enemy));
}
else
{
Instance.AddEnemyInternal(enemy);
}
}
private void ProcessJobQueue()
{
// JobQueue가 빌 때까지 JobQueue에 있는 작업을 빼내서 실행
while (jobQueue.Count > 0)
{
var job = jobQueue.Dequeue();
job();
}
}
'Unity 개발' 카테고리의 다른 글
[Unity] 최적화 실습하기 (1) | 2024.07.17 |
---|---|
[Unity] 코루틴(Coroutine) 실습하기 (수정필요) (1) | 2024.07.16 |
[Unity] Delegate(대리자)와 Event, Action 그리고 Callback (0) | 2024.06.27 |
[Unity] 동적 생성을 해보자 (0) | 2024.06.26 |
[Unity] Invoke C# Events를 이용한 InputManager만들기 - 4 - (0) | 2024.06.25 |