본문 바로가기

study/unity

[unity] #5. C# 스크립트 기초 - 클래스, 벡터

- 클래스

클래스는 함수와 변수를 모아둔 것이다.

 

플레이어의 스크립트를 작성한다고 가정했을 때, 플레이어에는 HP, MP 등 상태(변수)와 공격, 방어, 마법 등 액션(함수)등이 필요하다.

클래스를 사용하면 관계가 있는 변수와 함수를 하나로 합칠 수 있으므로 스크립트를 관리하기 쉽다.

 

멤버 변수 : 클래스에서 사용한 변수

멤버 메서드 : 클래스에서 사용한 메서드

 

class 클래스명{

      멤버 변수 선언;

      멤버 메서드 구현;

}

 

Player라는 class를 구현 후 Player myPlayer;를 쓰면 myPlayer 변수를 만들 수 있다.

이 상태에서 myPlayer 변수의 상자 안은 비어있는 상태이다.

int형의 num변수에 숫자를 대입하는 것처럼 myPlayer 변수에는 플레이어의 실체를 대입한다.

이 실체를 인스턴스라고 한다.

인스턴스(instance)는 해당 클래스의 구조로 컴퓨터 저장공간에서 할당된 실체를 의미한다. 

myPlayer 변수가 가진 멤버 메서드나 멤버 변수를 사용하려면 myPlayer. 멤버 메서드명(또는 멤버 변수명)을 쓴다.

 

직접 클래스를 만들 수도 있지만 유니티가 처음부터 제공하는 class도 있다.

Vector class와 Debug class 등이 있다.

 

<Player class 구현>

*Test class 외부에 추가하여야 한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player { //Player class 선언
	//멤버변수 hp, power 선언
	private int hp = 100; //다른 클래스에서 접근 불가 (myPlayer.hp라고 써도 접근 불가능)
	private int power = 50;
	
    //멤버메서드 Attack, Damage
	public void Attack() {
		Debug.Log(this.power + "대미지를 입혔다");
	}

	public void Damage(int damage)
	{
		this.hp -= damage;
		Debug.Log(damage + "대미지를 입었다");
	}
}

public class Test : MonoBehaviour
{
	void Start()
	{
		Player myPlayer = new Player();
		myPlayer.Attack();
		myPlayer.Damage(30);
	}
}

 

출력 결과

인스턴스를 만들려면 new 클래스이름();을 쓴다.

Player myPlayer = new Player();
//Player myPlayer; Player형 myPlayer 변수 선언 -> 상자 만들기
//new Player(); : Player형의 실체인 인스턴스를 작성하여 변수에 대입

- 접근 수식자

: 다른 클래스에서 멤버로 접근 가능한지의 여부

Player 클래스의 멤버 변수와 멤버 메서드 앞의 public이나 private 키워드 같은 것을 접근 수식자라고 한다.

 

public : 모든 클래스에서 접근 가능

protected : 같은 클래스와 해당 클래스의 서브 클래스에서 접근 가능

private : 같은 클래스에서만 접근 가능 , default 값

 

- this 키워드

: this는 자신의 인스턴스를 가리키는 키워드이다.

사실 this를 붙이지 않아도 자기 클래스의 멤버 변수를 사용할 수 있다.

하지만 만약 멤버 변수와 동일한 이름의 로컬 변수를 선언했을 때 로컬변수의 값이 우선해서 사용된다.

따라서 멤버 변수를 쓸 때는 명시적으로 this를 붙여야 오류가 생기지 않는다.

 

지금까지 설명한 내용은 객체 지향 프로그래밍이다.

객체지향의 3대 요소는 상속, 접근 수식자에 의한 캡슐화, 다형성이다.

여기서는 '캡슐화'를 소개했다.

 

캡슐화  : 외부에 감추는 방법으로는 언어적 측면에서 접근지정자를 두어 은닉의 정도를 기술하여 구현한다. 은닉의 정도를 접근 지정자로 기술하고 해당 영역에 들어가는 속성이나 메서드를 제한하면 된다. 접근 지정자에 의해 제한된 멤버들은 컴파일러에 의해 판단된다. 언어적 측면에서 접근 지정자에 의해 정의된 해당 멤버 변수나 멤버 함수는 코드 중에 접근방식을 위반한 코드를 작성하면 컴파일 오류로 처리하고 실행코드 생성을 제한한다.

 

다형성 : 어떤 한 요소에 여러 개념을 넣어 놓는 것으로 일반적으로 오버라이딩(같은 이름의 메서드가 여러 클래스에서 다른 기능을 하는 것)이나 오버로딩(같은 이름의 메서드가 인자의 개수나 자료형에 따라서 다른 기능을 하는 것)을 의미한다. 다형 개념을 통해서 프로그램 안의 객체 간의 관계를 조직적으로 나타낼 수 있다.

 

상속 : 새로운 클래스가 기존의 클래스의 자료와 연산을 이용할 수 있게 하는 기능이다. 상속을 받는 새로운 클래스를 부클래스, 파생 클래스, 하위 클래스, 자식 클래스라고 하며 새로운 클래스가 상속하는 기존의 클래스를 기반 클래스, 상위 클래스, 부모 클래스라고 한다. 상속을 통해서 기존의 클래스를 상속받은 하위 클래스를 이용해 프로그램의 요구에 맞추어 클래스를 수정할 수 있고 클래스 간의 종속 관계를 형성함으로써 객체를 조직화할 수 있다.

 

public class Test : MonoBehaviour
//상속 : 유니티가 미리 준비한 MonoBehaviour 클래스의 기능을 Test 클래스에 집어넣겠다고 선언하는 과정
// MonoBehaviour : 게임 오브젝트를 구성하는 기본 기능을 멤버 변수와 멤버 메서드로 준비한 클래스

 

* Debug.Log()는 static 함수로 인스턴스를 만들지 않고도 쓸 수 있는 함수로 선언되었다.

 

- vector

C#에는 float형의 x, y, z값 3개를 갖는 Vector3 클래스(정확히는 구조체 : 클래스처럼 변수와 함수를 합친 구조, 클래스와 비교하면 사용할 수 있는 기능이 제한되지만 클래스보다 빠르게 동작한다.)가 있다.

2D 게임용에는 float형의 x, y 값을 갖는 Vector2 클래스가 있다.

둘 다 좌표나 벡터로 쓸 수 있다.

그리고 가속도, 힘, 이동 속도와 같은 물리 수치로도 사용할 수 있다.

 

class Vector3{
	public float x;
    public float y;
    public float z;

	//Vector용 멤버 메서드가 아래에 이어짐
}

 

<Vector2 클래스의 멤버 변수에 숫자를 더하는 예제>

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
	void Start()
	{
		Vector2 playerPos = new Vector2(3.0f, 4.0f); //인수 전달 및 멤버 변수 초기화
		playerPos.x += 8.0f;
		playerPos.y += 5.0f;
		Debug.Log(playerPos);
	}
}

 

출력 결과

<Vector2 클래스끼리 뺄셈>

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
	void Start()
	{
		Vector2 startPos = new Vector2(2.0f, 1.0f);
		Vector2 endPos = new Vector2(8.0f, 5.0f);
		Vector2 dir = endPos - startPos;
		Debug.Log(dir);

		float len = dir.magnitude; //magnitude : 벡터의 길이 구하기
		Debug.Log(len); 
	}
}

 

출력 결과

출처 : <유니티 교과서 개정 3판> 책