zoukankan      html  css  js  c++  java
  • 使用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());
            }  
        }  
    
  • 相关阅读:
    (十)android项目中,通用布局的对话框的实现。
    devexpress控件layoutview特效之一旋转木马的实现
    devexpress设置皮肤、字体以及折叠菜单、伸缩Panel的实现
    devexpress设置系统全局字体(含工具栏字体)
    devexpress表格控件gridcontrol实现纵向标头
    中文繁简互换以及获取中文字符串首字母
    devexpress显示缓冲滚动条与实现类似QQ消息推送效果
    gridcontrol显示行号,总行,打印,导出Excel,设置标头及内容居中方法
    devexpress表格控件gridcontrol特殊应用(一)——实现禁用特定行(附源代码)
    devexpress表格控件gridcontrol设置隔行变色、焦点行颜色、设置(改变)显示值、固定列不移动(附源码)
  • 原文地址:https://www.cnblogs.com/Firepad-magic/p/8365619.html
Copyright © 2011-2022 走看看