유니티에서 더블 클릭을 구현하기가 여간 귀찮다. 방법이야 정말 여러개가 있지만 업데이트 문에서 감지한다던가 UniRx 를 써서 감지한다던가 하는 것도 가능하지만 성능상의 단점, 구현의 한계 등으로 몇번 시도해보다가 다른 방향으로 틀게 되었다. 이 문제의 핵심은 대쉬 구현이 아닌 키보드 더블 탭 구현이다. 그리고 이번도 저번과 마찬가지로 New Input System 을 활용한다.
Actions - Dash 의 Binding Properties 를 보면 Interactions - Multi Tap 기능이 있다. 간략히 설명을 하자면 다음과 같다. 상세 정보는 링크를 확인
Tap Count - 상호작용을 위해 필요한 탭 수
Max Tap Spacing - 탭 사이의 입력이 없어도 되는 시간
Max Tap Duration - 탭의 최대 입력 시간
Press Point - (정확한 정보 확인시 추가)
몇번 테스트 해본 결과 아주 만족스러운 디폴트 값이었기에 그냥 쓰기로 했다. 기존의 New Input System 과 마찬가지로 SendMessage 방식으로 작동하기에 OnDash 함수를 구현해주고 코루틴으로 애니메이션과 쿨다운을 넣었다.
더블 탭은 유니티에서 구현해주었으니 우리는 대쉬만 구현하면 된다.
작동방식
1. New Input System -> OnDash() 실행
2. 대쉬가 가능하면 애니메이션을 실행하고 코루틴을 시작
3. 대쉬 불가능 처리 및 현재 gravity 저장 후 순간 속도 증가
4. 대쉬 애니메이션이 끝나면 현재 위치에 따라 적절한 애니메이션으로 변경
5. 대쉬 전 변수들을 복구 후에 특정 시간이 지나면 대쉬 가능 처리
private void OnDash() // 1
{
if (isAbleDash)
{ // 2
anim.Play("Dash", -1, 0);
StartCoroutine(DashStart());
}
}
private IEnumerator DashStart()
{
Debug.Log("Dash!");
Debug.Log("Dash Cool Time Start");
// 3
isAbleDash = false;
isDashing = true; // isDashing 동안 사용자의 입력을 받지 않음
var originalGravity = rigid.gravityScale;
rigid.gravityScale = 0f;
rigid.velocity = new Vector2(transform.localScale.x * dashPower, 0);
// 4
while (anim.GetCurrentAnimatorStateInfo(0).normalizedTime <= 1.0f)
{
yield return null;
}
if (isGrounded)
anim.Play("Idle", -1, 0);
else
StartCoroutine(JumpAnimation());
// 5
isDashing = false;
rigid.gravityScale = originalGravity;
rigid.velocity = new Vector2(0, 0);
yield return new WaitForSeconds(dashCooldown); // 1초
isAbleDash = true;
Debug.Log("Dash Cool Time Finished");
}
다른 실행 장면을 각기 녹화한것이라 결과의 모습이 다르지만 잘 되는 걸 확인 할 수 있다.