구조를 조금 수정했다.
원래 Mediator에서 명령을 내려줘야 하는데 Status부분에서 SetDamage를 하면서 Mediator한테 전달해주는 건 의도한 바와 조금 달랐다. 그래서 Mediator에 Damaged라는 함수를 만들어서 Bullet에서 피격 판정을 할 때 Status에서 SetDamage를 부르는게 아닌 Mediator의 Damaged를 RPC로 불렀다.
[PunRPC]
public void Damaged(float attackPower)
{
status.SetDamage(attackPower);
UI.SetSliderValue(status.CurrentHP, status.MaxHP);
DamageAnimation();
effect.HitEffect(transform);
}
그리고 피격 애니메이션을 추가했다.
public void OnDamage()
{
ResetAttack();
ani.Play("Damage");
}
심플한 코드이다. 공격상태 도중에 불릴 수도 있으니 저번에 만든 ResetAttack 함수를 넣었고 Damage 애니메이션을 재생하게 했다. 그리고 effect를 나오게 했는데
public class EffectManager : MonoBehaviour
{
public GameObject hitEffect;
private MemoryPool memoryPool;
void Start()
{
memoryPool = GameObject.Find("MemoryPool").GetComponent<MemoryPool>();
}
public void HitEffect(Transform characterPosition)
{
GameObject tempEffect = memoryPool.ActivePoolItem(MemoryPool.ObjectType.HitEffect);
tempEffect.transform.position = characterPosition.position + new Vector3(0, 0.5f, 0);
}
}
HitEffect는 Transform 값을 받아서 해당 위치 + y 값으로 0.5위치에 나타나게 했다.
보면 Bullet할 때 봤던 ActivePoolItem에 매개변수가 추가된 것을 볼 수 있는데 만들어 뒀던 오브젝트 풀에 확장성을 추가했다.
public class MemoryPool : MonoBehaviour
{
public MemoryPool instance { get; private set; }
public GameObject bullet;
public GameObject hitEffect;
public enum ObjectType { Bullet, HitEffect }
private void Awake()
{
InitEnv(bullet, ObjectType.Bullet);
InitEnv(hitEffect, ObjectType.HitEffect);
}
private int increaseCount = 10; //오브젝트가 부족할 때 Instantiate()로 추가 생성되는 오브젝트 개수
private int maxCount; //현재 리스트에 등록되어 있는 오브젝트 개수
private int activeCount; //현재 게임에 사용되고 있는 활성화 오브젝트 개수
private GameObject bulletObject; //오브젝트 풀링에서 관리하는 게임 오브젝트 프리팹 // 불릿
private GameObject hitEffectObject; //오브젝트 풀링에서 관리하는 게임 오브젝트 프리팹 // 불릿
private List<PoolItem> poolItemList; //관리되는 모든 오브젝트를 저장하는 리스트
}
우선 인스팩터상에서 프리팹을 어사인 할 GameObject bullet 과 hitEffect가 추가됐다. 기존의 스크립트에서는 한 개만 있었다. 그리고 오브젝트 풀링에서 관리하는 게임 오브젝트 프리팹인 bulletObject와 hitEffectObject를 추가했다. 이 역시 기존에는 한 개만 있었다.
그리고 enum ObjectType이 추가됐는데 앞으로 추가로 오브젝트를 관리할 일이 생기면 프리팹 추가 및 enum 추가를 하면 된다.
public void InitEnv(GameObject poolObject, ObjectType objectType)
{
maxCount = 0;
activeCount = 0;
switch (objectType)
{
case ObjectType.Bullet: this.bulletObject = poolObject; break;
case ObjectType.HitEffect: this.hitEffectObject = poolObject; break;
default: break;
}
if(poolItemList == null)
poolItemList = new List<PoolItem>();
InstantiateObjects(objectType);
}
처음에 초기화를 해주기 위해 만들었던 함수이다. 불릿 오브젝트 풀을 만들고 싶으면 InitEnv(bullet, ObjectType.Bullet); 하면 되고, 히트 이펙트 오브젝트 풀을 만들려면 InitEnv(hitEffect, ObjectType.HitEffect); 를 사용하면 된다.
사실 bulletObject hitEffectObject 안 나눠놨어도 됐을 것 같은데 가독성을 위해 나눠놨다.
public void InstantiateObjects(ObjectType objectType)
{
maxCount += increaseCount;
for( int i =0; i < increaseCount; i++ )
{
PoolItem poolItem = new PoolItem();
poolItem.isActive = false;
switch (objectType)
{
case ObjectType.Bullet: poolItem.gameObect = GameObject.Instantiate(bulletObject); break;
case ObjectType.HitEffect: poolItem.gameObect = GameObject.Instantiate(hitEffectObject); break;
default: break;
}
poolItem.gameObect.transform.parent = this.transform;
poolItem.gameObect.SetActive(false);
poolItemList.Add(poolItem);
}
}
실제로 풀을 만드는 함수이다. enum Type을 받아서 타입에 맞는 오브젝트를 Instantiate 해주고 list에 추가한다.
SetActive True 와 False를 해주는 함수이다.
public GameObject ActivePoolItem(ObjectType objectType)
{
if (poolItemList == null)
return null;
if (activeCount == maxCount)
InstantiateObjects(objectType);
int count = poolItemList.Count;
for (int i = 0; i < count; i++)
{
PoolItem poolItem = poolItemList[i];
if(poolItem.isActive == false)
{
if (objectType == ObjectType.Bullet && poolItem.gameObect.CompareTag("Bullet"))
{
activeCount++;
poolItem.isActive = true;
poolItem.gameObect.SetActive(true);
return poolItem.gameObect;
}
else if (objectType == ObjectType.HitEffect && poolItem.gameObect.CompareTag("HitEffect"))
{
activeCount++;
poolItem.isActive = true;
poolItem.gameObect.SetActive(true);
return poolItem.gameObect;
}
}
}
return null;
}
// 현재 사용이 완료된 오브젝트를 비활성화 상태로 설정
public void DeactivatePoolItem(GameObject usedObject)
{
if (poolItemList == null || usedObject == null)
return;
int count = poolItemList.Count;
for (int i = 0; i < count; i++)
{
PoolItem poolItem = poolItemList[i];
if(poolItem.gameObect == usedObject)
{
activeCount--;
poolItem.isActive = false;
poolItem.gameObect.SetActive(false);
return;
}
}
}
내일은 오브젝트 풀의 리스트를 나누는 작업을 할 예정이다.
'Unity > Portfolio Daily Log' 카테고리의 다른 글
캐주얼 슈팅 액션 대전 게임 (모바일) - 11 피격시 카메라 흔들림, Hit Effect 변경 (0) | 2022.07.27 |
---|---|
캐주얼 슈팅 액션 대전 게임 (모바일) - 10 오브젝트 풀 개선 (0) | 2022.07.26 |
캐주얼 슈팅 액션 대전 게임 (모바일) - 8 포톤_4 피격 동기화 (0) | 2022.07.25 |
캐주얼 슈팅 액션 대전 게임 (모바일) - 7 포톤_3 체력바, 닉네임 색깔로 적과 차별점 두기 (0) | 2022.07.22 |
캐주얼 슈팅 액션 대전 게임 (모바일) - 6 체력바 (0) | 2022.07.22 |