Photon Unity Networking基础教程 8 网络实例化Player

本节将介绍通过网络实例化Player Prefab,并实现在播放时适应自动场景切换所需的各种功能。

主要内容

  • 实例化Player
  • 追踪Player实例
  • 在竞技场外时管理Player位置

实例化玩家

实际上很容易实例化我们的Player Prefab。我们需要在刚刚进入房间时实例化它,我们可以依靠GameManager脚本的Start()回调,这将表明我们加载了Arena,这意味着我们在一个房间里了。

  1. 打开GameManager脚本

  2. 在Public Variables区块,添加下面的变量

     [Tooltip("The prefab to use for representing the player")]
     public GameObject playerPrefab;
    
  3. 在Start()函数中,添加下面的代码

     if (playerPrefab == null) {
         Debug.LogError("<Color=Red><a>Missing</a></Color> playerPrefab Reference. Please set it up in GameObject 'Game Manager'",this);
     } else {
         Debug.Log("We are Instantiating LocalPlayer from "+Application.loadedLevelName);
     // we're in a room. spawn a character for the local player. it gets synced by using PhotonNetwork.Instantiate
         PhotonNetwork.Instantiate(this.playerPrefab.name, new Vector3(0f,5f,0f), Quaternion.identity, 0);
     }
    
  4. 保存脚本

这暴露了一个公共字段让你引用Player Prefab,它很方便,因为在这个特别的,我们可以直接拖放在GameManager Prefab上,而不是在每个场景,因为Player Prefab是一个Asset,所以引用将保持完好(与引用层次结构中的GameObject相反,Prefab只能在同一场景中实例化时)。

警告:一定要确保要通过网络实例化的Prefabs是放在Resources文件夹里面的,这是Photon的要求。

然后,在Start()中,我们实例化它(在检查我们有一个正确Prefab Player引用之后)。

注意,我们实例化在地板上方(5个单位以上,而Player只有2个单位高)。当新player加入房间时防止碰撞,Player可能已经在围绕舞台的中心移动,并且因此避免突然的碰撞。“下降”Player也是一个很好的清晰的指示,在游戏中引入了一个新的实体。

然而,这是不够的我们的情况下,我们有一个扭曲:)当其他Player将加入的时候,不同的场景将加载,我们想保持一致性,不能只是因为其中一个离开就破坏现有的Player。因此,我们需要告诉Unity不要销毁我们创建的实例,这反过来意味着,我们需要检查在加载场景时是否需要实例化。

追踪Player实例

  1. 打开PlayerManager脚本

  2. 在Public Variables区块,添加下面的代码

     [Tooltip("The local player instance. Use this to know if the local player is represented in the Scene")]
     public static GameObject LocalPlayerInstance;
    
  3. 在Awake()中添加下面的代码

     // #Important
     // used in GameManager.cs: we keep track of the localPlayer instance to prevent instantiation when levels are synchronized
     if ( photonView.isMine)
     {
         PlayerManager.LocalPlayerInstance = this.gameObject;
     }
     // #Critical
     // we flag as don't destroy on load so that instance survives level synchronization, thus giving a seamless experience when levels load.
     DontDestroyOnLoad(this.gameObject);
    
  4. 保存脚本

修改完这些,然后我们在GameManager脚本内部实现只在必要时实例化。

  1. 打开GameManager脚本

  2. 把实例化调用部分放到if语句中

     if (PlayerManager.LocalPlayerInstance==null)
     {
         Debug.Log("We are Instantiating LocalPlayer from "+Application.loadedLevelName);
         // we're in a room. spawn a character for the local player. it gets synced by using PhotonNetwork.Instantiate
         PhotonNetwork.Instantiate(this.playerPrefab.name, new Vector3(0f,5f,0f), Quaternion.identity, 0);
     }else{
         Debug.Log("Ignoring scene load for "+Application.loadedLevelName);
     }
    
  3. 保存脚本

这样的话,如果PlayerManager中LocalPlayerInstance为空的话,才会实例化。

在竞技场外时管理Player位置

我们还有一件事要注意。竞技场的尺寸基于玩家的数量而改变,这意味着存在如下情况:如果一个玩家离开,并且其他玩家接近当前竞技场尺寸的边界,那么在加载完小场景之后,他们将发现自己在较小的竞技场之外,我们需要考虑到这一点,并且在这种情况下简单地将Player重新定位到竞技场的中心。这在你的游戏和级别设计时是一个问题。

目前有一个额外的复杂性,因为Unity已经改进了场景管理,并且Unity 5.4已经弃用了一些回调,要创建一个兼容所有Unity版本(从Unity 4.7到最新)的代码,会稍微复杂一些。所以我们需要基于Unity不同版本写不同的代码。它与Photon Networking无关,但无论如何对你掌握项目更新很重要。

  1. 打开PlayerManager脚本

  2. 在顶部添加下面的代码

     #if UNITY_5 && (!UNITY_5_0 && !UNITY_5_1 && !UNITY_5_2 && ! UNITY_5_3) || UNITY_6
     #define UNITY_MIN_5_4
     #endif
    
  3. 在Start()方法末尾,添加下面的代码

     #if UNITY_MIN_5_4
     // Unity 5.4 has a new scene management. register a method to call CalledOnLevelWasLoaded.
     UnityEngine.SceneManagement.SceneManager.sceneLoaded += (scene, loadingMode) =>
             {
                 this.CalledOnLevelWasLoaded(scene.buildIndex);
             };
     #endif
    
  4. 在MonoBehaviour CallBacks区块,添加下面两个方法

     #if !UNITY_MIN_5_4
     /// <summary>See CalledOnLevelWasLoaded. Outdated in Unity 5.4.</summary>
     void OnLevelWasLoaded(int level)
     {
     this.CalledOnLevelWasLoaded(level);
     }
     #endif         
      
     void CalledOnLevelWasLoaded(int level)
     {
         // check if we are outside the Arena and if it's the case, spawn around the center of the arena in a safe zone
         if (!Physics.Raycast(transform.position, -Vector3.up, 5f))
         {
             transform.position = new Vector3(0f, 5f, 0f);
         }
     }
    
  5. 保存PlayerManager脚本

这个新的代码正在监听加载一个级别,从当前玩家的位置和向下发射射线,看看我们是否击中任何东西。如果没有,这意味着我们不在竞技场的地面上,我们需要重新定位回中心,正如我们第一次进入房间。

如果你的Unity版本低于Unity 5.4,我们将使用Unity的回调OnLevelWasLoaded。如果你是Unity 5.4或更高版本,OnLevelWasLoaded不再可用,而是必须使用新的SceneManagement系统。最后,为了避免重复代码,我们只需要调用CalledOnLevelWasLoaded()方法,该方法将从OnLevelWasLoaded或SceneManager sceneLoaded回调中调用。

原文

http://doc.photonengine.com/en-us/pun/current/tutorials/pun-basics-tutorial/player-instantiation

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容