이번 포스트에서는 단검이 적에게 적중하면 인접한 다른 적을 향해 단검이 튕겨나가도록 만들어보겠습니다.
1) SkillThrowingSwordController
public class SkillThrowingSwordController : MonoBehaviour
{
.
.
.
// Bounce Info
public bool _isBouncing;
public int _bounceAmount = 4;
public float _bounceSpeed;
public List<Transform> _enemyTargets;
private int _targetIndex;
.
.
.
private void Update()
{
.
.
.
if (_isBouncing && _enemyTargets.Count > 0)
{
transform.position = Vector2.MoveTowards(
transform.position,
_enemyTargets[_targetIndex].position,
_bounceSpeed * Time.deltaTime
);
if (Vector2.Distance(transform.position, _enemyTargets[_targetIndex].position) < 0.1f)
{
_targetIndex++;
_bounceAmount--;
if (_bounceAmount <= 0)
{
_isBouncing = false;
_isReturning = true;
}
if (_targetIndex >= _enemyTargets.Count)
_targetIndex = 0;
}
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (_isReturning)
return;
if (collision.GetComponent<EnemyController>() != null)
{
if (_isBouncing && _enemyTargets.Count <= 0)
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, 10);
foreach (Collider2D hit in colliders)
{
if (hit.GetComponent<EnemyController>() != null)
_enemyTargets.Add(hit.transform);
}
}
}
SwordStuck(collision);
}
private void SwordStuck(Collider2D collision)
{
_canRotate = false;
_circleCollider2D.enabled = false;
_rigidBody2D.isKinematic = true;
_rigidBody2D.constraints = RigidbodyConstraints2D.FreezeAll;
if (_isBouncing && _enemyTargets.Count > 0)
return;
_animator.SetBool("Rotation", false);
transform.parent = collision.transform;
}
}
추가된 로직은 위와 같습니다.
1 - 1) 프로퍼티
우선, 프로퍼티를 확인해보겠습니다.
_isBouncing의 경우 현재 단검이 튕기고 있는지 여부를 판단합니다.
_bounceAmount의 경우 단검이 튕겨지는 횟수를 의미합니다.
_bounceSpeed는 단검이 튕겨지는 속도를 의미합니다.
_enemyTargets은 단검을 튕기기 위해 적들을 캐싱하는 용도로 사용합니다.
_targetIndex는 단검을 튕기는 순서를 결정합니다. _enemyTargets의 안에서 사용됩니다.
1 - 2) Update 메서드
매 프레임마다 호출되는 Update 문에서는 새로운 로직을 수행합니다.
현재 튕겨지고 있고 _enemyTargets의 인덱스 개수가 0보다 크다면
단검이 _enemyTargets에서 _targetIndex번째로 캐싱된 적을 향해 날아가도록 합니다.
이때 적과 단검의 거리가 0.1보다 작다면,
다음 번째로 캐싱된 적을 향해 날아가고 _bounceAmount를 1 감소시킵니다.
만약, _bounceAmount가 0이되어 더는 튕길 수 없다면
튕겨지지 않도록 하고 단검을 회수합니다.
그리고 _targetIndex가 _enemyTargets의 인덱스 개수를 넘어섰다면
0번째 캐싱된 적을 향해 날아가도록 합니다.
1 - 3) OnTriggerEnter2D
단검이 적과 Trigger되었을 때 호출하는 OnTriggerEnter2D 역시 로직이 변경되었습니다.
기존의 로직은 새로운 함수 SwordStack이라는 이름으로 수행됩니다.
Trigger된 대상이 EnemyController를 컴포넌트로 갖고 있는 경우,
튕기고 있고 캐싱된 적이 없는지 판단하여
단검의 위치를 기준으로 반지름 10의 크기를 가진 Overlap 원을 그리게 됩니다.
그리고 Overlap된 대상을 다시 탐색하여
EnemyController를 컴포넌트로 갖고 있는 경우
캐싱하여 _enemyTargets에 저장하도록 합니다.
위의 로직이 전부 수행된 후 SwordStuck 메서드를 호출합니다.
1 - 4) SwordStuck
SwordStuck의 경우 이전의 로직에서 순서만 바꿔 간단하게 동작합니다.
이때 검이 박히는 경우 애니메이터 변수를 false로 바꾸고
검의 부모를 박힌 대상으로 설정하는 로직 이전에 작업을 수행하도록 수정하였습니다.
만약, 튕기고 있고 캐싱된 적이 있어 _enemyTargets의 크기가 0보다 크다면
캐싱된 적을 향해 검이 날아가야 하므로 위의 로직은 실행하지 않고 종료하게끔 수정하였습니다.
최종 실행 결과는 다음과 같습니다.
'유니티 > 게임 프로젝트' 카테고리의 다른 글
2D RPG - (15 - 8) 단검 투척 스킬 구현_08 (0) | 2025.02.05 |
---|---|
2D RPG - (15 - 7) 단검 투척 스킬 구현_07 (0) | 2025.02.05 |
2D RPG - (15 - 5) 단검 투척 스킬 구현_05 (0) | 2025.02.04 |
2D RPG - (15 - 4) 단검 투척 스킬 구현_04 (0) | 2025.01.29 |
2D RPG - (15 - 3) 단검 투척 스킬 구현_03 (0) | 2025.01.28 |