말감로그

[유니티 C# 스크립팅 마스터하기] - 1장 유니티 C# 복습 본문

Unity

[유니티 C# 스크립팅 마스터하기] - 1장 유니티 C# 복습

habbn 2025. 1. 2. 17:32
728x90

유니티를 공부하고 활용하면서, 초급 기법이 아닌 고급 기법을 적용시키고 싶다는 생각에 책을 구매하게 되었다.

그리고 유튜브나 구글링을 하며 찾을 수 있지만 제대로된 책 한 권을 구매한 후 읽는 것도 나쁘지 않을 것같다는 생각이 든 것두 있다.

 

1장은 챕터명 그대로 C# 복습하기로 변수, 함수, 조건문, 클래스와 상속, 다형성 등에 대한 기본적인 내용을 다룬다.

그 중 내가 헷갈리거나 정확히 알지 못했던 다형성, C# 프로퍼티에 대해서 짚고 넘어갈 것이다.


다형성

다형성은 개체 지향 프로그래밍의 중요한 특징으로, 동일한 인터페이스나 기본 클래스를 공유하는 객체들이 서로 다른 동작을 할 수 있게 하는 능력을 말한다.

기본 클래스는 가상 메서드를 정의 및 구현할 수 있으며, 파생 클래스는 이러한 가상 메서드를 재정의할 수 있다. 

 

이 예제 코드는 MyCharacter에서 파생해 각각의 NPC 종류마다 고유한 인사말을 건네도록 한다.

* virtual : 파생 클래스에서 이 함수를 재정의할 수 있도록 허용하는 함수

using UnityEngine;

public class MyCharacter
{
    public string CharName = "";
    public int Health = 100;
    public int Strength = 100;
    public float Speed = 10.0f;
    public bool isAwake = true;

    public virtual void SayGreeting()
    {
        Debug.Log("Hello, my friend");
    }
}

public class ManCharacter : MyCharacter
{
    public override void SayGreeting()
    {
        Debug.Log("Hello, I'm a man");
    }
}

public class WomanCharacter : MyCharacter
{
    public override void SayGreeting()
    {
        Debug.Log("Hello, I'm a woman");
    }
}

public class OrcCharacter : MyCharacter
{
    public override void SayGreeting()
    {
        Debug.Log("Hello, I'm an Orc");
    }
}

 

Tavern 클래스를 별개의 스크립트 파일로 선언하여 술집에 있는 NPC들의 배열을 생성한 뒤 파생클래스의 SayGreeting 함수를 호출한다.

다형성을 이용하면 기본 클래스의 함수 호출로 파생 클래스의 함수 접근이 가능해진다.

 
using UnityEngine;

public class Tavern : MonoBehaviour
{
    public MyCharacter[] Characters = null;
   
    void Start()
    {
        Characters = new MyCharacter[5];

        Characters[0] = new ManCharacter();
        Characters[1] = new WomanCharacter();
        Characters[2] = new OrcCharacter();
        Characters[3] = new ManCharacter();
        Characters[4] = new WomanCharacter();

        EnterTavern();
    }

    public void EnterTavern()
    {
        foreach (var character in Characters)
        {
            character.SayGreeting();
        }
    }
}
 

 

 

C# 프로퍼티

프로퍼티는 C#에서 클래스 내부에 선언한 변수의 값을 외부에서 접근할 수 있도록 하면서, 동시에 캡슐화를 지원하는 언어의 한 원리이다.

프로퍼티를 사용하는 이유는 변수의 값을 변경하거나 가져올 때, 조건을 걸어서 변수의 접근을 제어할 수 있기 때문이다.

(캡슐화는 정보 은닉을 위해 클래스에서 선언된 변수가 외부에서 접근이 안되도록 private으로 선언하여 외부에서 접근을 불가능하게 만드는 것이다.)

 
using UnityEngine;

public class Database : MonoBehaviour
{
    private int iMyNumber = 0;
   
    // private 변수인 iMyNumber를 위해 만든 public 프로퍼티
    // iMyNumber 변수에 접근하는 접근자 public 프로퍼티
    public int MyNumber
    {
        // 값을 가져올 때 호출
        get
        {
            return iMyNumber;
        }
        // 값을 설정할 때 호출
        set
        {
            // 범위가 1 ~ 10 사이일 때 값을 변경하고, 아닌 경우는 무시
            if (value >= 1 && value <= 10)
            {
                iMyNumber = value;
                NumberChanged();
            }
        }
    }

    void Start()
    {
        MyNumber = 11;  // 값이 10보다 크므로 실패
        MyNumber = 7;   // 값이 1-10사이므로 성공
    }

    // iMyNumber가 변경될 때 불리는 이벤트
    void NumberChanged()
    {
        Debug.Log("Variable iMyNumber changed to : " + iMyNumber.ToString());
    }
}
 

 

SendMessage와 BroadcastMessage

유니티 API에 포함된 MonoBehaviour 클래스는 대부분의 새로 작성하는 클래스의 기본 클래스로서 SendMessage와 BroadcastMessage 메서드를 제공한다.

이 함수들을 사용해 오브젝트에 붙은 모든 컴포넌트의 함수를 이름으로 실행할 수 있다. 이 방법은 무척 편리하면서도 코드를 효율적으로 단순하고 짧게 만들어준다.

 
using UnityEngine;

public class MyClass : MonoBehaviour
{
    void Start()
    {
        // 이 오브젝트에 붙어있는 모든 컴포넌트/스크립트에서 MyFunction 함수를 부른다.
        SendMessage("MyFunction", SendMessageOptions.DontRequireReceiver);
    }

    void MyFunction()
    {
        Debug.Log("hello");
    }
}

 

리플랙션

SendMessage와 BroadcastMessage는 오브젝트 간 그리고 컴포넌트 간 통신을 수월하게 만드는 효과적인 방법이다.

하지만, 내부적으로 c#의 리플랙션(reflection)이라는 기능에 의존하기 때문에 애플리케이션 실행 중에 스스로를 살펴보고 실행할 코드를 찾는다.

그렇기 때문에 일반적인 방법으로 함수를 실행할 때보다 무거운 연산을 필요로 하기 때문에 성능 저하를 일으킬 수 있다.

728x90