트랜스폼 트윈 트랙 샘플

이 트랙은 두 점 간의 간단한 트랜스폼 이동에 사용할 수 있습니다.
사용법
이 트랙은 간단한 트랜스폼 이동에 사용할 수 있습니다. 모든 이동은 직선상에서 일어나지만, 속도는 애니메이션 커브로 제어할 수 있습니다. 트윈 트랙은 이동하려는 씬 Transform에 바인딩됩니다.
| 필드 | 설명 |
|---|---|
| Start Location | 플레이어블이 시작할 때 이동하는 트랜스폼의 포지션 및/또는 회전을 표시하는 씬 내 트랜스폼에 대한 레퍼런스입니다. null로 설정하면, 플레이어블이 시작할 때 이동하는 트랜스폼의 포지션/회전이 사용됩니다. |
| End Location | 플레이어블이 끝날 때 이동하는 트랜스폼의 포지션 및/또는 회전을 표시하는 씬 내 트랜스폼에 대한 레퍼런스입니다. |
| Tween Position | 트랜스폼의 포지션을 변경해야 하는지 여부입니다. |
| Tween Rotation | 트랜스폼의 회전을 변경해야 하는지 여부입니다. |
커스텀 클립 워크플로 예제
이 예제는 다음에 대한 방법을 보여줍니다.
- 커스텀 클립, 트랙 및 믹서를 만듭니다.
- PlayableGraph API를 사용하여 오브젝트의 트랜스폼을 애니메이션화합니다.
ClipEditor를 사용하여 클립을 커스터마이즈합니다.
1. 커스텀 클립
타임라인이 재생을 시작하면 Playable이라는 노드가 생성됩니다. 이 노드는 PlayableGraph라는 트리 구조로 구성되어 있습니다. 각 프레임에 대해 타임라인은 이 그래프를 샘플링하여 여러 데이터 소스(애니메이션, 오디오 등)를 읽고 믹싱합니다.
커스텀 클립 생성의 첫 단계는 그래프에 추가될 새 PlayableBehaviour를 정의하는 것입니다. 이는 트랜스폼 트윈을 구현하는 데 필요한 데이터를 저장해야 합니다.
public class TweenBehaviour : PlayableBehaviour
{
public Transform startLocation;
public Transform endLocation;
public bool shouldTweenPosition;
public bool shouldTweenRotation;
public AnimationCurve curve;
}
PlayableBehaviour의 데이터는 직렬화되지 않으며, 부모 그래프가 삭제되면 손실됩니다. 이 데이터를 저장하기 위한 다음 단계는 새 PlayableAsset을 정의하는 것입니다.
[Serializable]
public class TweenClip : PlayableAsset
{
public ExposedReference<Transform> startLocation;
public ExposedReference<Transform> endLocation;
public bool shouldTweenPosition = true;
public bool shouldTweenRotation = true;
public AnimationCurve curve;
//...
}
참고: 클립은 시작과 끝 위치를 저장해야 합니다. 에셋은 씬 오브젝트를 직접 참조할 수 없으므로, 트랜스폼 오브젝트를 직접 저장할 수 없습니다. 바로 이러한 이유로 ExposedReference<Transform>을 사용합니다.
PlayableAsset의 주요 목적은 PlayableBehaviour를 빌드하는 것이며, 이는 CreatePlayable 메서드를 통해 수행됩니다.
public class TweenClip : PlayableAsset
{
//...
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
// create a new TweenBehaviour
ScriptPlayable<TweenBehaviour> playable = ScriptPlayable<TweenBehaviour>.Create(graph);
TweenBehaviour tween = playable.GetBehaviour();
// set the behaviour's data
tween.startLocation = startLocation.Resolve(graph.GetResolver());
tween.endLocation = endLocation.Resolve(graph.GetResolver());
tween.curve = curve;
tween.shouldTweenPosition = shouldTweenPosition;
tween.shouldTweenRotation = shouldTweenRotation;
return playable;
}
}
CreatePlayable은 TweenClip의 데이터를 사용하여 새 TweenBehaviour를 초기화합니다.
2. 커스텀 트랙
커스텀 트랙은 TrackAsset 서브 클래스를 정의하여 생성합니다. 다음 속성을 TrackAsset에 추가할 수 있습니다.
- TrackBindingType: 트랙에 바인딩해야 하는 오브젝트 타입을 정의합니다.
- TrackClipType: 트랙에 연결해야 하는 클립 타입을 정의합니다.
이 예의 경우 트랙에는 Transform 오브젝트 바인딩이 필요하며, 이전에 1단계에서 정의한 TweenClip 타입의 클립만 허용할 수 있습니다.
[TrackBindingType(typeof(Transform))]
[TrackClipType(typeof(TweenClip))]
public class TweenTrack : TrackAsset
{
// ...
}
데이터 설정이 완료되었습니다. 이제 TweenTrack 및 TweenClip을 타임라인에 추가할 수 있습니다.

하지만 트랜스폼 트윈은 아직 구현되지 않았습니다. 이를 위해서는 트랙 믹서가 필요합니다.
3. 트랙 믹서 정의
두 클립 간의 블렌딩 또는 크로스페이딩을 올바르게 처리하려면 트랙 믹서가 필요합니다. 트랙 믹서는 모든 클립 데이터에 액세스하고 그러한 데이터를 함께 블렌딩하는 PlayableBehaviour입니다.
트랙 믹서 설정
기본적으로 트랙이 타임라인에 추가되면, 빈 플레이어블이 생성되고 각 클립의 플레이어블에 연결됩니다.
예를 들어 이 트랙은 다음을 수행합니다.

다음 플레이어블 그래프를 생성합니다.

Timeline: 이 플레이어블은 플레이어블root입니다. 트랙과 연결된 모든 플레이어블은 이 노드에 연결됩니다.Playable: 이 플레이어블은 트랙 믹서를 나타냅니다. 트랙 믹서가 정의되지 않았으므로 빈 트랙 믹서가 생성됩니다.TweenBehaviour: 이 플레이어블은 클립을 나타냅니다. 클립당 하나씩 생성됩니다. 모든 클립 플레이어블은 트랙 믹서에 연결됩니다.
커스텀 트랙 믹서를 정의하려면 새로운 PlayableBehaviour를 정의해야 합니다.
public class TweenMixerBehaviour : PlayableBehaviour {}
그런 다음 TrackAsset에서 CreateTrackMixer 메서드를 사용하여 커스텀 트랙 믹서를 지정할 수 있습니다.
public class TweenTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
return ScriptPlayable<TweenMixerBehaviour>.Create(graph, inputCount);
}
}
이제 플레이어블 그래프는 다음과 같은 모습입니다.

클립 플레이어블을 서로 연결하는 데 사용되었던 빈 플레이어블이 이제 TweenMixerBehaviour로 대체됩니다.
트랜스폼 트윈 구현
트랜스폼 트윈의 구현은 TweenMixerBehaviour의 ProcessFrame 메서드에 상주합니다. 다음은 해당 구현의 주요 단계입니다.
- 초기화: 타임라인이 처음 재생될 때 트랙 바인딩의 초기 트랜스폼을 가져옵니다. 시작 또는 끝 트랜스폼이
null이면 초기 트랜스폼이 대신 사용됩니다. - 클립 동작 및 가중치 가져오기: 적절하게 블렌딩하려면 믹서가 모든 입력(클립)에 대한 정보를 요청해야 합니다.
// Iterate on all the playable's (mixer) inputs (ie each clip on the track)
int inputCount = playable.GetInputCount();
for (int i = 0; i < inputCount; i++)
{
// get the input connected to the mixer
Playable input = playable.GetInput(i);
// get the weight of the connection
float inputWeight = playable.GetInputWeight(i);
// get the clip's behaviour
TweenBehaviour tweenInput = GetTweenBehaviour(input);
}
- 계산 및 블렌딩: 리니어 보간을 사용하여 두 점 간의 트랜스폼을 계산합니다.
- 결과 적용: 계산이 완료되면 트랙 바인딩 오브젝트에 트랜스폼이 작성됩니다.
// Apply the final position and rotation values in the track binding
trackBinding.position = accumPosition + m_InitialPosition * (1.0f - totalPositionWeight);
trackBinding.rotation = accumRotation.Blend(m_InitialRotation, 1.0f - totalRotationWeight);
4. 클립의 형상 커스터마이즈
ClipEditor를 사용하여 에디터의 클립 기능을 강화할 수 있습니다. 이 에디터는 커스텀 인스펙터 역할을 합니다. 즉 CustomTimelineEditor 속성을 사용하여 타임라인에 ClipEditor 클래스를 특정 클립에 연결해야 함을 알릴 수 있습니다.
[CustomTimelineEditor(typeof(TweenClip))]
public class TweenClipEditor : ClipEditor
{
//...
}
DrawBackground 메서드를 사용하여 클립의 형상을 커스터마이즈할 수 있습니다.
public override void DrawBackground(TimelineClip clip, ClipBackgroundRegion region)
{
TweenClip asset = clip.asset as TweenClip;
if (asset == null)
return;
// Drawing code here...
}
참고
- 커브의 (0,1) 사이의 부분만 사용됩니다.
- 클립이 종료되면 트랙에 바인딩된 오브젝트가 원래 포지션으로 돌아갑니다.