如何在统一多人游戏中控制静态对象的动画过渡

问题描述 投票:0回答:1

我想要在一个多人游戏环境中的静态对象的动画,当玩家点击它时需要发生。并且动画将显示连接到服务器的每个玩家

public class AnimationCtr : NetworkBehaviour 
{

    Animator anim;
    bool canSpawn;

    int count;
    [SyncVar]
    bool flag;

    // Use this for initialization
    void Start () 
    {
        anim = GetComponent<Animator>();
        flag = false;
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, 100.0f))
            {
                if (hit.transform.gameObject.name.Equals("door") && (!flag))
                {
                    // anim.SetInteger("btnCount", 2);
                    Debug.Log(hit.transform.gameObject.name);
                    anim.SetInteger("btnCount", 2);
                    flag = true; 
                }
                else if (hit.transform.gameObject.name.Equals("door")&& (flag))
                {
                    anim.SetInteger("btnCount", 3);
                    flag = false;
                }
            }
        }
    }
}
unity3d animation multiplayer unity3d-unet
1个回答
1
投票

一个问题是你不能在客户端设置[Synvar]

来自[SyncVar] docu

这些变量的值将从服务器同步到客户端

我也只会让服务器决定flag的当前值是true还是false

public class AnimationCtr : NetworkBehaviour 
{

    Animator anim;
    bool canSpawn;

    int count;
    // no need for sync ar since flag is only needed on the server
    bool flag;

    // Use this for initialization
    void Start () 
    {
        anim = GetComponent<Animator>();
        flag = false;
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (!Physics.Raycast(ray, out hit, 100.0f)) return

            if (!hit.transform.gameObject.name.Equals("door")) return;

            // only check if it is a door
            // Let the server handel the rest
            CmdTriggerDoor();
        }
    }

    // Command is called by clients but only executed on the server
    [Command]
    private void CmdTriggerDoor()
    {
        // this will only happen on the Server

        // set the values on the server itself

        // get countValue depending on flag on the server
        var countValue = flag? 3 : 2;
        // set animation on the server
        anim.SetInteger("btnCount", countValue);
        // invert the flag on the server
        flag = !flag;

        //Now send the value to all clients
        // no need to sync the flag as the decicion is made only by server
        RpcSetBtnCount(countValue);
    }

    // ClientRpc is called by the server but executed on all clients
    [ClientRpc]
    private void RpcSetBtnCount(int countValue)
    {
        // This will happen on ALL clients

        // Skip the server since we already did it for him it the Command
        // For the special case if you are host -> server + client at the same time
        if (isServer) return;

        // set the value on the client
        anim.SetInteger("btnCount", countValue);
    }
}

但是,如果您只想打开或关闭门的动画,我宁可使用bool parameter,例如在isOpenanimator而只是改变它(animator.SetBool())。并在两种状态之间进行两次转换:

Default -> State_Closed   -- if "isOpen"==true  --> State_Open
                          <-- if "isOpen"==false --

在您的动画中,您只需保存1个具有目标位置的单个关键帧。在转换过程中,您可以设置转换持续时间 - >打开/关闭门需要多长时间(它们甚至可以不同)。

© www.soinside.com 2019 - 2024. All rights reserved.