본문 바로가기
XR개발/C#언어_Unity

Unity C# 기본정리2

by 오머리쿠_OmaryKoo 2025. 4. 17.

 

오브젝트에다 tag를 다는 이유는 식별하고, 선별적으로 조작하기 위함이다.

 

씐(Scene)안에는 수백개 오브젝트가 있을 경우, 특정 종류(플레이어, 적, 아이템)만 따로 처리하고플 때, Tag 통해 그걸 빠르게 구별가능하다.


 

Collision Detection이란 물리적인 충돌을 얼마나 정확하게 처리할지 설정하는 옵션을 말한다.

RigidBody를 가진 오브젝트가 빠르게 움직일 때, 벽이나 바닥을 뚫고 지나가는 현상이 생기는 걸 방지하기 위한 장치라고 보면된다.

 

Rigidbody Constraints(제약) 옵션을 통해 어떤 축의 위치나 회전이 변경되지 않게 고정할 수 있다.


여기서 물리적인 힘을 가하는 방식을 사용하기 위해, 리지드바디 컴포넌트를 할당할 변수와 이동 속력을 지정할 변수를 위와같이 선언한다.

 

Rigidbody는 타입(자료형)이며, playerRigidbody는 변수 이름(식별자)이다.

Rigidbody는 유니티에서 제공하는 컴포넌트 타입이며, 물리 엔진과 관련 기능을 제공해 (질량, 중력, 힘같은 걸 다룸)

playerRigidbody는 내가 직접 붙인 변수 이름이며, 이 변수 안에 특정 Rigidbody 컴포넌트가 지정이 되는 것이다.

 

쉽게 비유하면, Rigidbody는 "컵"의 종류이며,

playerRigidbody는 "내 책상 위에 있는 하얀 컵"처럼 "구체적인 것"을 가리키는 이름이다.

 

Rigidbodyt는 데이터의 종류를 나타내는 타입이며, playerRigidbody는 실제로 사용할 이름을 붙인 저장소를 말한다.

 

 

Q1. 왜 이름을 변경해서 playerRigidbody 같은 걸 만들었을까?

Rigidbody 자체는 자료형(Type).
즉, "이 변수는 Rigidbody 타입의 데이터를 담을 거야"라는 의미를 알려주는 것이다..

그런데! 현실 세계에서는 Rigidbody가 하나만 있는 게 아니다.

  • 플레이어(Player) Rigidbody
  • 적(Enemy) Rigidbody
  • 박스(Box) Rigidbody
    등등, 여러 개가 생길 수 있기 때문에, "이 Rigidbody는 누구를 위한 거다" 라고 구체적인 이름을 붙여야 하는 것이다.

즉, playerRigidbody 라는 이름은 "플레이어 오브젝트의 Rigidbody 컴포넌트를 담는 변수" 라는 의미를 명확하게 전달하기 위해 붙인 것이다.

 

 

Q2. 타입(Type)은 왜 대문자로 시작하고, 변수(이름)는 소문자로 시작할까?

이건 C# 언어 스타일 가이드에 따른 규칙이며, C#에서는 명명 규칙(Naming Convention) 이 엄격하게 잡혀 있다.


클래스/타입 이름 PascalCase (단어 첫 글자마다 대문자) Rigidbody, GameObject, PlayerController
변수 이름 camelCase (첫 글자 소문자, 이후 단어는 대문자) playerRigidbody, moveSpeed, jumpForce
메서드 이름 PascalCase Start(), Update(), MovePlayer()

정리하자면:

  • 타입/클래스/메서드 → 대문자로 시작 (PascalCase)
  • 변수/필드/지역변수 → 소문자로 시작 (camelCase)

이 규칙을 지키는 이유는?


→ 코드를 읽을 때, "이게 타입인지, 변수인지, 메서드인지"를 한눈에 알 수 있도록 하기 위해서이다.


 

"Rigidbody 타입의 변수 playerRigidbody를 선언했다고 해서 Rigidbody 타입의 오브젝트가 생성되는 건 아니다."


변수를 만든다는 건 "빈 상자"를 준비하는 것일 뿐,
그 안에 진짜 물건(오브젝트)을 만들어 넣은 건 아니라는 것이다.

 

  • Rigidbody 타입의 변수 선언 = "컵을 하나 책상 위에 올려놓는다."
  • Rigidbody 오브젝트 생성 = "컵 안에 진짜 물을 따른다."

지금 playerRigidbody를 선언하면,
"이 상자는 Rigidbody 타입의 무언가를 담을 수 있다"고 약속한 것.
하지만 "상자 안이 비어 있는지, 채워져 있는지"는 아직 모르는 상태.


 

  • playerRigidbody라는 Rigidbody를 담을 수 있는 변수(상자) 를 만들었다.
  • 하지만 아직 그 안에 무엇을 담지는 않았다.
  • 그래서 현재 playerRigidbody는 null 이다.
    • (null = 아무것도 안 담긴 상태)

Q3. 그럼 실제로 "가리킨다"는 건?

예를 들어, 유니티 에디터에서 playerRigidbody에
씬 안에 존재하는 진짜 Rigidbody 컴포넌트를 드래그해서 연결했다고 해보자.

이러면 무슨 일이 벌어지냐?

  • playerRigidbody 변수 안에 "씬에 존재하는 Rigidbody 오브젝트"를 가리키는 주소(참조) 가 들어간다.
  • 즉, playerRigidbody는 진짜 Rigidbody 오브젝트를 가리키는 포인터(참조) 가 되는 거야.

요약 그림으로 표현하면

상태설명
변수 선언만 함 (public Rigidbody playerRigidbody;) 빈 상자만 준비됨. 아직 아무것도 없음(null)
오브젝트 연결함 (playerRigidbody = GetComponent<Rigidbody>();) 상자 안에 실제 Rigidbody 오브젝트의 "주소"가 담김 (참조)
사용함 (playerRigidbody.AddForce(...)) 상자가 가리키는 오브젝트에 실제 동작을 시킴

5. 진짜 중요 포인트

  • 변수는 그 타입의 데이터를 담을 수 있는 그릇이다.
  • 변수 선언 = 공간을 만든 것이지, 실체(오브젝트)를 생성한 건 아니다.
  • 변수는 실제 존재하는 오브젝트(컴포넌트)를 가리킬 수 있다. (참조)

6. 한 문장으로 정리

"playerRigidbody를 선언하는 건 컵을 놓은 것일 뿐이고, Rigidbody 오브젝트를 생성하거나 연결하는 건 그 컵에 물을 따르는 것이다."


추가로 알아야 할 것

  • 만약 playerRigidbody가 null인데 코드를 실행하면,
    "NullReferenceException" 에러가 발생한다.
    → "빈 컵에 물을 따르려고 해서 터진 거"랑 같다.

Update()매서드는 Start()매서드처럼 특정 시점에 자동으로 실행되는 유니티 이벤트 메서드이다. Update()매서드는 한 프레임에 한 번, 매 프레임마다 반복 실행된다.

 

Input을 사용한 입력 감지

유니티의 Input 클래스는 사용자 입력을 감지하는 매서드를 모아둔 집합이다. Input의 입력 감지 매서드는 실행 시점에 어떤 키를 눌렀는지 알려준다.

 

Update()매서드는 1초에 수십 번씩 실행하며, 따라서 Update()매서드에서 입력 감지 매서드를 사용하면 입력 감지 매서드가 매우 짧은 간격으로 반복 실행되기 때문에 플레이어는 입력이 즉시 감지된다고 느낀다.

여기서 헷갈렸던 부분을 다시 정리!

 

프로그램은 행위(동작)과 대상(데이터)를 다룬다.

그래서 코드 흐름은 기본적으로

(1) 어떤 대상을 선택하고

(2) 그 대상에게 어떤 행동을 시킨다.

 

if(조건) { 대상, 행동()};


 

728x90