Menu
CoddyTech

직렬화 가능한 클래스

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 필드는 사용할 수 없습니다.

challenge icon

챌린지

쉬움

각 광선의 설정을 하나의 구조체로 묶으세요.

  1. Flashlight 위에 public struct Beam을 선언하고, Color color, float range, float angle을 public으로 선언하세요. Inspector에 표시되도록 [System.Serializable]을 지정하세요.
  2. 여섯 개의 개별 필드를 public Beam wide;와 public Beam focused;로 바꾸세요.
  3. 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 플레이그라운드