使用Photon引擎进行unity网络游戏开发(四)——Photon引擎实现网络游戏逻辑

使用Photon引擎进行unity网络游戏开发(四)——Photon引擎实现网络游戏逻辑

网络游戏逻辑处理与MasterClient

网络游戏逻辑处理:

方法一:编写Photon服务器与客户端程序

客户端传递数据之服务器,服务器完成逻辑判断,并将结果返回给客户端
enter description here

方法二:编写客户端程序

游戏逻辑在客户端处理,photon服务器只负责客户端之间数据验证和传递
enter description here

Master Client

  • 使用客户端处理网络游戏逻辑时,必须保证游戏房间内只有一个客户端处理网络游戏逻辑,我们选择某个客户端来网络处理游戏逻辑
  • 这个客户端根据其他客户端发送的数据,处理网络游戏逻辑。之后,将处理结果发送给所有客户端同步

PUN Master Client

在PUN的客户端Client中,包含一个MasterClient,我们使用MasterClient来处理网络游戏逻辑

  • MasterCIient是PUN里一个特殊的客户端,每个游戏房间Room有且仅有一个MasterClient
  • MasterCIient拥有比一般客户端更高的权限,包括将其它客户端踢出游戏房间、管理网络游戏场景对象等
  • MasterClient离开房间后,GameServer会自动选择ID最小的客户端作为MasterCIient
  • 使用PhotonNetwork.isMasterCIient判断本地客户端是否为MasterCIient

玩家对象生成

Photon中生成玩家对象需要调用下面方法实例化。

  • ReSourcesPrefabName:需要实例化Prefab在resources文件下下名称
  • Position:需要实例化对象的出生点
  • Quaternion:需要实例化对象的旋转信息
  • Group:编组信息,方便区分各个对象,如区分出我方和敌方 PhotonNetwork.Instantiate("ReSourcesPrefabName",Position,Quaternion, Group)
    例如:
    //生成玩家对象
    void InstancePlayer()
    {
        playerCustomProperties = PhotonNetwork.player.CustomProperties;
        if (playerCustomProperties["Team"].ToString().Equals("Team1"))
        {
            localPlayer = PhotonNetwork.Instantiate("MyPlayer",
                TeamOneSpTrans[(int)playerCustomProperties["TeamNum"]].position, Quaternion.identity, 0);
        }
        //如果玩家属于队伍2,生成RobotPlayer对象
        else if (PhotonNetwork.player.CustomProperties["Team"].ToString().Equals("Team2"))
        {
            localPlayer = PhotonNetwork.Instantiate("MyPlayer",
                TeamTwoSpTrans[(int)playerCustomProperties["TeamNum"]].position, Quaternion.identity, 0);
        }

        localPlayer.name = PhotonNetwork.player.NickName;
    }

游戏对象状态同步

位置朝向信息同步

方法一:通过将Transfrom组件拖到PhotonView组件上的observed componentS属性上。该方式尽管会传输对象的位置旋转信息,但是由于通信间隔的存在,导致对象运动不连续

方法二:使用PhotonTransformView实现玩家位置与朝向的同步。

PhotonTransformView组件内置几种插值算法,可以使用内置插值方法实现玩家的平滑“移动。

方法三:使用OnPhotonSerializeView(PhotonStream,PhotonMessageInfo)方法同步

使用该方法时需自行处理位置和旋转的插值。

private void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)  
    {  
        if (stream.isWriting)  
        {  
            //We own this player: send the others our data  
            ...
            stream.SendNext(transform.position);  
            stream.SendNext(transform.rotation);  
        }  
        else  
        {  
            ...
            PlayerPosition = (Vector3)stream.ReceiveNext();  
            PlayerRotation = (Quaternion)stream.ReceiveNext();  
        }  
    }  

enter description here

enter description here

enter description here

enter description here

动画信息同步

方法一:针对使用Animator组件的动画,使用PhotonAnimatorView快速开发。

enter description here

方法二:使用OnPhotonSerializeView(PhotonStream,PhotonMessageInfo)方法同步。使用该方法将动画参数的值传递,来实现动画的同步,该方法对animation组件动画适用。

Animation动画:
如player有针对于其动画的控制脚本,通过Update函数中的playerState来判断动画表现,这里我们传递playerState来实现动画同步

private void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)  
    {  
        if (stream.isWriting)  
        {  
            //We own this player: send the others our data  
            ...
           stream.SendNext(player.playerState);  
        }  
        else  
        {  
            ...
           player.playerState = (PlayAnimation)stream.ReceiveNext(); ;  
        }  
    }  

Animator动画:
animator组件中通过各个参数来控制动画的分支走向,这里我们同步其参数来实现动画同步

private void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)  
    {  
        if (stream.isWriting)  
        {  
            //We own this player: send the others our data  
            ...
           stream.SendNext(ani.GetFloat("RunSpeed"));  	
		   stream.SendNext(ani.GetBool("isJump"));  
        }  
        else  
        {  
            ...
           ani.SetFloat("RunSpeed",(string)stream.ReceiveNext());
		   ani.SetBool("isJump",(bool)stream.ReceiveNext());
        }  
    }  
posted @ 2018-01-27 13:21  世纪末の魔术师  阅读(4130)  评论(0编辑  收藏  举报