Unity 개인 공부

Unity 개인 공부(2025-01-21)

kimjunki-8 2025. 1. 21. 23:05

자, 저희 C#의 인스턴스의 개념이 뭔지 알아봅시다. 참고로 이 부분을 자세히 들여다봐야 어제 했던 내용이 이해가 갑니다.

먼저, 클래스와 인스턴스를 알아야합니다.

C#에서의 클래스는 Python과 다르게 다가옵니다. 근데 이전에 저희가 클래스를 만드는 법에 대해 배웠기 때문에.....하지만 거기에 숨겨진 의미가 있습니다.
기본 구조
public class Dog
{
    public string name;

    public Dog(string name)
    {
        this.name = name;
    }
}

// 인스턴스 만들기
Dog dog1 = new Dog("Buddy");  // "Buddy"라는 이름을 가진 Dog 클래스의 인스턴스를 만들었어요.​

C#에서의 인스턴스는 클래스를 바탕으로 실제 객체를 만들어 사용하는 것입니다.
Dog 클래스는 설계도이고, dog1은 그 설계도를 바탕으로 만든 실제 객체입니다.


여기까지는 배운 구조입니다. 하지만 이제 조금씩 느낌이 달라집니다.
이제 클래스타입에 대해서 이해해야 합니다. C#에서는 클래스가 곧 타입입니다. Python에서도 비슷하게, 클래스가 정의되면 그 클래스는 타입이 되고, 그 타입을 바탕으로 객체를 만들죠.
Dog dog1 = new Dog("Buddy");  // dog1은 Dog 타입의 객체

자, 여기서 중요!
Dog dog1 = new Dog("Buddy");에서 Dog가 왜 앞에 붙는지에 대해 더 파고들어 보겠습니다. 

타입 지정: Dog dog1
Dog는 클래스입니다.
dog1은 그 클래스를 바탕으로 만들어진 인스턴스입니다.
이렇게 생각해 볼 수 있어요:
Dog는 타입(type)을 의미합니다. 즉, dog1이 어떤 데이터 형태를 가질지 정의해요. dog1이 Dog 타입이기 때문에 dog1에는 Dog 클래스에서 정의한 내용만 들어갈 수 있어요.
타입을 지정하는 이유는 컴퓨터가 변수에 어떤 종류의 데이터를 넣을 수 있는지 알게 하기 위해서예요. 즉, dog1은 Dog 타입의 객체여야 하고, 그 안에는 Dog 클래스에서 정의된 속성과 메소드만 있을 수 있어요.

그런데 여기서 타입을 정의하는 것이 무엇을 의미하는 것일까요

C#에서 타입을 정의한다는 것은 변수나 객체가 어떤 종류의 값을 가질 수 있는지 제한하는 것입니다. 예를 들어:
int a = 5;  // a는 int 타입
string s = "Hello";  // s는 string 타입

여기서 a는 int 타입으로 정의되었으므로, a에는 정수만 들어갈 수 있습니다. a에 문자열이나 다른 타입의 값을 넣으려 하면 컴파일 에러가 발생합니다. 이때 int는 타입이므로, a는 정수만 받을 수 있습니다. 이와 비슷하게, string은 문자열만 받을 수 있습니다.



Dog라는 사용자 정의 타입의 의미
이제 Dog라는 클래스를 정의하면, 그것은 사용자가 만든 타입입니다. Dog는 단순한 데이터가 아니라, Dog라는 구조체로, 내부에 속성이나 메소드를 가질 수 있습니다. 예를 들어:
class Dog {
    public string Name;
    public int Age;

    public void Bark() {
        Console.WriteLine("Woof!");
    }
}​

이제 Dog는 타입이자 클래스입니다. 이 Dog 타입을 사용하면, dog1과 같은 객체는 Dog에서 정의한 속성(예: Name, Age)과 메소드(예: Bark())만 사용할 수 있게 됩니다.

Dog dog1 = new Dog();
dog1.Name = "Buddy";
dog1.Age = 3;
dog1.Bark();  // "Woof!" 출력​


타입을 정의할 때 dog1에 미치는 영향
Dog라는 클래스를 정의하고 dog1을 생성하면, dog1은 Dog 타입이므로 Dog에서 정의한 속성과 메소드만 사용할 수 있습니다. 이는 dog1이 Dog 타입이라는 제약을 가지게 된다는 뜻입니다. 즉, dog1에는 Dog 클래스에서 정의한 속성이나 메소드만 포함될 수 있고, 그 외의 다른 타입이나 클래스의 속성을 가질 수 없습니다.

타입에 따른 제약

Dog dog1 = new Dog();
dog1.Name = "Buddy";  // 유효
dog1.Age = 3;         // 유효
dog1.Bark();          // 유효

dog1 = 5;  // 에러: Dog 타입은 int를 받을 수 없음

dog1 = 5;와 같이 dog1에 정수를 할당하려고 하면 에러가 발생합니다. 왜냐하면 dog1은 Dog 타입으로 정의되었기 때문입니다.
dog1은 Dog 클래스에서 정의된 속성인 Name, Age, Bark()만 사용할 수 있으며, 그 외의 int나 다른 타입의 값은 받을 수 없습니다

다른 타입과 비교
int a = 5;  // a는 int 타입
a = "Hello";  // 에러: a는 string을 받을 수 없음​

타입을 지정하지 않으면 어떤 일이 발생하는가?
타입을 지정하지 않으면
변수나 객체가 어떤 데이터를 다룰지 알 수 없게 되어
컴파일러가 이를 이해할 수 없습니다. 예를 들어, C#에서 타입을 지정하지 않으면 코드가 제대로 동작하지 않게 됩니다.
dog1 = new Dog();  // 에러: dog1의 타입이 명시되지 않으면 어떤 객체를 가질지 알 수 없음​

그럼 다시 시작해볼까요?
새로운 Input System의 개념
Unity의 새로운 Input System은 입력을 처리하는 방식을 대폭 개선했습니다. 주요 개념은 다음과 같습니다:

Input Action:
입력(예: "Move", "Jump")을 추상적으로 정의합니다.
특정 키(W, A, S, D)나 입력 장치(조이스틱, 마우스)를 바인딩(연결)합니다.

Input Action Asset:
여러 Input Action을 모아놓은 파일. (예: "Move", "Jump", "Shoot" 액션 포함)

이벤트 기반 처리:
키를 누를 때마다 특정 이벤트를 발생시켜 입력을 처리합니다.
왜 Input System을 써야 할까?
장치 간 일관성: 키보드, 게임패드, 터치스크린 등 모든 입력 장치를 동일하게 처리 가능.
유연성: 복잡한 조합(예: WASD + 마우스 클릭)을 쉽게 처리.
확장성: 네트워크 플레이어나 AI가 같은 입력 시스템을 사용할 수 있도록 설계.

Input Action Asset 생성
1. Project 창에서 우클릭 > Create > Input Actions를 선택하여 새로운 Input Action Asset을 생성합니다.
파일 이름: InputControl.
2. Asset을 더블 클릭하여 Input Action Editor를 엽니다.
3. 새 액션을 추가:
이름: Move.
타입: Value.
제어 유형(Control Type): Vector2.
4. Move 액션에 키를 바인딩:
Binding Path에서 Keyboard를 선택하고 W, A, S, D를 각각 추가합니다.
using UnityEngine;
using UnityEngine.InputSystem; // Input System 관련 클래스 가져오기

public class PlayerInput : MonoBehaviour
{
    private InputAction moveAction; // "Move" 액션을 저장할 변수

    void Start()
    {
        // Input Action Asset 로드
        var asset = Resources.Load<InputActionAsset>("InputControl");

        // "Move" 액션 찾기
        moveAction = asset.FindAction("Move", true);

        // Move 액션 활성화
        moveAction.Enable();
    }

    void Update()
    {
        // "W", "A", "S", "D" 입력 상태 확인
        Vector2 input = moveAction.ReadValue<Vector2>();

        if (input.y > 0) // "W" 키가 눌린 상태
        {
            Debug.Log("W 키가 눌렸습니다!");
        }
        else if (input.x < 0) // "A" 키가 눌린 상태
        {
            Debug.Log("A 키가 눌렸습니다!");
        }
    }
}

밑 코드들을 보겠습니다.
1. ReadValue란?
ReadValue는 Unity의 Input System에서 사용자의 입력 값을 가져오는 함수입니다.
쉽게 말해, 현재 입력된 값을 읽는 역할을 합니다.
왜 ReadValue를 써야 할까?
Input System은 키보드, 조이스틱, 마우스 등 다양한 입력 장치를 지원합니다.
이 함수는 현재 연결된 입력 장치에서 데이터를 읽어옵니다.
데이터의 타입(예: Vector2, float, bool)에 따라 다르게 동작합니다.
예를 들어:
Vector2: 방향 데이터를 반환 (예: 이동).
float: 크기 데이터를 반환 (예: 스로틀).
bool: 참/거짓 데이터를 반환 (예: 버튼 누름).

어떻게 동작할까?
moveAction.ReadValue<Vector2>()는 Move 액션의 입력 값을 2D 벡터(Vector2)로 반환합니다.
반환된 값은 입력 장치에서 입력된 방향(예: WASD 키의 조합)을 나타냅니다.

2. Vector2란?
Vector2는 Unity에서 2D 공간의 방향 또는 위치를 표현할 때 사용되는 구조체입니다.
Vector2는 x와 y라는 두 축으로 구성되어 있습니다.
Vector2의 특징
x와 y 값:
x 축: 왼쪽(음수)과 오른쪽(양수) 방향.
y 축: 아래(음수)와 위(양수) 방향.
예: (1, 0)은 오른쪽 방향, (0, 1)은 위쪽 방향을 나타냅니다.

Vector2 direction = new Vector2(1, 1); // x: 1, y: 1
Debug.Log(direction); // 출력: (1.0, 1.0)

 

게임에서의 활용:
2D 이동: 캐릭터가 위/아래/왼쪽/오른쪽으로 움직일 때 사용.
조이스틱 입력: 방향 조작을 벡터로 처리.

왜 W는 y 축이고, A는 x 축인가?
WASD 키와 Vector2의 관계
Input System에서 W, A, S, D 키를 Vector2로 매핑하면 다음과 같이 동작합니다:

왜 이렇게 정의되었나요?
x와 y는 2D 공간에서의 좌표 체계:
x는 왼쪽-오른쪽의 수평 축.
y는 아래-위의 수직 축.
키보드 방향에 맞춘 표준 매핑:
W는 위쪽을 나타내므로 y = +1.
A는 왼쪽을 나타내므로 x = -1.
S는 아래쪽을 나타내므로 y = -1.
D는 오른쪽을 나타내므로 x = +1.

코드로 확인해 보기
아래 코드는 Vector2의 값을 출력하여 W, A, S, D 키의 동작을 확인합니다:

using UnityEngine;
using UnityEngine.InputSystem;

public class InputTest : MonoBehaviour
{
    private InputAction moveAction;

    void Start()
    {
        var asset = Resources.Load<InputActionAsset>("InputControl");
        moveAction = asset.FindAction("Move", true);
        moveAction.Enable(); // Move 액션 활성화
    }

    void Update()
    {
        Vector2 input = moveAction.ReadValue<Vector2>();
        Debug.Log($"x: {input.x}, y: {input.y}");
    }
}

 

PlayerInput과 InputAction을 사용하여 입력을 처리하는 방식
using UnityEngine;
using UnityEngine.InputSystem;

public class InputExample : MonoBehaviour
{
    private PlayerInput playerInput; // Input Action Asset과 연결된 Player Input 인스턴스
    private InputAction moveAction;

    private void Awake()
    {
        playerInput = new PlayerInput(); // Input Actions Asset 초기화
        moveAction = playerInput.Player.Move; // "Move" 액션 접근
        moveAction.Enable(); // 액션 활성화
    }

    private void Update()
    {
        // 특정 버튼을 누르고 있는지 확인
        if (moveAction.ReadValue<Vector2>().y > 0)
        {
            Debug.Log("Up 키가 눌렸습니다!");
        }
    }
}
이해 드릅게 안 가네;;

 

'Unity 개인 공부' 카테고리의 다른 글

Unity 개인 공부(2025-01-23)  (0) 2025.01.23
Unity 개인 공부(2025-01-22)  (2) 2025.01.22
Unity 개인 공부(2025-01-20)  (0) 2025.01.20
Unity 개인 공부(2025-01-19)  (0) 2025.01.19
Unity 개인 공부(2025-01-18)  (0) 2025.01.18