내일배움캠프 54일차 7/02 TIL + 유닛 이동 구현
유닛 이동 구현
어제 만든 이동 기능을 UserUnitController로 옮기고 진행했습니다. 이제 UserInputManager의 기능은 순수히 InputAction들을 실행시키기만 합니다.
private void OnEnable()
{
mouseLeftClick = playerInputActions.User.MouseLeftClick;
mouseRightClick = playerInputActions.User.MouseRightClick;
mouseDrag = playerInputActions.User.MouseDrag;
hold = playerInputActions.User.Hold;
readyToAttack = playerInputActions.User.ReadyToAttack;
mouseLeftClick.Enable();
mouseRightClick.Enable();
mouseDrag.Enable();
hold.Enable();
readyToAttack.Enable();
}
private void OnDisable()
{
mouseLeftClick.Disable();
mouseRightClick.Disable();
mouseDrag.Disable();
hold.Disable();
readyToAttack.Disable();
}
UserUnitController는 유저가 유닛을 컨트롤 할 때 필요한 기능 전반을 담당합니다. 선택한 유닛들을 이동시키는 기능도 포함됩니다. 선택한 유닛 목록을 관리하여 우클릭 시 각 유닛들에게 해당 위치로 이동하는 명령을 내립니다. 유닛끼리 해당 위치로 가려고 충돌이 일어날 텐데, 단순히 offset 값을 유닛 수가 늘어날 때마다 조금씩 주는 것으로 해결했습니다.
public void OnMouseRightClick(InputAction.CallbackContext context)
{
if (selectedUnits.Count > 0)
{
MouseStartPos = mouseDrag.ReadValue<Vector2>();
Vector2 worldMousePos = Camera.main.ScreenToWorldPoint(MouseStartPos);
targetPositionMarker.gameObject.SetActive(true);
targetPositionMarker.SetPosition(worldMousePos);
float offset = 0;
foreach (var unit in selectedUnits)
{
((IMovable)unit).Move(worldMousePos, offset);
offset += 1.0f;
}
}
}
이 작업을 하면서 인터페이스를 단순히 형변환만 해주면 해당 인터페이스가 속한 클래스의 기능들이나 같이 상속받은 인터페이스의 기능도 다 함께 사용할 수 있다는 것도 배웠습니다.
참고로 네비게이션 기능은 NavMeshPlus의 2D 네비게이션 기능을 활용하여 이동을 구현했습니다.
유닛을 선택하고 우클릭하면 스타크래프트나 워크래프트처럼 해당 자리에 초록 점이 잠깐 나타나고 그 자리로 이동합니다. 물론 이동은 유닛에서 구현했습니다.
public void MoveToTarget(Vector2 target, float offset)
{
isHold = false;
agent.stoppingDistance = offset;
agent.SetDestination(target);
}
또한, H 키를 누르면 이동 중에 멈추고 홀드되는 기능도 추가했습니다. 유닛이 이동을 중지하고 대기 상태로 전환됩니다.
public void HoldPosition()
{
isHold = true;
agent.isStopped = true;
}
느낀 점
이제 A 키를 누르면 공격 표시가 마우스를 따라다니다가 좌클릭하면 해당 유닛을 공격하거나, 해당 위치로 공격하며 이동하게 만들 계획입니다. 이를 대략 정리해보면 다음과 같습니다:
- A 누르기 -> 타겟 지정 -> 타겟 공격
- A 누르기 -> 땅 지정 -> 이동 -> 이동 중 적 발견 시 중지 및 공격 -> 적 이동 시 추적 -> 적 사살 시 다시 이동
- 정지 상태에서 적 감지 -> 공격 -> 적 이동 시 추격
공격 하나를 구현하는데 신경 쓸 것이 많지만, 내일 완료할 수 있을 것 같습니다. 생각보다 이동을 구현하는 것이 어렵지 않아서 다행입니다. 다만 UserUnitController가 너무 많은 기능을 담당하는지 고민이 되는데, 이는 프로토타입을 제작한 후 리팩토링 시간을 가지면 해결할 수 있을 것 같습니다.