Photon Unity Networking基础教程 2 Lo

作者: 浪尖儿 | 来源:发表于2016-10-24 09:59 被阅读521次

    Photon Unity Networking基础教程 2 Lobby UI

    这部分将会集中于给Lobby创建用户界面。这部分的内容非常基础,并且跟网络关系不大。

    主要内容

    • Play按钮
    • 玩家名字
    • 连接进度

    Play按钮

    目前我们的Lobby是把我们自动连接到一个房间,这是有益于早期测试,但我们想让用户选择是否以及何时开始游戏。 因此,我们将简单地提供一个Button。

    1. 打开场景Launcher
    2. 使用Unity菜单'GameObject/UI/Button'创建一个按钮,命名为Play Button,注意他在场景中创建了Canvas和EventSystem游戏对象,省了我们的事了,nice:)
    3. 编辑Play Button的Text值为“Play”
    4. 选择Play Button然后定位到按钮组建的On Click()部分
    5. 点击小的加号“+”添加一条
    6. 把Launcher对象从Hierachy面板中拖过来
    7. 在下拉列表中选择Launcher.connect()函数。我们现在把按钮和Launcher脚本连起来了,当用户点击按钮的时候,将会调用Launcher脚本的connect()函数
    8. 打开Launcher脚本
    9. 把Start()函数中的connect()函数删除
    10. 保存Launcher脚本和场景

    现在点击Play,你会发现需要点击按钮才能进行连接了。

    玩家名字

    典型游戏的另一个重要的最低要求是让用户输入他们的名字,以便其他玩家知道他们正在和谁玩。 我们将实现这个简单的任务,通过使用PlayerPrefs记住名字,以便当用户打开游戏,我们可以知道名字是什么。 要为您的游戏创建一个伟大的用户体验的话,这是一个非常方便和相当重要的功能。

    让我们先创建一个脚本来管理和记住玩家的名字,然后创建相关的UI。

    创建玩家名字输入框

    1. 创建一个新的C#脚本,命名为PlayerNameInputField

    2. 下面是脚本的全部内容,编辑然后保存

       using UnityEngine;
       using UnityEngine.UI;
       using System.Collections;
        
       namespace Com.MyCompany.MyGame
       {
           /// <summary>
           /// Player name input field. Let the user input his name, will appear above the player in the game.
           /// </summary>
           [RequireComponent(typeof(InputField))]
           public class PlayerNameInputField : MonoBehaviour
           {
               #region Private Variables        
        
               // Store the PlayerPref Key to avoid typos
               static string playerNamePrefKey = "PlayerName";         
        
               #endregion         
        
               #region MonoBehaviour CallBacks         
        
               /// <summary>
               /// MonoBehaviour method called on GameObject by Unity during initialization phase.
               /// </summary>
               void Start () {         
        
                   string defaultName = "";
                   InputField _inputField = this.GetComponent<InputField>();
                   if (_inputField!=null)
                   {
                       if (PlayerPrefs.HasKey(playerNamePrefKey))
                       {
                           defaultName = PlayerPrefs.GetString(playerNamePrefKey);
                           _inputField.text = defaultName;
                       }
                   }         
        
                   PhotonNetwork.playerName =  defaultName;
               }         
        
               #endregion         
        
               #region Public Methods                 
               /// <summary>
               /// Sets the name of the player, and save it in the PlayerPrefs for future sessions.
               /// </summary>
               /// <param name="value">The name of the Player</param>
               public void SetPlayerName(string value)
               {
                   // #Important
                   PhotonNetwork.playerName = value + " "; // force a trailing space string in case value is an empty string, else playerName would not be updated.         
        
                   PlayerPrefs.SetString(playerNamePrefKey,value);
               }         
        
               #endregion
           }
       }
      

    下面分析一下这个脚本:

    • RequireComponent(typeof(InputField))

    我们首先保证这个脚本必须InputField组件,这可以方便快捷的保证使用该脚本没有错误。

    • PlayerPrefs.HasKey(), PlayerPrefs.GetString() and PlayerPrefs.SetString()

    PlayerPrefs是一个简单的配对条目的查找列表(像一个excel表有两列),一个是键,一个是值。 Key是一个字符串,是完全任意的,你决定如何命名,你需要在整个开发过程中记住它。因此,有必要总是将PlayerPrefs键存储在一个地方,一个方便的方法是使用Static变量声明,因为它不会随着时间的推移在游戏过程中改变,并且每次都是相同的。

    所以,逻辑非常简单。如果PlayerPrefs有一个给定的键,我们可以得到它,并当我们要用的时候直接赋值。在我们的案例中,我们在启动时填充InputField时,在编辑过程中,我们把当前InputField的值设置给PlayerPref键,然后我们确定它被存储在用户设备上以供稍后检索(下一次用户打开此游戏)。

    • PhotonNetwork.playerName

    这是此脚本的要点,设置玩家在网络上的名称。 脚本在两个地方使用它,一次是在Start()中检查名称是否存储在PlayerPrefs中,一次是在公共方法SetPlayerName()中。 现在,没地方调用这个方法,我们需要绑定InputField OnValueChange()来调用SetPlayerName(),这样每次用户编辑InputField时,我们都会记录它。 我们可以做到这一点,只有当用户按下播放,这取决于你,但是这需要些更多的脚本,所以为了清楚起见让我们保持简单。 这也意味着,不管用户将做什么,输入将被记住,这通常是期望的行为。

    为玩家的名字创建UI

    1. 确保你打开的是Launcher场景
    2. 使用Unity菜单'GameObject/UI/InputField'创建InputField,命名为Name InputField
    3. 把RectTransform中的PosY值设置为35,它会在PlayButton的上面
    4. 定位到Name InputField的子对象PlaceHolder,设置它的文本值为"Enter your Name..."
    5. 选择Name InputField对象
    6. 把我们刚才创建的PlayerNamerInputField脚本给它加上
    7. 定位到InputField组件的On Value Change (String)部分
    8. 点击加号“+”添加一条
    9. 把PlayerNamerInputField拖拽到框里
    10. 下拉列表中选择PlayerNameInputField.SetPlayerName()
    11. 保存场景

    好了,你可以点击play运行,输入你的名字,然后停止play,再次点击play启动,你刚才输入的名字就会有了。

    我们实现了功能,然而在用户体验方面,我们缺少连接进度的反馈,还缺少当连接期间和加入房间时出现问题时的反馈。

    连接进度

    我们在这里尽量保持简单,隐藏名称字段和play按钮,并在连接期间将其替换为简单的文本“正在连接...”,并在需要时将其切换回来。

    为此,我们把播放按钮和名称字段做成一个组,以便我们只需要激活和停用该组。 后来更多的功能可以添加到组,它不会影响我们的逻辑。

    1. 确保你打开的是Launcher场景
    2. 使用unity菜单'GameObject/UI/Panel'创建UI面板,命名为Control Panel
    3. 删除Control Panel的Image和Canvas Renderer组件,我们不需要任何可视元素,我们只关心它的内容
    4. 把Play Button 和 Name InputField拖拽到Control Panel对象上去
    5. 使用unity菜单'GameObject/UI/Text'创建UI文字,命名为Progress Label,不用关心它影响了显示,我们将在运行时激活和停用它们
    6. 选择Progress Label的Text组件
    7. 设置对齐方式为center align和middle align
    8. 设置文字为“Connecting...”
    9. 设置颜色为白色或者其他和背景有区别
    10. 保存场景

    此时,为了测试,您可以简单地启用/禁用Control Panel和Progress Label,以查看各种连接阶段的情况。 现在让我们编辑脚本以控制这两个GameObjects激活。

    1. 编辑脚本Launcher

    2. 在Public Properties区块添加下面两个属性

       [Tooltip("The Ui Panel to let the user enter name, connect and play")]
       public GameObject controlPanel;
       [Tooltip("The UI Label to inform the user that the connection is in progress")]
       public GameObject progressLabel;
      
    3. 把下面的代码加入Start函数

       progressLabel.SetActive(false);
       controlPanel.SetActive(true);
      
    4. 在Connect方法开头添加下面的代码

       progressLabel.SetActive(true);
       controlPanel.SetActive(false);
      
    5. 在OnDisconnectedFromPhoton方法开头添加下面的代码

       progressLabel.SetActive(false);
       controlPanel.SetActive(true);
      
    6. 保存Launcher脚本,等待unity编译结束

    7. 确保打开场景Launcher

    8. 在Hierarchy中选中Launcher对象

    9. 把Hierarchy中的Control Panel和Progress Label拖拽到对应的Launcher中的组件

    10. 保存场景

    现在,如果你运行场景。 您将看到只有控制面板,可见,一旦您单击播放,将显示Progres标签。

    到此为止,我们做好了Lobby部分。 为了进一步增加Lobby的功能,我们需要切换到游戏本身,并创建各种场景,以便我们可以在加入房间时最终加载正确的级别。 我们将在接下来的部分完成,然后,我们将完成Lobby系统。

    原文

    http://doc.photonengine.com/en-US/pun/current/tutorials/pun-basics-tutorial/lobby-ui

    相关文章

      网友评论

      • 6b5de2697adc:这篇教程这里面有个坑,OnValuechanged方法里面没有办法传入string变量,需要修改代码
        public void SetPlayerName(string value) {
        // #Important
        value = this.GetComponent<InputField>().text;
        PhotonNetwork.playerName = value + " ";//force a trailing space string in case value is an empty string,else playName would not be updated
        PlayerPrefs.SetString(playerNamePrefKey, value);
        }
        并在OnEndEdit事件里面绑定,就可以了
        6b5de2697adc:教程原文里面Drag the Launch the component PlayerNamerInputField into the field。这句话有误
      • 开朗的自信草:你的文章,我很感兴趣,就是看不懂
        浪尖儿:@开朗的自信草 我也是正在学习啊哈哈:smile:
        开朗的自信草: @浪尖儿 你懂unity网络游戏开发吗!教我好吗
        浪尖儿:@开朗的自信草 写的不好,请见谅。。。

      本文标题:Photon Unity Networking基础教程 2 Lo

      本文链接:https://www.haomeiwen.com/subject/cbxluttx.html