멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 27일차 - 조이스틱 이동, 점프, 공격

2025. 6. 24. 16:37·강의/멋쟁이 사자처럼 유니티 부트캠프

오늘은 키보드로 구현했던 이동과 점프를 조이스틱과 UI 버튼으로 구현하고, 공격과 콤보에 대해 배웠다. 또한 Blend Tree를 이용해서 애니메이션 상태 변경을 자연스럽게 하는 방법을 배웠다. 지금은 리깅이 되어있지않은 스프라이트 애니메이션이기 때문에 큰 차이가 보이지 않지만, 리깅을 적용하는 경우 더 자연스러운 애니메이션이 될 것이다.

또한 콤보를 구현하는 부분이 생각보다 까다로운 작업이었다. 격투게임같은 복잡한 콤보 기술들은 어떤 식으로 구현하는지 궁금해진다. 

 

 

조이스틱

조이스틱 스크립트 생성

저번 시간에 인스펙터 상으로 추가했던 이벤트 트리거를 IPointerDownHandler, IDragHandler, IPointerUpHandler 인터페이스를 이용해서 스크립트로 작성할 수 있다.

public class JoystickController : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    public void OnPointerDown(PointerEventData eventData)
    {
        Debug.Log("Down");
    }

    public void OnDrag(PointerEventData eventData)
    {
        Debug.Log("Drag");
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        Debug.Log("Up");
    }
}

조이스틱 기능 구현

누른 곳에 background 이미지가 생기고, 드래그하면 그 쪽 방향으로 handelr 이미지가 이동하는 기능을 구현하였다.

public class JoystickController : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    [SerializeField] GameObject backgroundUI;
    [SerializeField] GameObject handlerUI;

    Vector2 startPos, currPos;
    void Start()
    {
        backgroundUI.SetActive(false);
    }
    public void OnPointerDown(PointerEventData eventData)
    {
        backgroundUI.SetActive(true);
        backgroundUI.transform.position = eventData.position;
        startPos = eventData.position;
    }

    public void OnDrag(PointerEventData eventData)
    {
        currPos = eventData.position;
        Vector2 dragDir =  currPos - startPos;

        float maxDist = Mathf.Min(dragDir.magnitude, 100f);
        
        handlerUI.transform.position = startPos + dragDir.normalized * maxDist;
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        handlerUI.transform.position = Vector2.zero;
        backgroundUI.SetActive(false);
    }
}

결과

캐릭터 이동

Drag 시 Knightcontroller의 inputDir 값만 바꾸어주면, 이전에 만들어둔 Move()에 의해 이동하게 된다.

// JoystickController
public void OnDrag(PointerEventData eventData)
{
    knightController.InputJoystick(dragDir.x, dragDir.y);
}
// KnightController
public void InputJoystick(float x, float y)
{
    inputDir = new Vector3(x, y, 0);
}

 

BlendTree

애니메이터에 Blend Tree를 추가하고, 타입을 2D Simple Directional로 바꾼다. 이렇게 하면 JoystickX가 양수나 음수일 때는 Run, 0일 때는 Idle로 바뀐다.

// KnightController
public void InputJoystick(float x, float y)
{
    inputDir = new Vector3(x, y, 0);
    animator.SetFloat("JoystickX", x);
    animator.SetFloat("JoystickY", y);
    
    if (inputDir.x != 0)
    {
        var scaleX = inputDir.x > 0 ? 1 : -1;
        transform.localScale = new Vector3(scaleX, 1, 1);
    }
}

손가락을 뗄 때도 속도를 0으로 조절해줘야한다.

// JoystickController 
public void OnPointerUp(PointerEventData eventData)
{
    handlerUI.transform.position = Vector2.zero;
    backgroundUI.SetActive(false);
    knightController.InputJoystick(0, 0);
}

결과

 

버튼

점프

점프 버튼을 만든 후, KnightController의 Jump 메소드와 연결시켜준다.

[SerializeField] Button jumpButton;

void Start()
{
    jumpButton.onClick.AddListener(Jump);
}

void Jump()
{
    if (isGround)
    {
        animator.SetTrigger("Jump");
        knightRb.AddForceY(jumpPower, ForceMode2D.Impulse);
    }
}

웅크리기

CrouchIdle, CrouchWalk 애니메이션도 추가하여 Blend Tree에 넣어주었다.

결과

 

공격

공격 애니메이션 추가 후 애니메이터와 코드를 수정한다.

void Attack()
{
	animator.SetTrigger("Attack");
}

결과

콤보

isCombo 값에 따라 공격에서 Idle 상태가 될 지 Combo 상태가 될 지 결정된다.

공격 애니메이션에 AddEvent해서 공격이 끝나는 시점에 Combo를 확인하는 CheckCombo 메소드를 넣어준다.

(마지막 프레임에 넣으면 놓치기때문에 적당히 앞에 넣어줘야 한다.)

이제 코드 상에서 공격 중 공격을 한 번 더 클릭하면 콤보 공격을 실행하는 내용을 작성해야한다.

위의 CheckCombo처럼 콤보 애니메이션의 마지막쯤에 EndCombo() 이벤트를 추가해주었다.

void Attack()
{
    if (!isAttack)
    {
        isAttack = true;
        animator.SetTrigger("Attack");
    }
    else
    {
        animator.SetBool("isCombo", true);
    }
}

public void CheckCombo()
{
    if (!animator.GetBool("isCombo"))
        isAttack = false;
}

public void EndCombo()
{
    isAttack = false;
    animator.SetBool("isCombo", false);
}

공격을 처음 누르면 공격 모션을 실행하고, 실행중(isAttack이 true일 때)에 눌ㄴ다면 Combo로 넘어간다. 공격 모션이 끝날 때 CheckCombo()로 콤보를 실행할 지 말지 결정하고, 만약 안 한다면 isAttack을 false로 바꾸어 공격을 종료시킨다.

콤보의 경우에도 끝날 때 EndCombo()를 실행시켜 isAttack을 false로 바꾸고, 애니메이션도 종료한다.

결과

'강의/멋쟁이 사자처럼 유니티 부트캠프' 카테고리의 다른 글
  • 멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 29일차 - 타운 조작, 상호 작용
  • 멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 28일차 - 타일맵, 키보드 공격
  • 멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 26일차 - 벡터, 행렬, 플랫포머 게임
  • 멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 25일차 - 몬스터 게임 마무리, 삼각함수
로또
로또
게임 개발자 연습생의 발전 일지
  • 로또
    게임 개발 발전소
    로또
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • 개발
        • 코딩테스트
        • JAVA
        • DB
        • Unity
      • 강의 N
        • 패스트캠퍼스 0원 챌린지
        • 멋쟁이 사자처럼 유니티 부트캠프 N
      • 게임
        • 공부
        • 리뷰
  • 블로그 메뉴

    • 홈
    • 방명록
    • 글쓰기
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    그리디알고리즘
    오공완
    3D웹인터랙티브
    그래프
    BFS
    한번에끝내는프론트엔드개발초격차패키지Online
    완전탐색
    백트래킹
    Unity
    그리디
    게임개발
    직장인인강
    자료구조
    패캠인강후기
    C#
    패스트캠퍼스후기
    환급챌린지
    분리집합
    dfs
    2839
    코딩테스트
    직장인자기계발
    Java
    트리
    멋쟁이사자처럼후기
    패캠챌린지
    수강료0원챌린지
    패스트캠퍼스
    백준
    C4D
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
로또
멋쟁이사자처럼부트캠프 유니티 게임 개발 5기 27일차 - 조이스틱 이동, 점프, 공격
상단으로

티스토리툴바