직렬화 가능한 클래스
Coddy Unity 여정의 Unity 게임 아키텍처 섹션에 포함된 레슨. 64개 중 18번째.
설정이 많은 스크립트는 Inspector에 길고 평평한 목록으로 표시됩니다. 일반 C# 클래스는 설정을 그룹화할 수 있습니다. 클래스에 [System.Serializable]을 표시하면 해당 클래스의 필드가 접기 메뉴로 나타나고, 접기 메뉴의 이름은 필드 이름을 따르며 그 안에 클래스의 필드가 표시됩니다. 하나의 클래스는 여러 필드와 여러 스크립트에서 사용할 수 있습니다.
[System.Serializable]
public class Stats
{
public float speed = 2f;
public int damage = 10;
}
public class Enemy : MonoBehaviour
{
public Stats normal;
public Stats enraged;
private Stats current;
void Start()
{
current = normal;
}
void Update()
{
transform.Translate(0f, 0f, current.speed * Time.deltaTime);
}
public void Enrage()
{
current = enraged;
}
}Inspector에는 접기 메뉴 두 개, Normal과 Enraged가 표시되고, 각각 Speed와 Damage가 들어 있습니다. 각 Enemy는 자체 Inspector에서 값을 입력하는 Stats 객체 두 개를 가지며, 코드에서는 normal.speed와 같이 읽습니다. Unity는 스크립트를 불러올 때 이 객체들을 생성하므로, = new Stats()가 없어도 normal은 항상 null이 아니며, 필드 초기화 값(2와 10)은 새 Enemy가 처음 갖는 값입니다. struct도 [System.Serializable] public struct Range { public float min; public float max; }와 같이 특성을 사용하면 같은 방식으로 작동하며, Vector3처럼 대입할 때 복사됩니다.
Unity는 저장하도록 지정된 형식만 저장하기 때문에 이 특성이 필요합니다. 이 특성이 없으면 클래스가 Inspector에 표시되지 않습니다. 접기 메뉴가 없고, 거기에 설정한 값은 저장되지 않으며, Unity가 객체를 생성하지 않으므로 normal.speed에서 NullReferenceException이 발생합니다. 클래스 내부에는 일반적인 Inspector 규칙이 적용됩니다. public 필드 또는 [SerializeField]가 지정된 private 필드만 사용할 수 있으며, 속성이나 static 필드는 사용할 수 없습니다.
챌린지
쉬움각 광선의 설정을 하나의 구조체로 묶으세요.
Flashlight위에public struct Beam을 선언하고,Color color,float range,float angle을 public으로 선언하세요. Inspector에 표시되도록[System.Serializable]을 지정하세요.- 여섯 개의 개별 필드를
public Beam wide;와public Beam focused;로 바꾸세요. Apply()에서focusedOn ? focused : wide의 값으로 조명의 세 가지 속성을 설정하세요.
‘플레이’를 누르고 Space 키를 누르세요. 광선이 수정에 닿습니다. 그런 다음 ‘확인’을 누르세요.
직접 해보기
using UnityEngine;
using UnityEngine.InputSystem;
public class Flashlight : MonoBehaviour
{
public Color wideColor = Color.white;
public float wideRange = 5f;
public float wideAngle = 60f;
public Color focusedColor = Color.white;
public float focusedRange = 10f;
public float focusedAngle = 30f;
private bool focusedOn;
private Light lamp;
void Start()
{
lamp = GetComponent<Light>();
Apply();
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
focusedOn = !focusedOn;
Apply();
}
}
void Apply()
{
lamp.color = focusedOn ? focusedColor : wideColor;
lamp.range = focusedOn ? focusedRange : wideRange;
lamp.spotAngle = focusedOn ? focusedAngle : wideAngle;
}
}
Unity 게임 아키텍처의 모든 레슨
직접 연습해 보세요: Unity 플레이그라운드