ps:期末老师要求的一篇3000字的玩具级别论文,基本是官网和api手册原本就有的。基本我就是个搬运工,不知道有什么用,就先扔上来了。用的是writage,让word转为markdown,可能会出现一些排版或者字体上的错误。
Photon在unity中的应用
摘要:本文主要介绍了一款实时Socket开发插件,服务端可以架构在windows平台上,也可以使用PunCloud服务进行直接使用,同时也介绍了Photon插件的api以及类。并在本文中使用unity游戏引擎开发网络多人游戏,在此利用Photon在unity的接口,快速开发一款多人网络游戏。
关键词:photon unity 多人网络游戏
unity与Photon
unity介绍
Unity 是一款由 Unity Technologies 所研发的跨平台2D / 3D 游戏引擎,可用于开发
Windows、MacOS 及 Linux 平台的单机游戏,PlayStation、XBox、Wii、3DS 和
任天堂Switch 等游戏主机平台的视频游戏,以及 iOS、Android 等移动设备的游戏。Unity
所支持的游戏平台还延伸到了基于 WebGL 技术的 HTML5 网页平台,以及 tvOS、Oculus
Rift、ARKit 等新一代多媒体平台。除可以用于研发电子游戏之外,Unity
还是被广泛用于建筑可视化、实时三维动画等类型互动内容的综合型创作工具。Unity3D是由Unity
Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。
Photon全称Photon Unity
Networking(PUN),是使用于unity引擎中的一个插件。在unity中使用Photon可以使玩家进入同步的对战房间。并且可以通过分析自己的需求进行自定义属性。还可以通过Photon
Cloud进行快速,可靠的连接。由于Photon
Cloud是通过Photon服务器来进行的。属于C-S结构,而非P2P结构。开发者无需了解Photon的源代码。Photon封装了三层Api。最高层是Photon的源代码,该层实现了Unity中的基础功能,比如RPC,网络对象等。第二层包括了处理服务器,匹配,回调等逻辑。最底层有链接库文件组成,其中包含放序列化,网络协议等。现在从个人开发到大型游戏的开发中,都可以见到Photon引擎的身影。世界上多个知名的游戏公司和工作室都选用Photon作为网络支持引擎。其中包括WB华纳,Codemaster,2K,Glu,微软工作室,SQUARE
ENIX,万代南梦宫等。并且也有许多新创企业也在采用Photon作为他们自己的网络支持引擎。
Photon和Unity NetWorking的区别
Unity
NetWorking基于C-S,服务器通过和Unity客户端进行消息传递。而Photon也是基于C-S,不过有一个专门服务器,不会因主机断开连接而连接中断。
Unity
NetWorking使用Nat穿透,由玩家自行搭建服务器。可能会因防火墙等问题导致连接不上。而Photon有一个专门的服务器,不需要借助Nat穿透的方式。可以保证连接的可靠性。
Photon与Photon性能差距不大,但由于Unity服务器是玩家自行搭建的。一般来说Photon的服务器会更好些。
在unity中网络维护的优先级并不高,很少有功能改进,错误修正也很少。而Photon积极维护可用的源代码,此外Photon提供Unity
NetWoring没有的功能,比如内置的负载均衡,和离线模式。
Api模块中最常用的应该是Pun类,Photon由各种各样的模块组成,有一些是公共的,有一些是Photon内部框架使用的。
常见的类都列举在下列中
定义了OnPhotonSerializeBView方法
这个接口是PUN所有回调方法的定义。
这个类提供了一个photonView和所有PUN可调用的事件。
一个包含特点消息,RPC或跟新信息的容器类
该容器用于OnPhotonSerializeView()函数中。
PhotonNetwork的主类。
玩家类,通过actorID验证玩家身份
PUN的NetworkView的替代类,可以像NetWorkView类一样使用。
房间属性的类,与RoomInfo相反,Room类的属性是可以改变的。
房间属性的类。属性不可以被更改
Photon在unity中的简单使用
下载Photon和Appid
在unity中使用Photon是一件非常简单的事情,只需要在unity商城中搜索Pun,即可下载Photon。或者也可以从官网上下载,然后导入新的项目中。
接着在官网上通过邮箱注册一个Photon Cloud账号,将账号中的AppId复制到PUN
Setup上。如果是想自己搭建一个服务器可以选择跳过注册Photon Cloud。
如果使用Photon Cloude只需在项目中PhotonServerSetting设置相关选项。Photon
Cloud会根据启动时ping通所有区域来获取一个低延迟的服务器。结果将会保存在PlayerPrefs中。如果不想自动设置。你还可以自行设置可连接的区域。如果你不想使用这样的自动连接也是可以的。Photon提供了PhotonNetwork.ConnectUsingSettings()方法。通过PhotonNetwork.ConnectToMaster()方法来手工连接到任意一个你自己所拥有的服务器上。
Pun使用一个C-S结构。拥有一个或者多个主服务器。服务器管理不同的客户端,并在进行多人游戏的时候提供一个服务器地址。
Pun中匹配以房间为单位,每一个房间都是独立的,并且有属于自己的ID。而大厅是包含多个房间的对象。大厅的可选用的。
默认情况下,Pun会加入默认的大厅,大厅会向客户端发送现有的房间列表。可以使用PhotonNetWork.GetRoomList()方法来获取列表
还可以使用PhotonNetwork.autoJoinLobby = false
自动加入房间。而PhotonNetWork.JoinLobby是一个加入特定大厅的方法。使用JoinRoom,JoinRadomRoom和CreatRoom中的一个参数可以是无需选择大厅就加入房间。
要使用PhontonNetwork功能以下代码是必须的
PhotonNetWork.ConnectUsingSettings(“v1.0”);
这行代码设置游戏客户端版本以及使用安装向导。另外使用Connect()方法连接服务器时你可以忽略PhontonServerSetting文件。
现在我们用一些代码来展示一下Photon的操作
PhotonNetwork.JionRoom(roomname); \\加入房间
PhotonNetwork.CreatRoom(roonName); \\ 创建房间
PhotonNetWork.JionRandomRoom(); [\\随机加入房间](file:///\随机加入房间)
Foreach(RoomInfo game in PhotonNetWork.GetRoomList()){ //在大厅中显示房间列表
GUILayout.Label(game.name+ ” “ + game.playerCount + “/” + game.maxPlayer)}
之后我们还可以设置房间属性,,房间属性时同步到所有房间里的玩家上。并且跟踪当前信息,比如回合数,开始时间。这些信息被当作以字符串为键值的散列表处理。可以在创建房间的时候会定义这些房间属性。比如
Hashtable roomProps= new Hashtable() = new Hashtable (){{“map”,1}};
//房间属性哈希表
String[] roomProsInLobbt = {“map”,”ai”}; //房间属性字符串
RoomOptions roomOptions = new RoomOptions(){customRoomProperties =
roomProps,customRoomPropertiesForLobby = roomPropsInLobby} //房间选项
CreateRoom(roomName,roomOptions,TypedLobby.Default) //创建房间
Photon还使用回调让你知道游戏中的状态变化,比如加入游戏或者是退出游戏。通常unity是在MonoBehaviour中实现。而Photon建议直接继承PunBehaviour来代替MonoBehaviour,这样可以很容易的重写回调函数。
接着介绍一下PhotonView,PhotonView是用于发送消息的脚本组件,PhotonView和unity自带的NetworkView十分相似。 要在游戏中发送消息或者是实例化PhotionView,确保游戏中必须有一个PhotonView。为了同步Position或者是Rotation我们还需要TransformView,TransformView可以选择同步物体的Position,Rotation或者Scale。一个PhotonView可以用来同步一个MonoBehaviour,在这种情况下OnPhotonSerializeView方法会被调用,这个方法可以根据是否是本地玩家来读写一个对象。
如果需要调用同房间的远程客户端中MonoBehaviour中的某个方法,我们可以使用RPCs来实现。要调用这个MonoBehaviour中的方法。必须在个游戏对象上实例一个PhotonView,来调用标记功能。
[PunRPC]
Void RpcFun(string s){
Debug.Log(“hell,I am RpcFun”); }
想要调用这个函数,我们需要一个PhotonView对象,使用Get(this)的方法获取PhotonView组件。然后在调用RPC。如下列代码
PhotonView photonView.Get(this); //获取PhotonView
photonView.RPC(“RpcFun”,PhotonTargets.ALL,”jup”,”and jup”);
在每一场游戏中我们需要为每一个玩家实例化一个甚至多个的玩家对象。我们可以使用PhotonNetwork.Instantiate方法来实例化一个对象。实例化的对象必须要提前制作成预制体,放在Resources文件夹下。用以下代码可以直接自动实例化
PhotonNetWork.Instantiate(“MyPrefabName”,new
Vector3(0,0,0),Quaternion.identity,0);
如果不依赖Resoures文件夹中的对象,则可以手动初始化。如果要手动生成的话,需要自己指定一个PhotonViewID。PhotonViewID是网络消息确定对象的关键。可以使用PhotonNetwork.AllocateViewID()方法分配一个新的ViewID。
Photon还支持离线模式,离线模式的特点是在没有网络环境的情况下也可以使用网络环境的代码。离线模式的主要目的是在使用PhotonNetwork功能并且在未联网时杜绝空引用或者是其他错误,并且在运行游戏时,这些代码是可以复用。
只要设置PhotonNetwirk.offlineMode = ture ;便可以很简单启用离线模式。
在PhotonNetwork中api最多支持1000个PhotonView和2147483个玩家。PhotonViews为每一个网络消息发出ViewID。ViewID是一个整数类型,他由玩家ID和玩家视图ID组成。
一个整形的上限为2147483647,除以我们最多支持的1000个PhotonView,可以发现这已经允许超过200万的玩家。显而易见的你可以减少PhotonView的数量进行增加玩家数量。相反也是一样。
在Photon中可以还添加了PhotonStatsGui组件,能够简单的添加一个在运行时跟踪网络活动的Gui。使用方法及其简单,只需要添加PhotonStatsGui到任意层级的游戏对象上就可以。不过有几个配置需要说明一下
Message Statistics 信息统计,会记录任何操作,响应。显示的输入输出的总计数。
Traffic Statistics 流量统计,这会记录网络数据包。
Health Statistics 健康统计,记录 客户端性能。
参考文献:
[1]
Photon官网https://doc.photonengine.com/zh-tw/pun/v2/getting-started/pun-intro