본문 바로가기

유니티(조이스틱구현 2, Animator Blend Tree) _ 멋쟁이사자처럼 유니티 부트캠프 후기 27회차

@salmu2025. 6. 24. 16:50
반응형

[27회차 수업내용] 250624

1. 조이스틱구현

2. 애니메이션 블렌드 트리 실습 1

 

1. Handler 인터페이스 (유니티엔진)

  •  UI 요소의 마우스 / 터치 입력 처리에 사용
using UnityEngine;
using UnityEngine.EventSystems;

// Joystick 입력 처리를 위한 스크립트, 이벤트 핸들러 인터페이스 구현
public class JoystickController : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    // 마우스 버튼 또는 터치가 눌렸을 때 호출됨
    public void OnPointerDown(PointerEventData eventData)
    {
        Debug.Log("Pointer Down"); // 시작 시 로그 출력
    }

    // 마우스 또는 터치가 드래그 중일 때 계속 호출됨
    public void OnDrag(PointerEventData eventData)
    {
        Debug.Log("Drag"); // 드래그 중 로그 출력
    }

    // 마우스 버튼 또는 터치가 떼졌을 때 호출됨
    public void OnPointerUp(PointerEventData eventData)
    {
        Debug.Log("Pointer Up"); // 종료 시 로그 출력
    }
}

* PointerEventData eventData핸들러 인터페이스에서 필수로 요구하는 매개변수

 

 

 

 

1.2 조이스틱 (핸들형 + 터치 시 작동) 구현 코드

using UnityEngine;
using UnityEngine.EventSystems;

// Joystick 입력을 처리하는 클래스, 드래그 기반 이동 컨트롤
public class JoystickController : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    [SerializeField] private KnightController_Joystick knightController; // 조작할 캐릭터 컨트롤러 연결
        
    [SerializeField] private GameObject backgroundUI; // 조이스틱 배경 UI
    [SerializeField] private GameObject handlerUI;    // 조이스틱 핸들(움직이는 부분) UI

    private Vector2 startPos, currPos; // 시작 위치, 현재 위치 저장용 변수

    void Start()
    {
        backgroundUI.SetActive(false); // 초기에는 조이스틱 비활성화 상태
    }
    
    // 터치(마우스) 시작 시 호출
    public void OnPointerDown(PointerEventData eventData)
    {
        backgroundUI.SetActive(true); // 조이스틱 UI 활성화
        backgroundUI.transform.position = eventData.position; // 터치 위치에 조이스틱 배경 위치 이동
        startPos = eventData.position; // 시작 위치 저장
    }

    // 드래그 중일 때 계속 호출
    public void OnDrag(PointerEventData eventData)
    {
        currPos = eventData.position; // 현재 터치 위치 갱신
        Vector2 dragDir = currPos - startPos; // 드래그 방향(벡터)

        // 조이스틱 핸들 이동 제한 (최대 거리 75px)
        float maxDist = Mathf.Min(dragDir.magnitude, 75f);
        
        // 핸들 위치 = 시작 위치 + 방향 * 거리
        handlerUI.transform.position = startPos + dragDir.normalized * maxDist;
        
        // 캐릭터 컨트롤러에 입력 전달 (X, Y)
        knightController.InputJoystick(dragDir.x, dragDir.y);
    }

    // 터치(마우스) 해제 시 호출
    public void OnPointerUp(PointerEventData eventData)
    {
        knightController.InputJoystick(0, 0); // 입력 초기화 (정지)
        handlerUI.transform.localPosition = Vector2.zero; // 핸들 위치 초기화
        backgroundUI.SetActive(false); // 조이스틱 UI 비활성화
    }
}

 

 

 

 

2.1 Animator용 Blend Tree 

: 여러 개의 애니메이션을 하나의 상태처럼 묶고, 파라미터 값에 따라 자연스럽게 섞어서 재생하는 구조

  • Animator → 오른쪽 클릭 → Create State → From New Blend Tree
1D 1개의 파라미터 기준으로 애니메이션 섞음 걷기 → 달리기
2D Simple Directional 2개의 파라미터 기준 (X, Y 방향) 상, 하, 좌, 우 이동 애니메이션
2D Freeform Cartesian 2D 평면 안에서 자연스럽게 블렌드 360도 방향 전환

 

=> 조이스틱 = 2D simple Directional = Joystick X + Joystick Y

  • Blend Tree 내부에서는 여러 애니메이션 사이를 ’선형 보간(Lerp)’으로 섞음
     → 애니메이션 개수가 많아질수록 중간 중간 상태가 세밀하게 표현됨 → 더 부드럽게 보임
  • Time Parameter = Blend Tree 전환 속도 제어 파라미터

 

 

2.2 조이스틱 , 블렌드 트리 이용 코드 

animator.SetFloat("파라미터명", 값); → Animator 안에 있는 Float 파라미터 값 설정
Blend Tree → 파라미터 연결 그 값으로 여러 애니메이션 사이를 부드럽게 섞음
using System;
using UnityEngine;

// 조이스틱으로 조작하는 기사 캐릭터 컨트롤러
public class KnightController_Joystick : MonoBehaviour
{
    private Animator animator; // 애니메이션 제어용 컴포넌트
    private Rigidbody2D knightRb; // 물리 이동용 Rigidbody2D

    private Vector3 inputDir; // 입력 방향 벡터
    [SerializeField] private float moveSpeed = 3f; // 이동 속도
    [SerializeField] private float jumpPower = 13f; // 점프 힘

    private bool isGround; // 땅에 닿아 있는지 여부

    void Start()
    {
        animator = GetComponent<Animator>(); // Animator 연결
        knightRb = GetComponent<Rigidbody2D>(); // Rigidbody2D 연결
    }

    void Update()
    {
        // 현재는 사용 안 함 → 점프 등 추가 입력 처리 가능
    }

    void FixedUpdate()
    {
        Move(); // 물리 이동 처리
    }

    // 바닥과 충돌 시 호출
    void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("Ground"))
        {
            animator.SetBool("isGround", true);
            isGround = true;
        }
    }

    // 바닥에서 떨어질 때 호출
    void OnCollisionExit2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("Ground"))
        {
            animator.SetBool("isGround", false);
            isGround = false;
        }
    }

    // 조이스틱으로 입력 전달 받는 메서드
    public void InputJoystick(float x, float y)
    {
        inputDir = new Vector3(x, y, 0).normalized; // 방향 벡터 정규화

        // 애니메이터에 입력 방향 전달 (Blend Tree 등 활용 가능)
        animator.SetFloat("JoystickX", inputDir.x);
        animator.SetFloat("JoystickY", inputDir.y);

        // 방향에 따라 캐릭터 좌우 반전 처리
        if (inputDir.x != 0)
        {
            var scaleX = inputDir.x > 0 ? 1 : -1;
            transform.localScale = new Vector3(scaleX, 1, 1);
        }
    }

    // 실제 물리 이동 처리
    void Move()
    {
        if (inputDir.x != 0)
            knightRb.linearVelocityX = inputDir.x * moveSpeed; // 커스텀 확장 메서드 사용 (linearVelocityX)
    }

    // 키보드 점프 처리 (조이스틱 이동 + 키보드 점프 혼합 사용 가능)
    void Jump()
    {
        if (Input.GetKeyDown(KeyCode.Space) && isGround)
        {
            animator.SetTrigger("Jump");
            knightRb.AddForceY(jumpPower, ForceMode2D.Impulse); // 커스텀 확장 메서드 사용 (AddForceY)
        }
    }
}
SetFloat("Speed", 값) → Blend Tree가 Idle → Walk → Run 자연스럽게 연결
SetFloat("JoystickX", 값) 좌/우 방향 Blend
SetFloat("JoystickY", 값) 위/아래 방향 Blend (예: 웅크리기, 점프 전환)

 

 

 

 

2.3 조이스틱 이미지

: Canvas 에 구현

Joystick 에 JoystickController.cs 넣고 UI 지정



 

Blend Tree 덕분에 애니메이션을 연속적으로 부드럽게 연결할 수 있었다. 이런 게임 엔진의 장점 덕분에 개발이 훨씬 수월해진다는 걸 체감했다. 앞으로는 AI 도움 받으면서 남는 시간에 개인 프로젝트도 병행해보고싶다. 내일은 공격과 콤보 로직을 다시 정리해서 완성도를 높여야겠다.

반응형
salmu
@salmu :: SMU 각종 기록

목차