当前位置:   article > 正文

【Unity插件Mirror】射击游戏样例学习(二)_unity mirror isserver 未赋值

unity mirror isserver 未赋值
10.网络优化
当运行后,SceneScript被disable了,直到玩家处于准备状态为止,因为GameObject.Find()无法保证具有NetworkIdentity的场景对象的被发现。
所以解决方法就是用GameObject.Find()用来得到非网络标识的物体,然后具有网络标识的可以设置预先设定。创建SceneReference空对象,加入SceneReference.cs,然后加入如下代码:
  1. using UnityEngine;
  2. namespace QuickStart
  3. {
  4. public class SceneReference : MonoBehaviour
  5. {
  6. public SceneScript sceneScript;
  7. }
  8. }
然后在SceneScript.cs加入public SceneReference sceneReference,最后两者把脚本相互映射进去,这样两者就可以通信了。
    
最后在PlayerScript的awake函数中加入sceneScript = GameObject.Find(“SceneReference”).GetComponent<SceneReference>().sceneScript;
11.制作游戏交互界面
在SceneScript.cs加入以下代码:
  1. using UnityEngine.SceneManagement;
  2. public void ButtonChangeScene()
  3. {
  4. if (isServer)
  5. {
  6. Scene scene = SceneManager.GetActiveScene();
  7. if (scene.name == "MainScene") { NetworkManager.singleton.ServerChangeScene("MyOtherScene"); }
  8. else { NetworkManager.singleton.ServerChangeScene("MainScene"); }
  9. }
  10. else { Debug.Log("You are not Host."); }
  11. }
将当前场景复制三个,命名如下:
将复制的场景Menu中一部分删除后,如下所示:
在Menu.cs中加入切换场景的代码:
  1. using UnityEngine;
  2. using UnityEngine.SceneManagement;
  3. namespace QuickStart
  4. {
  5.     public class Menu : MonoBehaviour
  6.     {
  7.         public void LoadScene()
  8.         {
  9.             SceneManager.LoadScene("GamesList");
  10.         }
  11.     }
  12. }
更新GameList场景,保留NetworkManager,并添加到GameList.cs到GameList物体对象中去。
  1. using UnityEngine;
  2. using UnityEngine.SceneManagement;
  3. namespace QuickStart
  4. {
  5.     public class GamesList : MonoBehaviour
  6.     {
  7.         public void LoadScene()
  8.         {
  9.             SceneManager.LoadScene("Menu");
  10.         }
  11.     }
  12. }
切换到MyOtherScene场景,该场景是地图二,所以在原有基础中做些差别就行
四个场景都配置好后,一一打开并添加到Build中去,注意要将Menu设置为第一个
打开预制体中的NetworkManager,将离线场景和在线场景添加进去
测试
场景跳转成功
12.子弹模块
分别在weapon1和weapon2下新建一个空物体,表示子弹开火位置
在weapon1和weapon2下分别创建一个Weapon脚本:
  1. using UnityEngine;
  2. namespace QuickStart
  3. {
  4.     public class Weapon : MonoBehaviour
  5.     {
  6.         public float weaponSpeed = 15.0f;
  7.         public float weaponLife = 3.0f;
  8.         public float weaponCooldown = 1.0f;
  9.         public int weaponAmmo = 15;
  10.         public GameObject weaponBullet;
  11.         public Transform weaponFirePosition;
  12.     }
  13. }
在任意一个场景中新建一个球体和立方体,它们的处理方法一样,如下:
保存成预制体
将武器模型和位置映射到脚本中去
预制体保存
在SceneScript中添加:
  1. public Text canvasAmmoText;
  2.     
  3. public void UIAmmo(int _value)
  4. {
  5.     canvasAmmoText.text = "Ammo: " + _value;
  6. }
从上文可知设置了2个地图,所以在两个场景中,添加如下一样的操作
在 PlayerScript.cs添加:
  1. private Weapon activeWeapon;
  2. private float weaponCooldownTime;  
更新OnWeaponChanged函数
  1. void OnWeaponChanged(int _Old, int _New)
  2. {
  3.     // disable old weapon
  4.     // in range and not null
  5.     if (0 < _Old && _Old < weaponArray.Length && weaponArray[_Old] != null)
  6.     {
  7.         weaponArray[_Old].SetActive(false);
  8.     }
  9.     
  10.     // enable new weapon
  11.     // in range and not null
  12.     if (0 < _New && _New < weaponArray.Length && weaponArray[_New] != null)
  13.     {
  14.         weaponArray[_New].SetActive(true);
  15.         activeWeapon = weaponArray[activeWeaponSynced].GetComponent<Weapon>();
  16.         if( isLocalPlayer ) { sceneScript.UIAmmo(activeWeapon.weaponAmmo); }
  17.     }
  18. }
更新Awake()添加在末行
  1. if (selectedWeaponLocal < weaponArray.Length && weaponArray[selectedWeaponLocal] != null)
  2. { activeWeapon = weaponArray[selectedWeaponLocal].GetComponent<Weapon>(); sceneScript.UIAmmo(activeWeapon.weaponAmmo); }
更新Update()添加在末行    
  1. if (Input.GetButtonDown("Fire1") ) //Fire1 is mouse 1st click
  2. {
  3.     if (activeWeapon && Time.time > weaponCooldownTime && activeWeapon.weaponAmmo > 0)
  4.     {
  5.         weaponCooldownTime = Time.time + activeWeapon.weaponCooldown;
  6.         activeWeapon.weaponAmmo -= 1;
  7.         sceneScript.UIAmmo(activeWeapon.weaponAmmo);
  8.         CmdShootRay();
  9.     }
  10. }
添加两个函数在Update()函数之后
  1. [Command]
  2. void CmdShootRay()
  3. {
  4.     RpcFireWeapon();
  5. }
  6. [ClientRpc]
  7. void RpcFireWeapon()
  8. {
  9.     //bulletAudio.Play(); muzzleflash  etc
  10.     var bullet = (GameObject)Instantiate(activeWeapon.weaponBullet, activeWeapon.weaponFirePosition.position, activeWeapon.weaponFirePosition.rotation);
  11.     bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * activeWeapon.weaponSpeed;
  12.     if (bullet) { Destroy(bullet, activeWeapon.weaponLife); }
  13. }
测试
完结!
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/104167
推荐阅读
相关标签
  

闽ICP备14008679号