화살은 움직이기도 하고 어떤 물체에 닿으면 사라지며 데미지를 입히는 효과를 적용시켜야 하기 때문에 컨트롤러가 필요하다.
그래서 ArrowController를 만들고 Arrow 스프라이트에 붙여주었다.
CreatureController에서 가상함수로 정의된 UpdateAnimation이 있었다. 플레이어만 쓸 수 있는 화살 애니메이션을 추가해줘야 하기 때문에 PlayerController에서 override하여 재정의해준다.
이번에는 화살 스킬 하나 밖에 없기 때문에 간단하게 클래스 멤버변수로 _rangeSkill = false로 선언해주었다.
(나중에 스킬이 많아질 때는 어떤 스킬에 어떤 애니메이션을 재생할지는 스킬 관련 데이터시트로 따로 빼주어서 관리하게 된다.)
_rangeSkill은 펀치할 때 호출하는 코루틴 함수에서 false로, 화살 쏠때 호출하는 코루틴 함수에서 true로 맞춰준다.
override된 UpdateAnimation 함수는 다음과 같이 바꿔주었다.
else if (_state == CreatureState.Skill)
{
switch (_lastDir)
{
case MoveDir.Up:
_animator.Play(_rangeSkill ? "ATTACK_WEAPON_BACK" : "ATTACK_BACK");
_sprite.flipX = false;
break;
case MoveDir.Down:
_animator.Play(_rangeSkill ? "ATTACK_WEAPON_FRONT" : "ATTACK_FRONT");
_sprite.flipX = false;
break;
case MoveDir.Left:
_animator.Play(_rangeSkill ? "ATTACK_WEAPON_RIGHT" : "ATTACK_RIGHT");
_sprite.flipX = true;
break;
case MoveDir.Right:
_animator.Play(_rangeSkill ? "ATTACK_WEAPON_RIGHT" : "ATTACK_RIGHT");
_sprite.flipX = false;
break;
}
}
아래는 별 설명없이 넘어가겠다.
IEnumerator CoStartShootArrow()
{
GameObject go = Managers.Resource.Instantiate("Creature/Arrow");
ArrowController ac = go.GetComponent<ArrowController>();
ac.Dir = _lastDir;
ac.CellPos = CellPos;
_rangeSkill = true;
yield return new WaitForSeconds(0.3f);
State = CreatureState.Idle;
_coSkill = null;
}
public class ArrowController : CreatureController
{
protected override void Init()
{
switch(_lastDir)
{
case MoveDir.Up:
transform.rotation = Quaternion.Euler(0, 0, 0);
break;
case MoveDir.Down:
transform.rotation = Quaternion.Euler(0, 0, -180);
break;
case MoveDir.Left:
transform.rotation = Quaternion.Euler(0, 0, 90);
break;
case MoveDir.Right:
transform.rotation = Quaternion.Euler(0, 0, -90);
break;
}
base.Init();
}
protected override void UpdateAnimation() {}
protected override void UpdateIdle()
{
if (_dir != MoveDir.None) // 유닛 한칸 이동 끝날때까지 입력 못받게
{
Vector3Int destPos = CellPos;
switch (Dir)
{
case MoveDir.Up:
destPos += Vector3Int.up;
break;
case MoveDir.Down:
destPos += Vector3Int.down;
break;
case MoveDir.Left:
destPos += Vector3Int.left;
break;
case MoveDir.Right:
destPos += Vector3Int.right;
break;
}
State = CreatureState.Moving;
if (Managers.Map.CanGo(destPos))
{
GameObject go = Managers.Obj.Find(destPos);
if (go == null)
{
CellPos = destPos;
}
else
{
Debug.Log($"hits {go.name}");
Managers.Resource.Destroy(gameObject);
}
}
else
{
Managers.Resource.Destroy(gameObject);
}
}
}
}