경일게임아카데미 멀티 디바이스 메타버스 플랫폼 개발자 양성과정 20220708 2022/04/04~2022/12/13

Jinho Lee·2022년 7월 12일
0

경일 메타버스 20220708 14주차 5일 수업내용. Unity를 위한 C# 프로그래밍

Unity를 위한 C프로그래밍

배열

  1. int[] 등, 타입 뒤에 []을 붙이는 것으로 선언한다.

  2. 초기화new 타입[]으로 할 수 있고, C++에서처럼 초기화할 수도 있다.

  3. 원소 접근은 C++과 같다.
    arr[1];

    • 이런 접근자를 C#에서는 인덱서(Indexer)라고 한다.
  4. 다차원 배열은 바라는 차원 수 만큼 ,을 괄호 안에 넣어 선언한다.
    ex) int[,] - 2차원 배열 int [,,,] - 4차원 배열

  5. 다차원 배열의 접근[ i, j ] 형식으로 한다.

  6. 가변 배열(Jagged Array)이란 배열의 배열이다.
    타입[][] 의 형식으로 선언한다.

  • 가변 배열은 각 원소가 배열의 주소인 배열이며,
    이는 원소인 배열이 비연속적으로 할당되어 있다는 것이다.

  • 매뉴얼에 따르면, 가변 배열다차원 배열보다 빠르다.

  • 배열에 대한 조작, 기능 등의 지원은 Array 클래스로 이루어진다.
    ex) Array.sort(arr);

// 1차원 배열
int[] arr = new int[5]; // int arr[5]; 와 같다.

// 초기화
arr = new int[5] { 1, 2, 3, 4, 5 };
arr = { 1, 2, 3, 4, 5 };

// 원소 접근
arr[1]; // C++과 같다.
// 인덱서(Indexer)라고 한다. 

// 다차원 배열
int[,] arr2 = new int[5, 5]; // int arr[5][5];와 같다.

// 초기화
arr2 = new int[5, 5] { { 1, 2, 3 }, { 4, 5, 6 }};
arr2 = { { 1, 2, 3 }, { 4, 5, 6 } };

// 원소 접근
arr[1, 2]; // 문법에 주의한다. 값은 6이다.

// 가변 배열(Jagged Array) : 배열의 배열
int[][] arr3 = new int[3][];
arr3[0] = new int[2] { 1, 2 };
arr3[1] = new int[4] { 1, 2, 3, 4 };
arr3[2] = new int[3] { 1, 2, 3 };

// C++의 경우, 가변 배열은
int** arr = new int*[3];
arr[0] = new int[2] {1, 2};
arr[1] = new int[4] { 1, 2, 3, 4 };
arr[2] = new int[3] { 1, 2, 3 };

// 원소 접근
arr[1][2]; // 3

간접 참조

  • C#에서는 포인터는 거의 없다시피 한다.

매개 변수 한정자(Parameter Specifier)

  • in

    • 참조로 전달되나, 변경이 되지 않는 인자를 의미한다.

    • 입력을 목적으로 한다.

    • const int& 와 같다

    • in 한정자도 인자가 반드시 초기화 되어야 한다.
      초기화를 하지 않으면 컴파일 오류가 난다.

    • 호출할 때는 적어주지 않아도 된다.

    • 예시 코드

      // C++
      void Foo(const int& a, const int& b)
      {
          // Do Something...
      }
      
      // C#
      // in 한정자도 인자가 반드시 초기화 되어야 한다.
      // 초기화를 하지 않으면 컴파일 오류가 난다.
      void Foo(in int a, in int b)
      {
          // Do Something...
      }
  • out

    • 참조로 전달되는 인자이며, 매개변수를 이용한 출력을 의미한다.

    • 출력을 목적으로 한다.

    • int& result 와 같다.

    • out 한정자는 함수가 끝나기 전 반드시 어떤 값이 할당되어야 한다.

    • 호출할 때 꼭 out 키워드를 적어야 한다.

    • 예시 코드

      // C++
      void Foo(int a, int b, int& result)
      {
          result = a + b;
      }
      
      // C#
      // out 한정자는 함수가 끝나기 전 반드시 어떤 값이 할당되어야 한다.
      void Foo(int a, int b, out int result)
      {
          result = a + b;
      }
      
      int r;
      Foo(10, 20, out r); // 호출할 땐 꼭 out 키워드를 적는다.

클래스

  • C++과 동일하게 필드와 메소드를 작성할 수 있으나,
    문법이 다르다.

    1. 접근 한정자를 매번 적어야 한다.

    2. 접근 한정자의 종류 또한 다르다.
      종류 : https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/accessibility-levels

    3. 주로 쓰는 접근 한정자

      • public

      • protected

      • private

    4. 세미콜론을 안 붙여도 된다.

    5. C++과 C#에서의 클래스 차이 예시 코드

      // C++
      class Temp
      {
      public:
          Temp()
          {
              std::cout << "기본 생성자"
          }
      
          Temp(int a, int b)
              : a(a), b(b)
          {
      
          }
      
          Temp(const Temp& other)
              : a(other.a), b(other.b)
          {
      
          }
      
          void Print()
          {
              std::cout << a << ", " << b << "\n";
          }
      private:
          int a = 0;
          int b = 0;
      };
      
      Temp temp = Temp(1, 2); // C++에서의 객체 생성
      
      // C#
      public class Temp
      {
          private int a = 0;
          private int b = 0;
      
          public Temp() => Debug.Log("기본 생성자");
      
          // 초기자 리스트가 없다.
          public Temp(int a, int b)
          {
              // C#에는 포인터라는 게 없어서 -> 연산자는 없다.
              this.a = a;
              this.b = b;
          }
      
          // 복사 생성자는 매우 드물게 작성한다.
          public Temp(Temp temp)
          {
              a = temp.a;
              b = temp.b;
      
              // 얕은 복사인 경우 아래와 같은 메서드를 이용할 수 있다.
              // this = temp.MemberwiseClone();
          }
      
          public void Print() => Debug.Log($"{a}, {b}");
      }
      
      Temp temp = new Temp(1, 2); // C#에서의 객체 생성

속성(Property)

// C++
class Person
{
public:
    std::string GetFirstName() const { return _firstName;}
    std::string GetSecondName() const { return _secondName; }
    std::string GetFullName() const { return _firstName + _secondName; }

    void SetFirstName(const std::string& firstName) { _firstName = firstName; }
    void SetSecondName(const std::string& secondName) { _secondName = secondName; }
private:
    std::string _firstName;
    std::string _secondName;
}

// C#
class Person
{
    public string FirstName { get; set; }
		// 위의 한 줄로 아래의 필드, Getter, Setter 메서드가 생성된 것
		// private string _firstName;
		// public string GetFirstName() { return _firstName; }
		// public string SetFirstName() { _firstName = name; }

    public string SecondName { get; set; }
    public string FullName
    {
        get { return $"{FirstName} + {SecondName}"; }
    }
}

상속

  • C#에서는 C++과 달리,
  1. 접근 한정자를 안 써도 된다.

  2. 다중 상속이 금지되어 있다.

  • 예시 코드
// C++
class Base { };

// public을 항상 써줘야 함
class Derived : public Base { };

// C#
class Base { }

// 안써도 됨
class Derived : Base { }

class Base1 { }
class Base2 { }
class Derived : Base1, Base2 { } // 컴파일 오류!

using

  • C++의 using namespace; 와 같은 기능을 한다.

MonoBehaviour

  • MonoBehaviour를 상속 받는 클래스는 유니티에서 관리한다.

타입

  • 값 타입

    • C# 내장 타입, 구조체 등

      • int, float, string, struct 등
    • 스택에 저장된다.
      스택에 인스턴스를 생성한다.

  • 참조 타입

    • 클래스, 레퍼런스 모든 컴포넌트, C# 스크립트 등

      • class, ref, in, out, component, MonoBehaviour를 상속 받는 클래스 등
    • 힙에 저장된다.
      힙에 생성된 인스턴스의 주소값을 저장한다.

  • 유니티의 스크립트 실행 순서

    • 스크립트는 복수 있다면 로딩되는 순서대로 임의로 실행된다.

    • 순서를 정하려면
      Edit → Project Setting → Script Execution Order
      에서 Apply하여 순서를 정할 수 있다.

0개의 댓글