InputAction에서 미리 만들어둔 Fire 부분 작성
// TopDownController.cs
protected bool isAttacking = false;
private float timeSinceLastAttack = float.MaxValue;
void Update()
{
HandleAttackDelay();
}
void HandleAttackDelay()
{
// TODO : MAGIC NUMBER 수정
if(timeSinceLastAttack < stats.CurrentStat.attackSO.delay)
{
timeSinceLastAttack += Time.deltaTime;
}
else if (isAttacking && timeSinceLastAttack >= stats.CurrentStat.attackSO.delay)
{
timeSinceLastAttack = 0f;
CallAttackEvent(stats.CurrentStat.attackSO);
}
}
public void CallAttackEvent(AttackSO attackSO)
{
OnAttackEvent?.Invoke(attackSO);
}
// PlayerInputController.cs
public void OnFire(InputValue val)
{
// 입력받은 키가 눌렸는지 확인
isAttacking = val.isPressed;
}
//TopDownShooting.cs
[SerializeField] Transform tfFirePoint;
Vector2 aimDir = Vector2.right;
public GameObject prefProjectile;
void Start()
{
// 공격 기능을 공격 이벤트 구독
controller.OnAttackEvent += OnShoot;
// 조준 기능을 마우스 포지션을 받는 이벤트에 구독
controller.OnLookEvent += OnAim;
}
void OnAim(Vector2 dir)
{
aimDir = dir;
}
void OnShoot()
{
CreateProjectile();
}
void CreateProjectile()
{
Instantiate(prefProjectile, tfFirePoint.position, Quaternion.identity);
}
심화 파트 구현
// TopDownShooting.cs
void CreateProjectile(RangedAttackSO rangedAttackSO, float angle)
{
// 심화 파트
// 회전각
float rotZ = Mathf.Atan2(aimDir.y, aimDir.x) * Mathf.Rad2Deg;
// 날아가기 구현 : 심화
Projectile p = Instantiate(prefProjectile, tfFirePoint.position, Quaternion.Euler(new Vector3(0, 0, rotZ)));
p.Fire(10f, aimDir);
}
// Projectile.cs
public class Projectile : MonoBehaviour
{
Rigidbody2D rb;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
}
public void Fire(float speed, Vector2 dir)
{
rb.velocity = speed * dir;
}
public void OnCollisionEnter2D(Collision2D other)
{
if(other.gameObject.tag.Equals("Obstacle"))
{
Destroy(gameObject);
}
}
}
데이터를 분리했다는 차원에서는 동일하게 사용.
나는 데이터들을 내부에 구조체 리스트나 맵으로 만들어 둠.
하나의 오브젝트에서 찾아서 쓰는 방법.
여기서는 개별, 한 개씩 만들어서 사용하는 방법.