Animations
개요
Fusion 애니메이션 샘플에서는 Fusion을 사용하여 애니메이션 네트워킹을 처리하는 6가지 방법을 보여 줍니다.
예제 1에서 5는 렌더링 정확 방법을 사용하는 반면, 예제 6은 틱 정확 접근 방식을 사용합니다. 각 예제는 다리 및 팔 히트 박스를 약 1초 간격으로 그려 서버 캐릭터와 프록시 캐릭터 간의 정밀도를 보여줍니다. 애니메이션 정밀도는 게임이 지연 보상을 사용할 때 특히 중요합니다.
다운로드
버전 | 릴리즈 일자 | 다운로드 | |
---|---|---|---|
1.1.6 | Jul 11, 2023 | Fusion Animations 1.1.6 Build 211 |
폴더 구조
프로젝트는 6개의 소규모 독립 예제로 구성됩니다.
/01_AnimatorSimple | 예제 1 - 애니메이터를 가진 네트워크 된 상태 |
/02_AnimatorInterpolated | 예제 2 - 애니메이터가 있는 보간 된 네트워크 상태 |
/03_AnimatorStateSync | 예제 3 - 애니메이터와의 상태 동기화 |
/04_NetworkMecanimAnimator | 예제 4 - 네트워크 메카님 애니메이터 |
/05_AnimancerFSM | 예제 5 - Animancer가 있는 네트워크 FSM |
/06_FusionAnimationController | 예제 6 - Fusion 애니메이션 컨트롤러 |
/Common | 모든 예제에 대한 프리팹, 스크립트 및 공통 머터리얼 |
/ThirdParty | 타사 에셋 (모델, 애니메이션, Animancer 라이트) |
방법
게임 시작하기
각 예제에는 열고 플레이할 수 있는 고유한 씬 파일이 있습니다. 또는 시작 씬에서 모든 예제를 시작할 수 있습니다
시연을 위해 호스트 + 클라이언트 2개가 포함된 다중 피어 모드가 권장됩니다(호스트 시작 + 클라이언트 2개 버튼). 이렇게 하면 편집기에서 상태 권한, 입력 권한 및 프록시 결과를 보고 비교할 수 있습니다.
제어
모든 예제에서는 세 가지 애니메이션 상태만 사용합니다. 유휴 애니메이션은 기본적으로 플레이되며 위쪽 화살표 키를 누르면 캐릭터 실행 애니메이션이 시작되고 스페이스 키를 누르면 점프 애니메이션이 트리거 됩니다.
여러 피어를 사용하는 동안 Num 0, 1, 2 및 3 키를 사용하여 피어 간을 전환할 수 있습니다. 또는 Runner Visibility Controls 창(맨 위 메뉴 Fusion > Windows > Runner Visibility Controls)에서 피어를 전환할 수 있습니다.
애니메이션 정밀도 이해
피어 간의 정확한 애니메이션 동기화는 정확한 지연 보상과 같은 특정 게임 애플리케이션에 중요할 수 있습니다. 애니메이션이 완벽하게 동기화되면 한 클라이언트에서 인식되는 히트도 서버에서 인식되어 플레이어 환경이 좋아집니다. 물론 이것은 캐릭터 히트 박스가 애니메이션의 영향을 받는 경우에만 적용됩니다. Fusion 매뉴얼에서 중요한 개념이 자세히 설명된 애니메이션 페이지를 확인합니다.
모든 예제는 로컬 플레이어에서 볼 수 있는 다리 및 팔 히트 박스의 예상 위치(프록시* 캐릭터의 히트 박스는 파란색으로 표시됨)와 서버에 나타날 때(녹색으로 표시됨)를 보여줍니다. 애니메이션 정밀도가 높을수록 박스가 더 가깝게 정렬됩니다.
히트 박스 드로잉은 플레이어 프리팹에 배치된 HitboxDraw
스크립트로 수행됩니다. 차이를 더 잘 비교하기 위해 히트 박스는 50개의 틱(약 1초)으로 그려집니다.
프록시 객체 = 입력 권한(로컬 플레이어가 제어하지 않음) 또는 상태 권한(인스턴스는 네트워크 상태에 대한 권한(일반적으로 서버의 인스턴스)이 없는 네트워크 객체 인스턴스입니다. 간단히 말해, 클라이언트로 플레이할 때, 프록시 캐릭터는 플레이어가 볼 수 있는 다른 플레이어입니다.
시뮬레이션 네트워크 조건
애니메이션 정밀도를 높이기 위한 일부 변경 사항(예: 보간 된 데이터 사용)은 네트워크 상태가 좋지 않을 때 더 잘 나타납니다. 이러한 조건을 신속하게 시뮬레이션하기 위해 Clumsy와 같은 도구를 사용할 수 있습니다. 상세 내용은 네트워크 조건 시뮬레이션을 참고하세요.
예제 1 - 애니메이터를 가진 네트워크 된 상태
정확한 접근 방식 렌더링
이 예제에서는 최신 네트워크 상태를 사용하여 애니메이터 매개 변수를 제어하는 가장 간단한 솔루션을 보여 줍니다.
일반적으로 이미 존재하는 네트워크 상태(예: _controller.Speed
)를 사용하여 애니메이션을 제어할 수 있습니다. 렌더 정확한 애니메이션은 렌더 메소드의 네트워크 데이터 또는 OnChanged
콜백을 기반으로 설정됩니다.
C#
private CharacterController _controller;
private Animator _animator;
public override void Render()
{
if (_lastVisibleJump < _controller.JumpCount)
{
_animator.SetTrigger("Jump");
}
_lastVisibleJump = _controller.JumpCount;
_animator.SetFloat("Speed", _controller.Speed);
}
예제 2 - 애니메이터가 있는 보간 된 네트워크 상태
정확한 접근 방식 렌더링
이 예제는 최신 예제와 달리 보간 된 네트워크 데이터를 사용하여 이전 예제에서 한 단계 업그레이드한 것입니다. 보간 된 데이터를 사용하면 애니메이션을 보다 정확하게 만들 수 있으며 네트워크 조건이 이상적이지 않은 경우에도 이 정밀도를 유지할 수 있습니다(네트워크 조건 시뮬레이션 섹션 참조).
C#
private CharacterController _controller;
private Animator _animator;
public override void Render()
{
int jumpCount = _useInterpolation == true ? _controller.InterpolatedJumpCount : _controller.JumpCount;
if (_lastVisibleJump < jumpCount)
{
_animator.SetTrigger("Jump");
}
_lastVisibleJump = jumpCount;
float speed = _useInterpolation == true ? _controller.InterpolatedSpeed : _controller.Speed;
_animator.SetFloat("Speed", speed);
}
보간 된 데이터와 최신 데이터를 비교하기 위해 플레이어 컴포넌트에 간단한 확인란이 있습니다. Player_AnimatorInterpolated 프리팹 및 보간 사용을 해제합니다. 두 개의 추가 클라이언트로 게임을 시작하고, 불량 네트워크(Clumsy - 지연 100ms, 20% 감소)를 시뮬레이션한 후 차이를 비교합니다.
예제 3 - 애니메이터를 가진 상태 동기화
정확한 접근 방식 렌더링
이 예에서는 현재 플레이어의 애니메이터 상태와 시간을 주기적으로 동기화하는 특수 컴포넌트 AnimatorStateSync
를 추가합니다. 상태 동기화는 플레이어가 게임에 참여한 후 또는 프록시 객체가 관심 영역에 진입한 후에도 프록시 애니메이션이 동기화되도록 합니다.
상태 동기화는 장시간 실행되는 애니메이션(예: 이동)이나 렌더 정확한 접근 방식으로 발생할 수 있는 실수를 수정하는 데 특히 중요할 수 있습니다.
예제: 로컬 플레이어가 게임에 참여하면 원격 플레이어는 이미 10초 동안 실행 애니메이션을 수행하고 있습니다. 그러나 애니메이션 시간이 동기화되지 않으면 로컬 플레이어 시스템의 프록시 캐릭터가 처음부터 실행 중인 애니메이션을 시작하기 때문에 애니메이션 타이밍이 달라집니다. 다음 애니메이션 작업(예: 점프)에서는 타이밍이 자동으로 수정되지만, 그때까지는 애니메이션이 동기화되지 않습니다.
예제 4 - 네트워크 메카님 애니메이터
정확한 접근 방식 렌더링
네트워크 메카님을 통한 애니메이션 동기화를 위한 간단한 솔루션 Fusion SDK와 함께 제공되는 NetworkMecanimAnimator
(NMA) 컴포넌트입니다.
Network Mecanim Animator는 보간 된 네트워크 데이터를 사용하지 않으므로 애니메이션 정밀도는 예제 3의 솔루션에서 가능한 것보다 낮습니다. NMA는 기존 네트워크 데이터를 사용하지 않고 현재 Animator 매개 변수를 자체 네트워크 데이터 구조체에 복사하므로 동기화된 매개 변수가 많이 변경되는 경우 대역폭 집약도가 높아집니다.
네트워크 메카님 애니메이터에 대한 자세한 내용은 애니메이션 설명서를 참조하십시오.
C#
private CharacterController _controller;
private NetworkMecanimAnimator _networkAnimator;
public override void FixedUpdateNetwork()
{
if (IsProxy == true)
return;
if (Runner.IsForward == false)
return;
if (_controller.HasJumped == true)
{
_networkAnimator.SetTrigger("Jump", true);
}
_networkAnimator.Animator.SetFloat("Speed", _controller.Speed);
}
예제 5 - Network FSM with Animancer
정확한 접근 방식 렌더링
이 예에서는 인기 있는 타사 애니메이션 자산 Animancer을 사용하며 이 샘플에서만 현재 미리 보기에 있는 네트워크 FSM 추가 기능입니다. Animancer는 FSM 없이도 첫 번째 예와 유사한 방식으로 사용할 수 있습니다.
네트워크 FSM을 사용하려면 게임 객체에 StateMachineController
컴포넌트를 배치해야 하며, 상태 머신을 유지하고 IStateMachineOwner
인터페이스를 구현하는 사용자 스크립트(예: Player)가 필요합니다. 그러면 StateMachineController
가 필요한 데이터를 모든 피어에 자동으로 동기화하고 등록된 컴퓨터를 업데이트합니다.
C#
public class Player : NetworkBehaviour, IStateMachineOwner
{
private PlayerBehaviourMachine _fullBodyMachine;
void IStateMachineOwner.CollectStateMachines(List<IStateMachine> stateMachines)
{
var states = GetComponentsInChildren<PlayerStateBehaviour>();
var animancer = GetComponentInChildren<AnimancerComponent>();
_fullBodyMachine = new PlayerBehaviourMachine("Full Body", _controller, animancer, states);
stateMachines.Add(_fullBodyMachine);
}
}
애니메이션은 상태 변화에 따라 플레이됩니다. 상태는 StateBehaviour
스크립트가 연결된 플레이어 계층의 객체(예: 점프 상태, 이동 상태)이거나 State
스크립트(이 예에서는 표시되지 않음)에서 상속되는 일반 클래스인 단일 플레이어 동작을 나타냅니다.
C#
public override void FixedUpdateNetwork()
{
if (IsProxy == true)
return;
if (_controller.HasJumped == true)
{
_fullBodyMachine.TryActivateState<PlayerJumpState>();
}
}
C#
public class PlayerJumpState : PlayerStateBehaviour
{
[SerializeField]
private ClipTransition _jumpClip;
protected override void OnEnterStateRender()
{
Animancer.Play(_jumpClip);
}
protected override void OnFixedUpdate()
{
if (Machine.StateTime >= _jumpClip.Length * _jumpClip.Speed)
{
// Jump animation should be finished, let's leave this state
Machine.TryDeactivateState(StateId);
}
}
}
상위 상태에서 제어되는 하위 상태 시스템(하위 시스템)을 생성하여 HFSM(계층적 유한 상태 시스템)을 효과적으로 생성할 수 있습니다. 예를 들어, 하위 머신은 Airborne 부모 상태에서 제어되는 점프, 폴 및 랜드와 같은 상태를 가진 항공기일 수 있습니다. 이러한 분리는 여러 상태의 복잡한 애니메이션 설정을 제어할 때 유용합니다.
Network FSM은 기본적으로 보간 된 데이터를 기반으로 프록시에서 상태를 전환하고 현재 상태 시간(Machine.StateTime
)을 제공합니다. 렌더 호출에서 확인할 때도 보간 됩니다. 이를 통해 많은 노력 없이 미세한 애니메이션 정밀도를 보장합니다.
C#
public class PlayerLocomotionState : PlayerStateBehaviour
{
[SerializeField]
private LinearMixerTransition _moveMixer;
protected override void OnEnterStateRender()
{
Animancer.Play(_moveMixer);
// Update the animation time based on the state time
_moveMixer.State.Time = Machine.StateTime;
}
protected override void OnRender()
{
_moveMixer.State.Parameter = Controller.InterpolatedSpeed;
}
}
예제 6 - Fusion 애니메이션 컨트롤러
틱 정확 방법론
Fusion Animation Controller는 유니티의 하위 레벨Playables API 위에 직접 구축된 틱 정확 애니메이션 솔루션입니다
Mecanim과 마찬가지로 애니메이션 컨트롤러는 Animation Layers와 함께 작동합니다. 모든 계층에는 하나 이상의 애니메이션 상태가 포함됩니다. 레이어와 상태는 모두 객체 계층의 객체로 간단히 표시됩니다(Player_FusionAnimationController
프리팹 참조). 애니메이션은 애니메이션 컨트롤러 컴포넌트를 통해 코드에서 제어됩니다.
C#
private CharacterController _controller;
private PlayerLocomotionState _locomotionState;
private PlayerJumpState _jumpState;
public override void FixedUpdateNetwork()
{
if (IsProxy == true)
return;
if (_controller.HasJumped == true)
{
_jumpState.Activate(0.15f);
}
else if (_jumpState.IsPlaying() == false || _jumpState.IsFinished(-0.15f, false) == true)
{
_locomotionState.Activate(0.15f);
}
}
Fusion 애니메이션 컨트롤러는 BR200에 사용된 애니메이션 컨트롤러의 개선된 버전입니다. 따라서 보다 정교한 애니메이션 예제는 BR200을 참조하십시오
타사 에셋
애니메이션 샘플에는 각 제작자가 제공하는 여러 에셋이 포함되어 있습니다. 각 사이트에서 자체 프로젝트에 대해 전체 패키지를 구입할 수 있습니다:
- Kybernetik의 Animancer LITE
중요: 상업적인 프로젝트에서 그것들을 사용하려면, 각 제작자로부터 라이선스를 구매해야 합니다.
Back to top