日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PUN ☀️九、玩家网络实例化与昵称显示

發布時間:2023/12/18 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PUN ☀️九、玩家网络实例化与昵称显示 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 🟥 目標
    • 1?? 玩家網絡實例化
    • 2?? 實現戰斗數據不重置
    • 3?? 位置重置
    • 4?? 激光碰撞判斷
  • 🟧 代碼編寫
    • 🚩 PlayerManager
    • 🚩 GameManager
  • 🟨 血條、昵稱顯示
  • 🟩 最終效果展示:


🟥 目標

1?? 玩家網絡實例化

即把玩家要操控的角色生成出來。GameManager里面Start時實例化角色。



2?? 實現戰斗數據不重置

原先只有兩個人,再加入一個人,會切換到3人的場景。但原先的兩個人當前戰斗數據會被重置,這是不合理的。

我們來讓之前的玩家數據不被重置。

a、PlayerManager 聲明的靜態字段LocalPlayerInstance 記錄本地玩家實例化的。
Awake賦值,并在加載新場景時,不銷毀當前角色。
b、但在重新加載新場景時,GameManager 腳本 Start時會再次實例化角色,于是一個玩家就有了兩個角色。所以GameManager Start時根據判斷 LocalPlayerInstance 是否為空,確定是否已經實例化了角色。



3?? 位置重置

若從3人房切換到2人房,房間變小了。若切換后原先在地面上的角色懸空了,會出Bug。

所以增加判斷:若切換后沒踩在地板上,則位置回到出生位置(原點高空)。

方法:PlayerManager 腳本Start時增加加載完場景時的委托,增加的委托事件判斷當前角色位置



4?? 激光碰撞判斷

解決當跳躍時觸發激光,會造成自身減血的現象。

這是因為激光與自身角色控制器的觸發器檢測碰撞了,我們要檢測激光不是接觸的自身才行,避免自己碰撞掉血。解決辦法:

  • 設置自身的Tag,觸發檢測Tag再決定是否減血。
  • PlayerManager腳本判斷射線碰撞到的角色是否是自己,不是的話再減血(此處采用)
if (other.GetComponentInParent<PhotonView>().IsMine)return;Health -= 0.1f;

現在我們可以測試看看,如果發現連接不上,就換成中國區Appid試試,我隔了一天申請通過了,現在你申請的應該也好了。



🟧 代碼編寫

🚩 PlayerManager

using UnityEngine; using Photon.Pun;public class PlayerManager : MonoBehaviourPunCallbacks, IPunObservable {#region Parameterspublic GameObject beams;//記錄本地玩家實例化public static GameObject LocalPlayerInstance;public float Health = 1f;//當用戶開火時,為Truebool IsFiring;#endregion#region Mono CallBacksvoid Awake(){beams.SetActive(false);if (PhotonNetwork.IsConnected == true && photonView.IsMine)LocalPlayerInstance = gameObject;DontDestroyOnLoad(gameObject);}void Start(){//當重新加載場景時,檢測改腳本所賦值的角色是否踩在空中,若是,則回到出生點重新降落。UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded;if (PhotonNetwork.IsConnected && photonView.IsMine)GetComponent<Skode_CameraWork>().OnStartFollowing();}void Update(){if (Health <= 0f)GameManager.ins.Skode_LeaveRoom();if (PhotonNetwork.IsConnected == true && photonView.IsMine)ProcessInputs();if (IsFiring != beams.activeSelf)beams.SetActive(IsFiring);}void OnTriggerEnter(Collider other){if (!photonView.IsMine && !other.CompareTag("beam"))return;Health -= 0.1f;}void OnTriggerStay(Collider other){if (!photonView.IsMine && !other.CompareTag("beam"))return;//乘以增量時間,防止因為幀率FPS不同,扣血不同(舉例:不乘,每幀執行一次扣血,卡的人比流暢的人扣血少)Health -= 0.1f * Time.deltaTime;}#endregion#region PUN CallBackspublic override void OnDisable(){base.OnDisable();UnityEngine.SceneManagement.SceneManager.sceneLoaded -= OnSceneLoaded;}public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info){if (stream.IsWriting){// 我們擁有這個角色:把我們的數據發送給其他人stream.SendNext(IsFiring);stream.SendNext(Health);}else{// 網絡角色,接收數據IsFiring = (bool)stream.ReceiveNext();Health = (float)stream.ReceiveNext();}}#endregion#region Private Methodsvoid OnSceneLoaded(UnityEngine.SceneManagement.Scene scene, UnityEngine.SceneManagement.LoadSceneMode loadingMode){CalledOnLevelWasLoaded(scene.buildIndex);}void CalledOnLevelWasLoaded(int level){// 檢查我們是否在競技場外面,如果是這樣,移動到競技場中心的安全地帶if (!Physics.Raycast(transform.position, -Vector3.up, 5f)){transform.position = new Vector3(0f, 5f, 0f);}}void ProcessInputs(){//鼠標左鍵if (Input.GetButtonDown("Fire1"))IsFiring = true;if (Input.GetButtonUp("Fire1"))IsFiring = false;}#endregion }



🚩 GameManager

using UnityEngine.SceneManagement; using Photon.Pun; using Photon.Realtime; using UnityEngine;public class GameManager : MonoBehaviourPunCallbacks {public static GameManager ins;[Tooltip("用來代表玩家的預置體")]public GameObject playerPrefab;#region Mono CallBacksprivate void Awake(){ins = this;}private void Start(){//若本地玩家第一次進游戲場景,還未生成角色,則生成一個。//且這個角色通過使用PhotonNetwork.Instantiate進行同步if (PlayerManager.LocalPlayerInstance == null)PhotonNetwork.Instantiate(playerPrefab.name, new Vector3(0f, 5f, 0f), Quaternion.identity, 0);}#endregion#region Public Methods//離開服務器房間Btnpublic void Skode_LeaveRoom(){//不允許主客戶端離開房間if (!PhotonNetwork.IsMasterClient)PhotonNetwork.LeaveRoom();}#endregion#region PUN Callbacks/// <summary>/// 本地玩家離開服務器房間時回調/// </summary>public override void OnLeftRoom(){// 加載大廳場景SceneManager.LoadScene(0);}/// <summary>/// 其他玩家連接房間時的回調(不是自己)/// </summary>public override void OnPlayerEnteredRoom(Player other){print(other.NickName + " 加入房間");//根據當前玩家的人數,主客戶端加載對應場景if (PhotonNetwork.IsMasterClient)LoadArena();}//當玩家離開房間或變得不活動時調用。public override void OnPlayerLeftRoom(Player other){print(other.NickName + " 離開了房間");//根據當前玩家的人數,主客戶端加載對應場景if (PhotonNetwork.IsMasterClient)LoadArena();}#endregion#region Private Methodsvoid LoadArena(){//Photon分為主客戶端、其他客戶端。只有主客戶端才可進行加載房間。//根據當前房間人數加載對應場景。該方法會使其他玩家會自動加入主客戶端的房間PhotonNetwork.LoadLevel("Room for " + PhotonNetwork.CurrentRoom.PlayerCount);}#endregion }



🟨 血條、昵稱顯示

1、創建UI

在人物下創建3D Slider血條,并且有文本框用于顯示名字。

若是滑動條即使是滿值也不到頭,只需改下滑動條下Fill Area 的 Right值就好了。

2、代碼賦值

將下代碼掛到機器人身上,并賦值。

using UnityEngine; using UnityEngine.UI;public class PlayerUI : MonoBehaviour {#region Parameters[Tooltip("顯示玩家名字的UI文本")]public Text playerNameText;[Tooltip("健康值Slider")]public Slider playerHealthSlider;[Tooltip("用于獲取生命值賦值給血條")]public PlayerManager target;#endregion#region Mono Callbacksvoid Start(){playerNameText.text = target.photonView.Owner.NickName;}void Update(){playerHealthSlider.value = target.Health;}#endregion }

若現在還沒把機器人放到 Resources里,現在就要放進去了。已經放進去的Apply一下。

將 Resources 里的機器人預制體賦值給GameManager,刪掉面板的機器人。

各個場景的 GameManager都賦值一下,接下來要進行測試了。

還有,記得關閉離線模式哦



🟩 最終效果展示:

落頭上了哈哈

好啦,本系列暫告一段落🧸





大家還有什么問題,歡迎在下方留言!



如果你有 技術的問題 項目開發

都可以加下方聯系方式

和我聊一聊你的故事🧡

總結

以上是生活随笔為你收集整理的PUN ☀️九、玩家网络实例化与昵称显示的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。