반응형
[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 도움 받으면서 남는 시간에 개인 프로젝트도 병행해보고싶다. 내일은 공격과 콤보 로직을 다시 정리해서 완성도를 높여야겠다.
반응형
'프로그래밍 > 유니티 부트캠프' 카테고리의 다른 글
| 유니티(Camera Follow / 표지판 팝업 UI 인터랙션/ 씬 내부 맵 이동/타이핑 코루틴) _ 멋쟁이사자처럼 유니티 부트캠프 후기 29회차 (0) | 2025.06.27 |
|---|---|
| 유니티(콤보 공격 구현, 타일맵 Props 실습) _ 멋쟁이사자처럼 유니티 부트캠프 후기 28회차 (1) | 2025.06.26 |
| 유니티(게임수학_외적내적/ 타일 생성 포탑 설치 실습 / 조이스틱구현1) _ 멋쟁이사자처럼 유니티 부트캠프 후기 26회차 (0) | 2025.06.23 |
| 유니티(몬스터 공격 실습/아이템획득/게임수학/터렛회전) _ 멋쟁이사자처럼 유니티 부트캠프 후기 25회차 (2) | 2025.06.23 |
| 유니티(상속/인터페이스 연습/layer) _ 멋쟁이사자처럼 유니티 부트캠프 후기 24회차 (0) | 2025.06.18 |