대마법사(진) 2025. 5. 26. 23:43

Photon Fusion으로 멀티플레이 상황에서 애니메이션을 동기화 해보자

Trouble Shooting

 

애니메이션이 동기화 되지않는 모습

 

문제 상황 : 플레이어 에게는 애니메이션이 정상작동하지만 상대방의 입장에서는 애니메이션이 작동하지않는다.

 

해당 코드

private static readonly int HashIsWalk = Animator.StringToHash("isWalk");
private static readonly int HashIsRun = Animator.StringToHash("isRun");
private static readonly int HashX = Animator.StringToHash("x");
private static readonly int HashY = Animator.StringToHash("y");

 public override void FixedUpdateNetwork()
 {
     if (!HasInputAuthority) return;

     float horizontal = Input.GetAxis("Horizontal");
     float vertical = Input.GetAxis("Vertical");

     float mouseX = Input.GetAxis("Mouse X");
     float mouseY = Input.GetAxis("Mouse Y");

     Vector3 move = new Vector3(horizontal, 0, vertical);
     Vector3 rot = new Vector3(mouseX, 0, mouseY);


     UpdateRunState();
     Move(move);
     Rotate(rot);
     Jump();
 }
 
 //이동 
private void Move(Vector3 dir)
{
    float h = dir.x;
    float v = dir.z;

    bool isMoving = h != 0 || v != 0;

    if (isRunning)
        anim.SetBool(HashIsRun, isMoving);
    else
    {
        anim.SetBool(HashIsWalk, isMoving);
        anim.SetBool(HashIsRun, false);
    }
    float forwardMoveSpeed = isRunning ? forwardRunSpeed : forwardSpeed;
    Vector3 movement = transform.forward * v * forwardMoveSpeed + transform.right * h * sideSpeed;

    controller.Move(movement * Time.deltaTime);

    anim.SetFloat(HashX, h);
    anim.SetFloat(HashY, v);
}

 

위와같이 코드를 짰을때 이동하는것은 멀티로 구현이 되길래 당연히 애니메이션도 같은 방식으로 될줄알았다.

하지만 애니메이션은 조금 다르다.

 

응 달라

우선 코드에 잘못된점이 좀 있다.

 

1. 애니메이션 관련 변수가 [Networked] Attribute를 사용하지 않았다.

2. 애니메이션 관련 코드가 Render() 에서 사용되지 않았다.

3. HasInputAuthority가 False면 실행되지 않는다. (음 이건 사실 잘모르겠어서 확인해봐야할듯 수저예정)



아래는 수정된 코드이다.

//Networked를 사용하고 전역변수로 변경
[Networked] float h { get; set; }
[Networked] float v { get; set; }
[Networked] bool isMoving { get; set; }
[Networked] private bool isRunning { get; set; } = false;

public override void FixedUpdateNetwork()
{
    if (HasInputAuthority)
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = Input.GetAxis("Mouse Y");

        Vector3 move = new Vector3(horizontal, 0, vertical);
        Vector3 rot = new Vector3(mouseX, 0, mouseY);


        UpdateRunState();
        Move(move);
        Rotate(rot);
        Jump();
    }    
}

private void Move(Vector3 dir)
{
    h = dir.x;
    v = dir.z;
    isMoving = h != 0 || v != 0;

    float forwardMoveSpeed = isRunning ? forwardRunSpeed : forwardSpeed;
    Vector3 movement = transform.forward * v * forwardMoveSpeed + transform.right * h * sideSpeed;

    controller.Move(movement * Time.deltaTime);
    //FixedUpdateNetwork에서 애니메이션을 실행하지않는다.
    
}

//Render를 Override하여 애니메이션을 실행한다.
public override void Render()
{
    ApplyAnimation();
}
private void ApplyAnimation()
{
    if (isRunning)
        anim.SetBool(HashIsRun, isMoving);
    else
    {
        anim.SetBool(HashIsWalk, isMoving);
        anim.SetBool(HashIsRun, false);
    }

    anim.SetFloat(HashX, h);
    anim.SetFloat(HashY, v);
}

애니메이션에 사용될 Float 변수를 전역변수로 빼주고 Attribute 를 부여해주었다.

Render를 오버라이드하여서 해당 함수내에서 애니메이션을 실행하였다.

 

 

수정후 실행

 

 

음 상대방한테도 애니메이션이 잘 보인다.

 

(따봉 두개드립니다.)


자 그럼이제 Docs를 읽어봅시다.

(순서가 굉장히 잘못되었지만..)

https://doc.photonengine.com/ko-kr/fusion/current/concepts-and-patterns/animation

 

Fusion 2 - 애니메이션 | Photon Engine

애니메이션은 플레이어 입력에 의해 유도되는 움직임 및 동작과 같은 중요한 게임 플레이 피드백을 플레이어에게 제공합니다. 이 문서에서는 Fusion으로 멀티플레이어 게임을 만들 때 적합한 애

doc.photonengine.com

흠... 읽어보면 Render가 아닌 FixedUpdateNetwork() 에서 애니메이션을 실행하여도 되어야할것같은데.. 되지는않는다.