게임 개발 공부 기록

25일차 - PenguinRun 팀 프로젝트 3

00lwt 2025. 2. 26. 21:20

▶▷ PenguinRun

오늘은 애니메이터와 각종 스크립트 연결 및 플레이어 관련 자잘한 오류들을 수정하였다.

 

애니메이터

달리기 게임이기 때문에 시작부터 Move 상태이고 화살표는 상태 전환을 위한 트랜지션이다.

하나의 애니메이션이 다 끝나지 않아도 다른 애니메이션으로 전환될 수 있도록 트랜지션들의 HasExitTime의 체크를 풀어주었고 컨디션 부분에는 각종 bool 및 trigger형 파라미터를 넣어 정상적으로 전환되도록 하였다.

 

AnimationHandler

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnimationHandler : MonoBehaviour
{
    // 애니메이터 파라미터 이름을 해시값으로 변환 (문자열 비교 비용 절감)
    private static readonly int IsMoving = Animator.StringToHash("IsMoving");
    private static readonly int IsDamage = Animator.StringToHash("IsDamage");
    private static readonly int IsSliding = Animator.StringToHash("IsSliding");
    private static readonly int IsJumping = Animator.StringToHash("IsJumping");
    private static readonly int IsInvincibility = Animator.StringToHash("IsInvincibility");

    private Animator animator;

    private void Awake()
    {
        animator = GetComponentInChildren<Animator>();
    }

    // 이동 애니메이션
    public void Move()
    {
        animator.SetBool(IsMoving, true);
    }

    /// <summary>
    /// 점프 애니메이션
    /// true면 점프 애니메이션을 활성화하고 이동 애니메이션을 비활성화
    /// false면 점프 애니메이션을 비활성화하고 이동 애니메이션을 활성화
    /// </summary>
    /// <param name="ju">점프 여부</param>
    public void SetJump(bool ju)
    {
        if (ju)
        {
            animator.SetBool(IsJumping, true);
            animator.SetBool(IsMoving, false);
        }
        else
        {
            animator.SetBool(IsJumping, false);
            animator.SetBool(IsMoving, true);
        }
    }

    /// <summary>
    /// 슬라이딩 애니메이션
    /// true이면 슬라이딩 애니메이션을 활성화하고 false이면 비활성화
    /// </summary>
    /// <param name="sl">슬라이딩 여부</param>
    public void Slide(bool sl)
    {
        animator.SetBool(IsSliding, sl);
    }

    // 데미지 애니메이션
    public void Damage()
    {
        animator.SetTrigger(IsDamage);
    }

    /// <summary>
    /// 무적 상태 애니메이션
    /// true면 무적 애니메이션 활성화, false면 일반 상태
    /// </summary>
    /// <param name="inv">무적 상태 여부</param>
    public void Invincibility(bool inv)
    {
        animator.SetBool(IsInvincibility, inv);
    }
}

 

애니메이션 핸들러에서는 각 애니메이션의 실행을 담당한다. 스탯 핸들러와 플레이어 컨트롤러에서 bool형 매개변수를 통해 값을 전달하면 해당 값에 따라 애니메이션을 활성화, 비활성화 한다.

 

 

▶▷ 트러블 슈팅

막히는 부분

1. 애니메이터에서 애니메이션 간의 전환이 정상적으로 이루어지지 않는 현상

2. 애니메이션 핸들러 복잡도 상승

3. 슬라이딩 시 애니메이션이 돌아가는 현상

4. 타일맵의 옆이나 아래에 닿아도 점프 카운트가 초기화 되어 벽을 타고 올라오거나 타일맵 아래에서 윗부분 충돌로 생존 가능한 현상

 

원인 

1. 부모 오브젝트와 자식 오브젝트에 애니메이터 컴포넌트가 둘 다 할당되어 있었음

2. 점프, 슬라이딩, 무적 등의 애니메이션을 해제하는 메소드를 별도로 만들어 메소드의 개수가 너무 늘어나게됨

3. 기존의 오브젝트를 90도 눕히는 방식으로 슬라이딩을 진행해서 애니메이션 또한 회전

4. 태그를 지정하고 콜라이더 충돌하는 방식으로 변경한 부분이 원인

 

 

해결

1. 부모 오브젝트에서 애니메이터를 제외하고 SpriteRenderer 컴포넌트가 있는 자식 오브젝트에 할당하여 해결

2. 메소드에 bool 매개변수를 추가하여 하나의 메소드 안에서 활성화, 비활성화를 모두 관리하여 해결

3. 회전 방식을 제거 후 자식 오브젝트를 두개 생성해서 상체와 하체 부분의 콜라이더를 나누어 슬라이딩 시 상체의 콜라이더를 비활성화하여 해결

4. 기존의 아래로 향하는 레이캐스트로 바닥을 탐지하는 방식으로 다시 수정하여 해결

 

▶▷ 알게된 점

오브젝트를 인스펙터에서 직접 할당하지 않고 스크립트에서 동적으로 찾는 방법

게임 오브젝트를 참조하는 변수 선언 후 Awake()나 Start()에 transform.Find("오브젝트 명")?.gameObject; 작성