문제상황
텍스트 RPG의 내용으로써 아이템을 장착하면 Inventory 클래스의 playerEquip 배열의 알맞은 위치에 아이템 클래스를 입력하고, 플레이어의 스텟을 장착한 아이템에 맞게 변화를 주려고 했습니다.
아이템을 장착하는 함수는 Inventory 클래스에 있는 상태이며 아이템을 장착할 때, 스텟을 업데이트하는 함수를 호출할 방법이 필요했습니다.
//Character 클래스
//장비에 따른 스테이터스 업데이트
public void UpdateStatus()
{
//무기 장착에 따른 공격력 변화
if (playerInven.PlayerEquip[0] != null)
{
ItemWeapon equipedWeapon = (ItemWeapon)playerInven.PlayerEquip[0];
Attack = attack + equipedWeapon.ItemDamage;
}
else
{
Attack = attack;
}
//방어구 장착에 따른 방어력 변화
if (playerInven.PlayerEquip[1] != null)
{
ItemArmor equipedArmor = (ItemArmor)playerInven.PlayerEquip[1];
Defence = defence + equipedArmor.ItemDefence;
}
else
{
Defence = defence;
}
}
시도해본것, 해결방법
일단 인벤토리 클래스의 객체는 캐릭터 클래스에 선언되어있는 상태입니다.
internal class Character
{
//생략...
//인벤토리
public Inventory playerInven = new Inventory();
//생략...
}
여기서 인벤토리에 자신의 객체를 넘겨주려고 한다면 생성자를 통해서 인벤토리 객체를 생성하여, 자신을 매개변수로 넘겨주어야 합니다.
여기서 자신 클래스에서 따로 객체를 생성하여 사용하는 클래스에 플레이어 변수를 따로 넣어주지 않기위해 이벤트를 사용해보았습니다.
먼저 Inventory 클래스에 이벤트를 선언해주고, 이벤트에 등록된 함수를 호출할 지점을 만들어주었습니다.
이때 델리게이트(대리자) 를 선언하고, 대리자를 기반으로 이벤트를 생성하게됩니다.
//델리게이트 선언
public delegate void EquipEventHendler();
//델리게이트를 통해 이벤트 생성
public event EquipEventHendler UpdateStatus;
public void EquipItem(int index)
{
if (playerInven[index] == null)
{
Console.WriteLine("아이템이 없습니다");
Console.ReadLine();
}
else
{
if (playerInven[index].ItemType == ItemType.Weapon)
{
if (playerEquip[0] == null)
{
playerEquip[0] = playerInven[index];
RemoveItem(index);
}
else
{
IItem temp = playerEquip[0];
playerEquip[0] = playerInven[index];
RemoveItem(index);
AddItem(temp);
}
}
else if (playerInven[index].ItemType == ItemType.Armor)
{
if (playerEquip[1] == null)
{
playerEquip[0] = playerInven[index];
RemoveItem(index);
}
else
{
IItem temp = playerEquip[1];
playerEquip[0] = playerInven[index];
RemoveItem(index);
AddItem(temp);
}
}
else
{
Console.WriteLine("해당아이템은 장착할 수 없습니다.");
Console.ReadLine();
}
//장비 장착후, 스테이터스 변환
UpdateStatus?.Invoke();
}
}
장비를 장착한 후, 이벤트에 등록된 함수를 호출합니다.
이후 Character 클래스의 생성자에 이벤트 함수를 등록해주었습니다.
public Character()
{
maxHealth = 100;
attack = 10;
defence = 10;
PlayerGold = 100;
Health = maxHealth;
Attack = attack;
Defence = defence;
Name = "player";
//이벤트 함수 등록, 장비 변경시 스텟 업데이트 함수 호출
playerInven.UpdateStatus += UpdateStatus;
}
이를 통해 아이템 장착이 완료된 후, 이벤트 함수가 UpdateStatus() 함수를 호출하여 장착 아이템의 상태에 따라 스테이터스를 변경하게 됩니다.
이벤트의 경우, C#에서는 처음 써보아서 사용 방법을 따로 적어보았습니다.
Unity의 경우 이벤트 처럼 사용할 수 있는 UnityAction 을 지원합니다.
UnityAction은 별도의 대리자를 사용하지 않으며 외부값을 호출해야하는 함수의 클래스에 UnityAction을 선언하여 사용합니다.
또한 매개변수가 있는 함수를 호출해애할 경우 <>에 매개변수의 종류를 지정해주어 사용합니다.
public class Health : MonoBehaviour
{
#region Variables
public StatsObject stats;
//데미지를 입을때 호출되는 함수
public UnityAction<float, GameObject> OnDamaged;
//죽을때 호출되는 함수
public UnityAction OnDie;
private bool isDeath = false;
#endregion
//데미지 입기 : 데미지량, 데미지를 주는 오브젝트
public void TakeDamage(float damage, GameObject damageSource)
{
Debug.Log($"stats.Health: {stats.Health}");
Debug.Log($"damage: {damage}");
stats.AddHealth(-damage);
//데미지 처리
OnDamaged?.Invoke(damage, damageSource);
HandleDeath();
}
void HandleDeath()
{
if (isDeath) return;
if(stats.Health <= 0)
{
isDeath = true;
//죽음처리
OnDie?.Invoke();
}
}
}
위 코드에서는 UnityAction으로 2개의 매개변수가 있는 OnDamaged 와 OnDie 를 선언해준 뒤, TakeDamage() 함수 와 HandleDeath() 함수에서 호출하는 모습입니다.
아래 코드에서와 같이 Start나 Awake 등에서 UnityAction을 통해 호출될 함수를 정해줄 수 있습니다.
public class Player : MonoBehaviour
{
//
private Health health;
//데미지
public GameObject damageUI;
public AudioSource hurt01;
public AudioSource hurt02;
public AudioSource hurt03;
private void Start()
{
//Health 이벤트 함수 등록
health = GetComponent<Health>();
health.OnDamaged += OnDamaged;
health.OnDie += OnDie;
}
//데미지 처리
void OnDamaged(float damage, GameObject damageSource)
{
StartCoroutine(DamageEffect());
}
//죽음 처리
void OnDie()
{
//게임 오버시 구현 내용
//.....
GameManager.isGameOver = true;
}
}
여기서는 OnDamaged 호출시 OnDamage(float damage, GameObject damageSource) 가 호출되며
OnDie 호출시 OnDie() 함수가 호출되는형식입니다.
'내일배움캠프 > TIL' 카테고리의 다른 글
내일배움캠프 15일차 TIL - 얕은 복사, 깊은 복사 (0) | 2024.10.04 |
---|---|
내일배움캠프 14일차 TIL - 마크다운(Mark Down) 문법 (0) | 2024.10.02 |
내일배움캠프 12일차 TIL - 속성(프로퍼티) (0) | 2024.09.30 |
내일배움캠프 11일차 TIL - GC(가비지 컬렉터) (0) | 2024.09.27 |
내일배움캠프 10일차 TIL - C# 싱글톤 (0) | 2024.09.26 |