Part 1 - Lobby 第一章 大厅
Animator教程是一个基于Unity3D的教程。它将向您展示如何开发由Photon Cloud提供支持的支持多人游戏的应用程序,以及如何使用Animator为角色动画制作角色。
Connection to Server, Room Access and Creation
连接到服务器,访问和创建房间
首先,让我们先来解决本教程的核心问题,能够连接到Photon Cloud服务器并加入一个房间,或者根据需要创建一个房间。
1.创建一个新的场景,并保存为Launcher.unity。
2.创建一个新的C#脚本,名字叫:Launcher。
3.在Hierarchy中创建一个名为Launcher的空GameObject
4.将c#脚本附加到GameObject的属性栏内。
5.编辑c#脚本,使其内容如下。
编码提示:推荐你别直接复制粘贴,因为教程里面的代码如果你自己输入的,你可能会记得更牢,理解的更好。动手是最好的学习方法,记住空谈误国也误人啊!
因为不放心,所以,我不顾千万人的劝阻还是在这里代码做成了图片,逼着你动手实践,也许是最好的办法了吧:
保存,脚本。
让我们来看一下,截至目前为止的这个脚本中的内容,首先从一个一般的Unity脚本开始,然后看看我们所做的PUN特定的调用。
Namespace: 命名空间
虽然不是强制性的,但为脚本提供适当的命名空间可以防止与其他的脚本之开发人员发生冲突。如果另一个开发人员创建一个Launcher类会有什么发生? Unity会报错,你或那个开发者谁先使用了这个类,或者职位高,或者说服能力强,另外那个倒霉蛋就将不得不重命名Unity的类才能被允许执行。
如果冲突来自您从资源商店下载的资源,这可能会非常棘手。现在,Launcher类实际上是Com.MyCompany.MyGame.launcher ,别人也使用这个完全相同的Namespace实际上几率是很低的,所以使用这种公司名和游戏名为命名空间,会使你的代码安全、组织清晰。Com.MyCompany.MyGame应该被你自己的公司名和游戏名称取代,记住这是很好的习惯。当然具有雄心的你肯定也在想自己的公司名吧,那在这个教程里你就不用藏着掖着了,尽情的使用吧。
MonoBehaviour类
请注意,我们正在使用MonoBehaviour类来派生我们的类,从本质上讲我们的类变成了一个Unity组件,然后我们可以把它放到一个GameObject或Prefab上。一个扩展MonoBehaviour的类可以访问许多非常重要的方法和属性。在本例中,我们将使用两个回调方法,Awake()和Start()。
PhotonNetwork.autoJoinLobby
在Awake()中,我们将PhotonNetwork.autoJoinLobby设置为false,因为我们不需要大厅功能,我们只需要获取现有房间的列表。这通常是一个强制设置的好主意,因为实际上在同一个项目中,你可能有另外一个想要自动加入大厅的场景,所以在同一个项目中这两种情况使用不同的方法都没有问题。
PhotonNetwork.ConnectUsingSettings()
在Start()中,我们使用PhotonNetwork.ConnectUsingSettings()将公共函数Connect()连接到PUN Cloud。注意代表您的游戏版本的the_game版本变量。您应该将其设置为“1”,直到您需要对已经存在的项目进行重大更改。这里要记住的重要信息是PhotonNetwork.ConnectUsingSettings()是您的游戏联网并连接到Photon Cloud的起点。
PhotonNetwork.automaticallySyncScene
我们的游戏将有一个基于玩家数量的可调整的竞技场,为了确保每个连接的玩家的加载场景相同,我们将使用Photon提供的非常方便的功能:PhotonNetwork.automaticallySyncScene。当其值为 ture时,MasterClient可以调用PhotonNetwork.LoadLevel(),所有连接的玩家将自动加载相同的场景,此时,您可以保存启动场景并打开PhotonSettings(从Unity菜单窗口/ Photon Unity Networking / Highlight Photon服务器设置中选择它),我们需要将调试日志设置为Full,如下所示:
PhotonSettings 调试级别设置
然后我们可以点击Play。您应该在Unity控制台中看到好几十个日志。专门查看“Connected to masterserver.”日志。它表明我们已经连接完毕,并准备加入一个房间的日志输出。
总是测试失败的可能性是我们编码时的好习惯。在这里,我们假设电脑连接到互联网,但如果电脑没有连接到互联网会发生什么?让我们来试试。关闭电脑的互联网并播放场景。你应该在Unity控制台中看到一个错误"Connect() to 'ns.exitgames.com' failed: System.Net.Sockets.SocketException: No such host is known"
理想情况下,我们在编写脚本的时候应该意识到这个问题,并对这些情况作出优雅的反应,并做出一个响应式的体验,不管出现什么样的情况或问题都进行处理避免程序的崩溃。
现在,让我们来处理这两种情况,并在我们的Launcher脚本中通知我们确实已经连接或不连接到PUN服务器。这将是PUN回调的完美介绍。
PUN CallBacks PUN 回调
PUN的回调非常灵活,并提供了三种非常不同的实现方式。为了学习,我们将涵盖所有三种方法,并根据情况选择最适合的方法。
"Magic" Methods 魔法方法
当使用普通的MonoBehaviour时,实际上可以简单地创建私有方法
这是个魔法方法,因为任何MonoBehaviour都可以实现这个方法或任何其他来自PUN的消息。它遵循相同的原则就跟Unity本身的主要方法(如Awake()或Start())一样。但是我们不打算使用这个,因为如果你拼错了这些“魔法”方法,它不会告诉你什么相关的错误信息,所以这是一个非常快速和实用的实现方法,但只有当您确切知道每个方法的名称,非常熟悉并擅长调试技术能用来快速找到出现的问题再使用。
使用IPunCallbacks和IPunObservable接口
PUN提供了两个可以在你的类中实现的c#接口:IPunObservable和IPunCallbacks。
这是一种非常安全的方法来确保类符合接口的定义,但是它迫使开发者去实现所有的接口里面的方法的声明。最好的脚本编辑器(vs就不错)将使这个任务非常容易,如上面使用MonoDevelop时所示。然而,这个脚本最终会有很多可能用不着的方法,但是必须全部实现才行。(也挺烦的),在数据序列化的教程里面,我们还真的要使用IPunObservable接口。
Using Photon.PunBehaviour 使用自Photon.PunBehaviour的继承关系
最后一个技术(三个技术里面的),是我们经常使用的技术,也是最方便的技术。我们会从Photon.PunBehaviour派生类来取代从MonoBehaviour派生类,因为它拥有了我们使用的特定属性和使用的虚方法,方便重写。这是非常实用的,因为可以肯定,我们不会产生拼写错误,也不需要实现所有的方法。
注意:在重写时,大多数脚本编辑器会默认实现一个基本调用并自动填充,但在我们的教程下,不需要,因此Photon.PunBehaviour的一般规则是永远不会调用基本方法。
注意:重写的另一个好处是,只需将鼠标悬停在方法名称上,就可以从上下文的编辑器帮助里面获得方法名。
来,让我们实践下OnConnectedToMaster()和OnDisconnectedFromPhoton()回调
打开脚本编辑器,改 MonoBehaviour 为 Photon.PunBehaviour
在类的最后添加以下两个方法,在Photon.PunBehaviour CallBacks区域内添加。
现在,网络对我们来说已经不是问题了,因为联不联网都可以进入这个场景玩游戏啦,我们将在适当的步骤添加一些逻辑通知玩家是不是进入游戏。我们将在下一节开始构建UI的时候再讨论这个问题。现在我们将处理成功的连接:
所以,我们追加到OnConnectedToMaster()方法下面的调用:
正如注解所说,我们需要知道如果加入一个随机房间失败,在这种情况下,我们需要创建一个房间,所以我们在脚本中实现OnPhotonRandomJoinFailed()的PUN回调方法,并使用PhotonNetwork.CreateRoom()方法创建一个房间,你已经猜到了,相关的PUN回调函数OnJoinedRoom()会在我们有效的加入房间的时候通知你的脚本:
现在,如果你运行这个场景,你最终应该遵循连接到PUN的逻辑顺序,尝试加入现有的房间,否则创建一个房间并加入新创建的房间。
到本教程的这步,我们现在已经涉及到连接和加入房间的关键点,有那么一点不是很方便,而且需要早一些来解决。这些与学习PUN关系不大,不过从整体角度来看也是重要的。
在Unity Inspector中显示公开变量
您可能已经知道这一点,但是如果您还不知道,MonoBehaviours会自动将其公共属性公开给Unity Inspector。这是Unity中一个非常重要的概念,在我们的例子中,我们将修改我们定义日志级别的方式,并创建一个公共变量,以便我们可以在不触及代码本身的情况下进行设置。
在Awake()中我们将修改它如下:
所以,现在我们不强制脚本是某种类型的日志,我们只需要在Unity检查器中设置它,然后运行,不需要打开脚本就可以编辑它,保存它,等待统一重新编译并最终运行。这样做更有效率和灵活性
同样,我们也会为每个房间的最大玩家数量设置为公共属性。在代码中对代码进行硬编码并不是最好的做法,相反,让我们把它作为一个公共变量,以便我们以后可以实验和最终确定这个数字而不需要重新编译。
在类声明的开始处,在公共变量区域内,我们添加:
然后我们修改PhotonNetwork.CreateRoom(),并使用这个新的公共变量来代替之前使用的编码数字
本章到此结束。