이번엔 이벤트 상호작용을 만들 것이다.

발자국이 특정 이벤트 존에 도달하게 되면 이벤트가 진행된다.
우선 만들어본 이벤트는 애니메이션 이벤트로 만들어 봤다.
만들면서 배운 Timeline을 사용하여 만들어주었다.
EventZone
이벤트의 트리거 역할을 한다.
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
public class EventZone : MonoBehaviour
{
private PlayableDirector myDirector;
private void Awake()
{
myDirector = GetComponent<PlayableDirector>();
}
private void OnTriggerEnter2D(Collider2D collision)
{
FootPrint footPrint = collision.GetComponent<FootPrint>();
if (footPrint != null)
{
Debug.Log("Foot in Event Area");
EventManager.Instance.StartEvent(myDirector);
}
}
// 자신의 이벤트 종료
public void MyEventFinish()
{
EventManager.Instance.FinishEvent();
Destroy(gameObject);
}
}
발자국이라는 컴포넌트를 가진 오브젝트와 부딧혔을 때, 자신의 타임라인 이벤트를 이벤트 매니저에 넘겨준다.
MyEventFinish함수에서 이벤트 매니저에게 이벤트의 종료를 알리고, 삭제한다. (1회성 이벤트)
FootPrint
충돌 확인을 위해 넣은 스크립트
using UnityEngine;
public class FootPrint : MonoBehaviour
{
}
왼쪽,오른쪽의 발자국에 넣어준다.
GameManager
게임의 여러 상태를 관리하는 게임매니저를 미리 만들어준다.
using UnityEngine;
public class GameManager : Singleton<GameManager>
{
// 이벤트 상태
public enum EventState
{
NORMAL,
EVENT,
}
public EventState eventState { get; private set; } = EventState.NORMAL;
protected override void Awake()
{
base.Awake();
}
public void SetEventState(EventState state)
{
eventState = state;
}
}
지금은 이벤트상태인지 아닌지만 확인하기 위해 EventState만 만들어 준다.
(싱글톤은 나중에 설명)
EventManager
이벤트를 관리하는 매니저 컴포넌트
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
public class EventManager : Singleton<EventManager>
{
protected override void Awake()
{
base.Awake();
// director = GetComponent<PlayableDirector>();
}
// 이벤트 시작
public void StartEvent(PlayableDirector director)
{
GameManager.Instance.SetEventState(GameManager.EventState.EVENT);
director.Play();
}
// 이벤트 종료
public void FinishEvent()
{
GameManager.Instance.SetEventState(GameManager.EventState.NORMAL);
Debug.Log("이벤트 끝");
}
}
타임라인을 실행하기 위해 자신의 PlayableDirector를 가져와 넣어준다.
StartEvent에서 이벤트를 실행한다. 먼저 게임의 상태를 이벤트중으로 변경해주고, 받아온 타임라인을 실행할 타임라인에 넣어준 이후 실행한다.
FinishEvent에서 게임의 상태를 다시 기본적인 상태로 바꿔준다.
타임라인 만들기
프로젝트에서 타임라인을 생성하거나, 타임라인을 생성할 오브젝트를 클릭후 Create를 눌러준다.

이후 Event Area 오브젝트를 만들어주고, Playable Director를 넣어준다.
Playable에는 생성한 타임라인을 넣어주고, 활성상태 재생은 해제한다.

이후 타임라인에서 여러 오브젝트를 변형해가며 애니메니션을 만들어준다. (Animation Track)
이때, 이동하는 오브젝트의 경우, Animator 컴포넌트가 필요하다.
이벤트가 끝이 날때는 Signal Track으로 종료를 알린다. 때문에 Event Area에는 Singal Receiver라는 컴포넌트가 필요한다.
이후
애니메이션의 특수환경
이 게임에서 발자국이 끊기면서 애니메이션이 되게끔, 노드사이의 자연스러운 이동을 없앨 것이다.
양쪽 탄젠트의 일정을 눌러 부드러운 움직임을 제거한다.

https://docs.unity3d.com/Packages/com.unity.timeline@1.8/manual/curves-tangents.html
테스트

완성본

시스템 아키텍처


제네릭 싱글톤
이 게임에서는 제네릭 싱글톤을 만들것이다.
제네릭 싱글톤이란, 싱글톤을 사용하는 컴포넌트의 부모 클래스를 제네릭으로 만들어, 일일이 싱글톤을 만들지 않아도, 상속만 받게되면 싱글톤이 완성되는 패턴이다.
Singleton
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T instance;
public static T Instance
{
get { return instance; }
}
protected virtual void Awake()
{
if (instance == null)
{
instance = this as T;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
Singleton이라는 클래스를 만들고, 제네릭을 사용해준다. <T>
제네릭의 T는 아무 변수가 들어갈수 있지만 제약을 걸어주기위해 where이라는 예약어를 사용해준다.
where T : MonoBehaviour의 경우, 상속받는 컴포넌트는 유니티 컴포넌트(유니티 기능을 사용하는 컴포넌트)로 제약을 걸어준다.
이후 T라는 변수로 instance를 만들어 주고, 싱글톤과 똑같이 처리한다.
이렇게 제네릭 싱글톤을 작성하고 나면 싱글톤을 사용하는 다른 클래스에서 더 수월하게 사용할 수 있다.
기본적인 사용방법
using UnityEngine;
public class GameManager : Singleton<GameManager>
{
protected override void Awake()
{
base.Awake();
}
}
Singleton을 상속받고 제네릭에는 자신의 클래스를 넣어준다.
virtual 함수인 Awake를 재정의를 통해 부모클래스의 함수를 사용한다.
'GameDev > Step of Love' 카테고리의 다른 글
| Step of Love 카메라 제어 (0) | 2026.05.28 |
|---|---|
| Step of Love 달리기 시스템 (0) | 2026.05.27 |
| Step of Love - NavMesh (1) | 2026.05.25 |
| Step of Love 스토리텔링 (0) | 2026.05.24 |
| Step of Love - 발자국 시스템 (0) | 2026.05.24 |