유니티/유니티 공부

#3 C# 프로그래밍 (메서드, 간단한 코딩예시, 클래스,인스턴스,접근제한자,참조타입)

DOlpa_GB 2025. 3. 17. 21:01

이번에 해볼것은 바로 유니티에서 쓰이는 C# 프로그래밍이다

하지만 지금 이 글을 쓰고 있는 시점과 비슷하게 이미 나는 C# 공부를 따로 하고 있고

 

 

CLR, 변수, 스택과 힙, 데이터 형식, 박싱&언박싱, 형식 변환

글을 시작하기 전에 별로 중요하지 않다 생각하고 넘긴 CLR에 대해서 알아보겠다 CLR(Common Language Runtime) : C#으로 만든 프로그램이 실행되는 환경C#뿐만 아니라  LS 규격을 따르는 모든 언어로 작

sangeun00.tistory.com

 

C# 공부용 글까지 적고 있기에 겹치는 부분들은 빼고 새로운 부분만 적어보도록 하겠다

 

 

 

<함수(메서드)>

이미 여러번 다뤘지만 프로그래밍에서 함수(메서드)는 미리 정해진 동작을 수행하는 코드 묶음 이다

따라서 어떤 처리를 미리 함수로 만들어두면 다시 반복해서 사용할 수 있다

 

만약 상자를 옮기는 행동을 게임안에서 한다고 쳐보자

 

<상자 옮기기>

 

1. 상자를 잡는다

2. 상자를 든다

3. hp가 3만큼 감소됨

4. 9m만큼 상자를 옮김

5. 상자를 내려놓음

 

만약 이걸 100번 한다고 치자. 게다가 매번 떨어지는 hp의 양과 상자를 옮기는 길이가 달라진다면..

1~5번까지의 행동을 각각 값이 다르게 무려 100번이나 반복해야 하는것이다

 

하지만 이것을 함수로 만든다면

 

Move(감소될 hp값 a, 이동할 거리 b)

{

1. 상자를 잡는다

2. 상자를 든다

3. hp가 a만큼 감소됨

4. b만큼 상자를 옮김

5. 상자를 내려놓음

}

 

이렇게 함수를 만들어놓고

 

Move(2,3);

Move(11,6);

Move(5.3,6.7);

 

이렇게 손쉽게 쓰는게 가능하다

 

Move(float a, float b) 처럼 매개변수가 있는 방식도 되지만 

 

GetRandomNumber()

{

    int num = 0;

    num = 임의의 숫자

 

    return num;

}

 

이런식으로 랜덤으로 숫자 하나를 return으로 반환하도록 할 수 있다

 

int randomnum = GetRandomNumber()

 

그럼 이렇게 GetRandomNumber()함수를 이용하여 새로 선언한 변수에 랜덤한 값을 담을 수 있다

 

 

----------------------

 

<Debug.log>

 

이미 다 아는 기능들은 건너뛰지만 하나만 짚고 넘어가겠다

 

Debug.Log("변수의 값 : " + number);

=> 변수의 값 : 10

 

이렇게 메세지와 변수 값을 한줄안에 넣어 로그를 출력하게 할 수 있다

 

Console.WriteLine($"변수의 값 : {num}");

Console.WriteLine("변수의 값 : {0}", num);

 

C#에서는 이렇게 표현할 수 있다. 

 

 

public class NewBehaviourScript : MonoBehaviour
{
    void Start()
    {
        float dis;
        dis = GetDistance(2f, 2f, 5f, 6f);
        Debug.Log(dis);
    }

    float GetDistance(float x1, float y1, float x2, float y2 )
    {
        float distancex = (x2 - x1) * (x2 - x1);
        float distancey = (y2 - y1) * (y2 - y1);
        float distance = distancex + distancey;
        distance = Mathf.Sqrt(distance);
        return distance;
    }
}

 

예시로 간단하게 짜본 코드. 각각 두 점의 x,y축 값을 받아와 피타고라스의 원리를 이용해

두 점 사이의 거리를 구하는 코드이다

 

--------------------------------------

 

<배열>

 

다른건 다 건너뛰고 그나마 조금 생소하게 느껴지는 배열만 짚고 넘어가자

 

배열 : 나열된 여러 값을 하나의 변수로 다룰 수 있는 타입

 

건물의 호실이라고 생각하면 편하다. 

101,102,103,104,105호.....

방문마다 호실이 표시되어있고, 호실마다 하나의 값이 존재한다. 그리고 호실을 안다면 그 안에 있는 값을 수정가능하다

 

여기서 호실번호를 인덱스(Index)라고 부른다. 주로 같은 타입의 변수가 많을때 사용한다

 

int[] student = new int[5];

 

student[0] = 100;

student[1] = 80;

student[2] = 70;

student[3] = 100;

student[4] = 50;

 

이런 식으로 선언하고 값을 할당해줄 수 있다

 

for(int i = 0; i<student.Length; i++)

{

     Debug.Log((i+1) + "번째 학생의 점수는" + student[i]);

}

 

그리고 이런식으로 for문을 이용해서 차례대로 출력할 수도 있다

 

 

 

-------------------------------

 

<클래스와 오브젝트>

 

 

#2 유니티 엔진 동작 원리 (클래스,메서드,상속,컴포넌트, 브로드캐스팅, MonoBehavior)

이번글에서는 유니티에서 엔진이 동작하는, 정확히는 게임 속 모든 오브젝트들이 움직이는원리에 대해서 알아보려고 한다 그전에, 이미 다른글에도 정리되어 있지만 가장 기본이며 가장 많이

sangeun00.tistory.com

 

이미 클래스에 대해서는 이곳에 설명되어 있으니 가볍게 짚고만 넘어가자

 

클래스와 오브젝트는 객체지향의 핵심이다.

객체지향은 '사람이 현실 세상을 보는 방식'에 가깝게 프로그램을 완성하는것'이다

 

클래스 : 표현하고 싶은 대상을 추상화하여 대상과 관련된 변수와 메서드를 정의하는 틀이다

(추상화 : 대상의 핵심적인 개념과 기능을 추려내는것)

 

오브젝트 : 물건의 설계도인 클래스와 달리 그 설계도로 만들어낸 실제 존재하는 물건(실체)이다

 

 

그림을 보면 더 이해가 쉬울 것이다 Human이라는 설계도(클래스)를 이용해

철수와 영희라는 사람(오브젝트)를 만들어내는 원리인 것이다. 

 

마치 전세계에게 몇십억의 인구가 있지만 모두 '인간'으로 분류되듯 아무리 많은 오브젝트들이라고

결국 하나의 클래스로 분류될 수 있다

 

이렇게 클래스라는 툴로 오브젝트를 찍어내 실체화하는 것을 인스턴스화 한다고 하며

인스턴스화를 이용해 생성된 오브젝트들을 인스턴스라고 한다

 

이제 한번 코드로 예시를 들어보도록 하겠다

 

public class Animal : MonoBehaviour
{
    public string name;
    public string sound;
    public void GoSound()
    {
        Debug.Log(name + " : " + sound);
    }
}

 

public class zoo : MonoBehaviour
{
    void Start()
    {
        Animal tom = new Animal();
        tom.name = "톰";
        tom.sound = "냐옹~";
        tom.GoSound();
    }

 

각각 Animal과 Zoo라는 이름으로 클래스를 만들어주었고 유니티에서 Zoo 스크립트를 실행한 결과이다

 

여기서 봐야하는것은 Zoo 클래스이다

 

        Animal tom = new Animal();

 

new 연산자는 클래스로부터 인스턴스를 생성한다.

즉 new Animal();은  '새로운 Animal 오브젝트(인스턴스)를 탄생시켜라'라고 명령을 한 것이다

 

 

 

<멤버와 접근 제한자>

 

그럼 이번엔 클래스를 이루는 요소를 좀 더 알아보도록 하자

 

public class Animal : MonoBehaviour
{
    public string name;
    public string sound;
    public void GoSound()
    {
        Debug.Log(name + " : " + sound);
    }
}

 

다시 한번 코드를 살펴보자

 

-클래스의 멤버

어떤 클래스에 속하며 해당 클래스의 데이터와 행위를 표현하는 요소를 멤버라고 한다

Animal 클래스에 속한 변수 name과 sound, GoSound() 메서드가 Animal의 멤버이다

 

-클래스의 필드

클래스의 멤버들 중 변수를 필드라고 한다. 즉 name, sound가 Animal 클래스의 필드이다

 

-접근제한자

클래스 멤버의 공개 여부를 정하는 키워드. 주로 다음 세가지가 쓰인다

 

public : 클래스 외부에서 멤버에 접근 가능

private : 클래스 내부에서만 접근가능

protected : 클래스 내부와 파생 클래스에서만 멤버에 접근 가능

 

만약 public name이 아니라 private name 이었다면 Zoo 클래스에서는 Animal 클래스의 name에 접근하지 못해

tom.name = "톰"; 이 정상적으로 실행될 수 없다

 

 

------------------------------------

 

<참조 타입>

 

public class zoo : MonoBehaviour
{
    void Start()
    {
        Animal tom = new Animal();
        tom.name = "톰";
        tom.sound = "냐옹~";

        Animal jerry = new Animal();
        jerry.name = "제리";
        jerry.sound = "찍찍";

        jerry = tom;
        jerry.name = "미키";

        tom.GoSound();
        jerry.GoSound();
        
    }
}

 

이 코드를 보자. 

 

        jerry = tom;
        jerry.name = "미키";

 

특이한 점이라면 이 두줄인데, 만약 jerry에 tom을 대입한다면 jerry에 관한 모든게 tom의 이름과 울음소리로 바뀔것이다

여기까지는 예상한대로 진행되지만 jerry.name을 미키로 바꿔버린다면...

 

톰 : 냐옹~

미키 : 냐옹~

 

이 나와야 할 것 같지만 정작 실행결과는 

이렇게 나와버리고 만다. 왜이렇게 바뀌는것일까?

 

그림으로 확인해보자 처음엔 이 상태였고

 

        jerry = tom;
        jerry.name = "미키";

 

이 코드가 추가되는 순간

 

 

위 그림처럼 jerry의 값이 tom과 똑같이 덮어씌워져 바뀌었을거라 생각하지만 실제는 아니다

 

아예 jerry에 할당된 참조값이 tom으로 변경되면서 아예 가르키던 화살표가 달라져버린다

결론적으로 변수는 tom과 jerry 두개 다 존재하지만 두 변수가 참조값을 통해 가리키는 Animal 오브젝트는 하나뿐

즉, jerry를 수정하는것은 tom을 수정하는것과 같은 의미이다

 

그렇다면 기존에 jerry가 참조하던 오브젝트는 그 누구의 참조도 받지 못하는데 어떻게 될까?

그대로 미아가 되버린다....나중에 가비지 컬렉터가 청소할때 지워버린다

 

이렇듯 변수에 실체가 아니라 실체로 향하는 참조가 할당되고,

변수에 접근하면 참조를 통해 실체에 접근하는 변수를 참조 타입 이라고 한다

 

 

Animal tom = new Animal();

물론 이렇게 참조타입인 변수들도 있지만 모든 변수들이 다 참조로 동작하는것은 아니다

 

int a = 20;

string name = "안녕하세요"

이렇게 값을 바로 참조 하는 값 타입도 있다

 

참조 타입 변수는 값(실체)으로 향하는 참조를 저장하고,

값 타입의 변수는 해당 변수 공간에 값 자체를 저장한다

 

int a = 0;

int b = 10;

a = b;

b = 100;

 

이런 코드를 보자 이런 경우는 값 타입의 변수이기 때문에

a=b를 선언해놓고 b = 100으로 바꾼다고 해서 a의 값까지 바뀌지않는다

 

반응형