유니티 RPG - 35. 전략패턴을 활용한 플레이어 무기시스템 - 3
Intro
이번 포스팅에서는 플레이어가 무기를 장착하고 해제할 때 그 무기를 생성하고, 무기에맞는 애니메이션을 수행하는것을 구현해보았습니다.
게임이 시작되면 플레이어 데이터를 불러와서 장착중이던 장비대로 능력치 및 외관 장비가 장착되어 있어야합니다. => 이 부분은 나중에 구현 하려합니다.
-
먼저 플레이어는 게임이 시작되면 주먹(Punch) 무기를 장착하도록 했습니다.
- 인벤토리에서 무기를 장착하면 주먹 무기를 파괴하고, 장착한 무기정보에따라 프리팹을 생성합니다.
- 장착중이던 무기를 해제하면 다시 주먹 무기를 장착합니다.
- 프리팹이 생성되면, 프리팹의 무기타입에따라 플레이어의 공격 애니메이션이 달라집니다.
WeaponManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/*
WeaponManager : 무기 및 전략 관리
- SetWeapon() : 현재 무기 설정
- ChangeAttackStrategy() : 공격 전략 변경
- Attack() : 현재 무기의 공격 실행
*/
public class WeaponManager : Singleton<WeaponManager>
{
#region ** Serialized Fields **
[SerializeField] PlayerController player;
[SerializeField] Transform weaponTransform;
#endregion
#region ** Fields **
private GameObject myWeaponGo; // 장착중인 무기 오브젝트
private WeaponType myWeaponType; // 장착중인 무기의 타입
private Weapon currentWeapon;
readonly private int hashWeaponType = Animator.StringToHash("WeaponType");
#endregion
// 무기 타입별 WeaponType 파라미터값
public int CurWeaponType
{
get => player.Anim.GetInteger(hashWeaponType);
set => player.Anim.SetInteger(hashWeaponType, value);
}
private void Start()
{
InitWeapon();
}
// 시작 무기 세팅
public void InitWeapon()
{
currentWeapon = weaponTransform.GetComponentInChildren<Weapon>(); // 현재 장착중인 무기 가져오기
// 무기가 없을 때
if(currentWeapon == null)
{
// 맨손 무기 생성
ResourceManager.Instance.LoadWeaponPrefab("Punch.prefab", prefab =>
{
if (prefab != null)
{
// 프리팹 생성
GameObject newWeapon = Instantiate(prefab, prefab.transform.position, prefab.transform.rotation, weaponTransform);
newWeapon.transform.localPosition = prefab.transform.localPosition;
newWeapon.transform.localRotation = prefab.transform.localRotation;
// 무기 설정
myWeaponGo = newWeapon;
currentWeapon = myWeaponGo.GetComponent<Weapon>();
myWeaponType = WeaponType.None;
}
else
{
Debug.Log($"Failed to load prefab for item : {prefab}");
}
});
}
else
{
myWeaponType = currentWeapon.type;
}
// 현재 무기 애니메이션설정
CurWeaponType = (int)myWeaponType;
}
// 현재 무기 세팅(기본값 Punch)
public void SetWeapon(string type = "None", string weapon = "Punch")
{
if(Enum.TryParse(type, out WeaponType result))
{
ResourceManager.Instance.LoadWeaponPrefab(weapon + ".prefab", prefab =>
{
if (prefab != null)
{
currentWeapon = null;
// 기존 무기 삭제
Destroy(myWeaponGo);
// 프리팹 생성
GameObject newWeapon = Instantiate(prefab, prefab.transform.position, prefab.transform.rotation, weaponTransform);
newWeapon.transform.localPosition = prefab.transform.localPosition;
newWeapon.transform.localRotation = prefab.transform.localRotation;
myWeaponGo = newWeapon;
currentWeapon = myWeaponGo.GetComponent<Weapon>();
// 새로운 무기로 설정
myWeaponGo = newWeapon;
myWeaponType = result;
CurWeaponType = (int)myWeaponType;
}
else
{
Debug.Log($"Fail to load prefab for item : {prefab}");
}
});
}
else
{
Debug.Log($"{type} 은(는) 유효한 타입이 아닙니다.");
}
}
// 공격 전략 변경
public void ChangeAttackStrategy(IAttackStrategy newStrategy)
{
if(currentWeapon != null)
{
currentWeapon.SetAttackStrategy(newStrategy);
}
// 무기가 없을 때(임시)
else
{
Debug.Log("무기가 장착되지 않았음");
}
}
// 현재 무기 공격 실행
public void Attack()
{
if(currentWeapon != null)
{
currentWeapon.PerformAttack();
}
// 무기가 없을 때(임시)
else
{
Debug.Log("무기가 장착되지 않았음");
}
}
}
-
WeaponController 클래스를 싱글톤으로 바꿈으로써 WeaponManager 로 이름을 변경하였습니다.
-
게임시작시 InitWeapon() 호출을 통해 주먹 무기를 장착합니다.
-
SetWeapon() 함수는 무기 장착 및 해제를 구현하는 아이템 클래스에서 호출합니다.
- 매개변수로 아무것도 주어지지 않으면 무기 장착 해제로, 주먹 무기가 생성되도록 했습니다.
WeaponItem.cs
/*
WeaponItem : 무기 아이템
Equip() : 무기 장착
- 무기 데이터의 수치만큼 플레이어 능력치 상승
Unequip() : 방어구 해제
- 무기 데이터의 수치만큼 플레이어 능력치 하락
*/
public class WeaponItem : EquipmentItem
{
public WeaponItemData WeaponData { get; private set; }
public WeaponItem(WeaponItemData data) : base(data)
{
WeaponData = data;
}
// 장착
public override void Equip()
{
// 장비에 따른 플레이어 능력치 반영
DataManager.Instance.GetPlayerData().EquipItem(WeaponData.Damage, WeaponData.Type);
// 장비에 따른 플레이어 무기 설정
WeaponManager.Instance.SetWeapon(WeaponData.SubType, WeaponData.ItemPrefab);
}
// 장착 해제
public override void Unequip()
{
// 장비에 따른 플레이어 능력치 반영
DataManager.Instance.GetPlayerData().UnequipItem(WeaponData.Damage, WeaponData.Type);
// 기본 무기 설정
WeaponManager.Instance.SetWeapon();
}
}
- Equip() 및 Unequip() 함수에서 WeaponManager의 SetWeapon 함수를 호출하여 무기를 세팅합니다.
데이터 추가
어드레서블 에셋 그룹에 무기 프리팹을 추가해주었습니다.
-
어드레서블 에셋 그룹의 프리팹을 가져오기위해서, WeaponData에 itemPrefab 필드를 추가하여 각 아이템의 프리팹 이름을 가져올 수 있도록 했습니다.
-
어드레서블 에셋을 추가하면 반드시 Build - New Build - Default Build Script 를 통해 초기화해주어야합니다.
댓글남기기