처음 괄호를 보고 이건 그냥 장식용으로 쓰이는건가 싶었지만 당연히 아니었다.
매개변수라 부른다는데
매개변수()는 메서드(함수)나 생성자를 호출할 때 전달하는 값을 의미한다.
즉, 어떤 기능을 실행할 때 추가적인 정보를 넘겨주는 역할을 한다.
그럼 매게변수에는 무엇이 들어갈까?
기본적으로 제공하는 자료형을 전달할 수 있다.
int (정수)
float (실수)
bool (참/거짓)
string (문자열)
ex)체력깍기
void Damage(int amount)
{
Debug.Log("플레이어 " + amount + " 피해 입음");
}
Damage(10); 호출 시 10 값을 매개변수로 전달한다.
유니티에 자주 사용하는 GameObject, Transform, Rigidbody 같은 컴포넌트나 오브젝트를 전달할 수 있다.
ex) 특정 대상 데미지 주기
void Attack(GameObject target)
{
Debug.Log(target.name + " 공격!");
}
여러 개의 값을 한꺼번에 전달할 때 배열이나 List<>를 전달할 수 있다.
ex)여러 몬스터에게 데미지 주기
void DamageEnemies(GameObject[] enemies)
{
foreach (GameObject enemy in enemies)
{
Debug.Log(enemy.name + " 데미지를 줌!");
}
}
델리게이트나 Action<>을 매개변수로 사용하면 특정 기능을 호출할 때 실행할 동작을 변경할 수 있다.
ex: 버튼 클릭 이벤트 설정
void SetButtonAction(UnityEngine.Events.UnityAction action)
{
action.Invoke();
}
기본값을 설정해서 매개변수를 생략할 수 있다.
ex) 기본 공격력 적용
void Attack(int power = 10)
{
Debug.Log("공격력: " + power);
}
→ Attack();을 호출하면 기본값 10이 사용되고,
Attack(20);을 호출하면 20이 적용된다.
out과 in 키워드는 매개변수를 다룰 때 사용하는 특수한 키워드다.
ex) 몬스터 처치 후 보상
void GetReward(out int gold, out string item)
{
gold = 100; // 골드 보상
item = "전설의 검"; // 아이템 보상
}
↑ gold와 item을 반환
int rewardGold;
string rewardItem;
GetReward(out rewardGold, out rewardItem);
Debug.Log("획득한 골드: " + rewardGold);
Debug.Log("획득한 아이템: " + rewardItem);
결과 → 획득한 골드: 100, 획득한 아이템: 전설의 검
out의 특징
반드시 메서드 내부에서 값을 할당해야 함.
함수 호출 전에는 변수에 값을 할당하지 않아도 됨.
in은 읽기 전용 매개변수
즉, 함수 내에서 값을 변경할 수 없다. 대신, 값이 복사되지 않고 참조로 전달된다.
void MonsterInfo(in Monster monster)
{
Debug.Log("몬스터 이름: " + monster.name);
Debug.Log("체력: " + monster.hp);
monster.hp = 50; // 변경 불가능 (에러 발생)
}
in의 특징
함수 내부에서 값을 변경할 수 없다.
큰 구조체(struct)를 전달할 때 복사 비용을 줄여 성능 최적화 가능하다.
struct Monster
{
public string name;
public int hp;
public Monster(string name, int hp)
{
this.name = name;
this.hp = hp;
}
}
Monster boss = new Monster("드래곤", 500);
MonsterInfo(in boss);
out: 함수에서 여러 개의 값을 반환할 때
in: 큰 구조체를 복사 없이 전달해서 성능을 최적화하고 싶을 때
A : 꼭 struct(구조체)만 사용할 필요는 없지만 보통 struct와 함께 사용하는 게 일반적이다.
왜?
1) 클래스(class)는 원래 참조형(reference type)
클래스는 원래 참조로 전달되기 때문에 in을 붙여도 성능 차이가 거의 없다.
2) 구조체(struct)는 값형(value type)이라 복사가 발생
기본적으로 struct는 값이 복사돼서 전달되는데
in을 붙이면 복사 없이 참조로 전달되므로 성능 최적화 효과가 있다.
class에 in 쓰기
class Monster
{
public string name;
public int hp;
public Monster(string name, int hp)
{
this.name = name;
this.hp = hp;
}
}
void MonsterInfo(in Monster monster)
{
Debug.Log("몬스터 이름: " + monster.name);
// monster.hp = 50; // 여전히 변경 가능 (클래스는 참조형이기 때문)
}
클래스는 참조 타입이기 때문에 in을 붙여도 큰 차이가 없다.
in을 struct에 쓰기
struct Monster
{
public string name;
public int hp;
public Monster(string name, int hp)
{
this.name = name;
this.hp = hp;
}
}
void MonsterInfo(in Monster monster)
{
Debug.Log("몬스터 이름: " + monster.name);
monster.hp = 50; // 에러 발생! (in은 읽기 전용)
}
기본적으로 값이 복사되지만, in을 쓰면 참조로 전달돼서 성능이 좋다.