This document is about: FUSION 1
SWITCH TO

수정중인 페이지 입니다.

Animations

Level 4

개요

Fusion 애니메이션 샘플에서는 Fusion을 사용하여 애니메이션 네트워킹을 처리하는 6가지 방법을 보여 줍니다.

Overview
Fusion의 애니메이션에 대한 소개 및 정확한 애니메이션 렌더링과 정확한 애니메이션 표시 간의 차이점은 다음Fusion 매뉴얼의 애니메이션 문서 페이지를 참조하십시오.

예제 1에서 5는 렌더링 정확 방법을 사용하는 반면, 예제 6은 틱 정확 접근 방식을 사용합니다. 각 예제는 다리 및 팔 히트 박스를 약 1초 간격으로 그려 서버 캐릭터와 프록시 캐릭터 간의 정밀도를 보여줍니다. 애니메이션 정밀도는 게임이 지연 보상을 사용할 때 특히 중요합니다.

Hitboxes

다운로드

버전 릴리즈 일자 다운로드
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개 버튼). 이렇게 하면 편집기에서 상태 권한, 입력 권한 및 프록시 결과를 보고 비교할 수 있습니다.

Start

제어

모든 예제에서는 세 가지 애니메이션 상태만 사용합니다. 유휴 애니메이션은 기본적으로 플레이되며 위쪽 화살표 키를 누르면 캐릭터 실행 애니메이션이 시작되고 스페이스 키를 누르면 점프 애니메이션이 트리거 됩니다.

여러 피어를 사용하는 동안 Num 0, 1, 23 키를 사용하여 피어 간을 전환할 수 있습니다. 또는 Runner Visibility Controls 창(맨 위 메뉴 Fusion > Windows > Runner Visibility Controls)에서 피어를 전환할 수 있습니다.

애니메이션 정밀도 이해

피어 간의 정확한 애니메이션 동기화는 정확한 지연 보상과 같은 특정 게임 애플리케이션에 중요할 수 있습니다. 애니메이션이 완벽하게 동기화되면 한 클라이언트에서 인식되는 히트도 서버에서 인식되어 플레이어 환경이 좋아집니다. 물론 이것은 캐릭터 히트 박스가 애니메이션의 영향을 받는 경우에만 적용됩니다. Fusion 매뉴얼에서 중요한 개념이 자세히 설명된 애니메이션 페이지를 확인합니다.

모든 예제는 로컬 플레이어에서 볼 수 있는 다리 및 팔 히트 박스의 예상 위치(프록시* 캐릭터의 히트 박스는 파란색으로 표시됨)와 서버에 나타날 때(녹색으로 표시됨)를 보여줍니다. 애니메이션 정밀도가 높을수록 박스가 더 가깝게 정렬됩니다.

Hitboxes
노트: 틱 정확 솔루션(예 6)을 사용하면 완벽하고 가장 안정적인 애니메이션 정밀도를 달성할 수 있지만, 올바르게 설정하고 유지 관리하기가 가장 복잡하다는 큰 단점이 있습니다. 시작하기 전에 렌더링 그리고 틱 정확 애니메이션 솔루션 사이의 차이점을 이해해야 합니다.

히트 박스 드로잉은 플레이어 프리팹에 배치된 HitboxDraw 스크립트로 수행됩니다. 차이를 더 잘 비교하기 위해 히트 박스는 50개의 틱(약 1초)으로 그려집니다.

HitboxDraw

프록시 객체 = 입력 권한(로컬 플레이어가 제어하지 않음) 또는 상태 권한(인스턴스는 네트워크 상태에 대한 권한(일반적으로 서버의 인스턴스)이 없는 네트워크 객체 인스턴스입니다. 간단히 말해, 클라이언트로 플레이할 때, 프록시 캐릭터는 플레이어가 볼 수 있는 다른 플레이어입니다.

시뮬레이션 네트워크 조건

애니메이션 정밀도를 높이기 위한 일부 변경 사항(예: 보간 된 데이터 사용)은 네트워크 상태가 좋지 않을 때 더 잘 나타납니다. 이러한 조건을 신속하게 시뮬레이션하기 위해 Clumsy와 같은 도구를 사용할 수 있습니다. 상세 내용은 네트워크 조건 시뮬레이션을 참고하세요.

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);
}
Example
노트: 다른 두 클라이언트가 가입한 후 시작할 때 이동 애니메이션이 어떻게 동기화되지 않을 수 있는지 주목하십시오. 이는 애니메이션 시간이 동기화되지 않아 상태 권한의 캐릭터가 이미 몇 초 동안 애니메이션을 플레이하고 있음에도 불구하고 모든 클라이언트에서 애니메이션이 0부터 플레이되기 시작하기 때문입니다. 이 문제는 다음 애니메이션 작업(예: 점프)에서 자동으로 수정되지만, 이러한 동작이 허용되지 않을 경우 애니메이션 시간 동기화가 필요합니다(예 3 참조).

예제 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);
}
Example
많은 프로젝트에서 보간기를 사용하는 것이 불필요한 복잡성이 될 수 있으며 예제 1의 솔루션은 충분한 결과를 산출할 수 있기 때문에 게임의 정확도 향상을 통해 이점을 얻을 수 있습니다.

보간 된 데이터와 최신 데이터를 비교하기 위해 플레이어 컴포넌트에 간단한 확인란이 있습니다. Player_AnimatorInterpolated 프리팹 및 보간 사용을 해제합니다. 두 개의 추가 클라이언트로 게임을 시작하고, 불량 네트워크(Clumsy - 지연 100ms, 20% 감소)를 시뮬레이션한 후 차이를 비교합니다.

예제 3 - 애니메이터를 가진 상태 동기화

정확한 접근 방식 렌더링

이 예에서는 현재 플레이어의 애니메이터 상태와 시간을 주기적으로 동기화하는 특수 컴포넌트 AnimatorStateSync를 추가합니다. 상태 동기화는 플레이어가 게임에 참여한 후 또는 프록시 객체가 관심 영역에 진입한 후에도 프록시 애니메이션이 동기화되도록 합니다.

Example

상태 동기화는 장시간 실행되는 애니메이션(예: 이동)이나 렌더 정확한 접근 방식으로 발생할 수 있는 실수를 수정하는 데 특히 중요할 수 있습니다.

예제: 로컬 플레이어가 게임에 참여하면 원격 플레이어는 이미 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);
}
Example

예제 5 - Network FSM with Animancer

정확한 접근 방식 렌더링

이 예에서는 인기 있는 타사 애니메이션 자산 Animancer을 사용하며 이 샘플에서만 현재 미리 보기에 있는 네트워크 FSM 추가 기능입니다. Animancer는 FSM 없이도 첫 번째 예와 유사한 방식으로 사용할 수 있습니다.

유의사항: Animancer는 Kybernetik이 개발, 유지 및 지원하는 타사 Unity 에셋입니다. 작성 시 Fusion과 함께 사용할 수 있습니다. Photon은 즉시 사용 가능한 Animancer-Fusion 통합을 제공하지 않습니다.
Example

네트워크 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 부모 상태에서 제어되는 점프, 랜드와 같은 상태를 가진 항공기일 수 있습니다. 이러한 분리는 여러 상태의 복잡한 애니메이션 설정을 제어할 때 유용합니다.

노트: 이 예에서는 자식 시스템을 보여주지 않지만 기본적으로 원하는 부모 상태의 OnCollectChildStateMachines 메소드에서 자식 시스템을 제공한 다음 상태 시스템을 정상적으로 제어하기에 충분합니다.

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 애니메이션 컨트롤러는 실험 상태이며 웹 문서가 부족합니다. 이해를 위해서는 중간 코딩 기술이 필요합니다.

Fusion Animation Controller는 유니티의 하위 레벨Playables API 위에 직접 구축된 틱 정확 애니메이션 솔루션입니다

게임에서 사용하기 전에 사용자 지정 애니메이션 솔루션의 제한 사항을 이해해야 합니다. 틱 정확한 애니메이션에 대한 자세한 내용은 애니메이션 문서를 참조하십시오.
Example

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을 참조하십시오

타사 에셋

애니메이션 샘플에는 각 제작자가 제공하는 여러 에셋이 포함되어 있습니다. 각 사이트에서 자체 프로젝트에 대해 전체 패키지를 구입할 수 있습니다:

중요: 상업적인 프로젝트에서 그것들을 사용하려면, 각 제작자로부터 라이선스를 구매해야 합니다.

Back to top