网站建设导航栏怎么创建一个属于自己的平台
- 作者: 五速梦信息网
- 时间: 2026年04月20日 07:51
当前位置: 首页 > news >正文
网站建设导航栏,怎么创建一个属于自己的平台,wordpress网站加载慢,保定徐水网站建设【Unity工具#xff0c;简单应用】Photon PUN 2#xff0c;做一个简单多人聊天室前置知识#xff0c;安装#xff0c;及简单UI大厅聊天室简单同步较复杂同步自定义同步最终效果前置知识#xff0c;安装#xff0c;及简单UI 【Unity工具#xff0c;简单学习】PUN 2简单应用】Photon PUN 2做一个简单多人聊天室前置知识安装及简单UI大厅聊天室简单同步较复杂同步自定义同步最终效果前置知识安装及简单UI 【Unity工具简单学习】PUN 2多人在线游戏开发初步使用需要有一定 UNITY 使用经验的开发者可以顺利阅读。 大厅 简单搭建一下大厅UI。 给 Laucher 节点一个 Launcher 脚本 Launcher 脚本如下具体功能看注释 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Photon.Pun; using Photon.Realtime;public class Launcher : MonoBehaviourPunCallbacks {public string RoomName Room; // 设置房间名确保每次连接到同一个房间private string gameVersion 1;[SerializeField]private const byte maxPlayersPerRoom 4; // 设置单房间最多玩家数[SerializeField]private GameObject controlPanel;[SerializeField]private GameObject progressLabel;void Awake(){// Then let master server can use PhotonNetwork.LoadLevel()// Everyone will see the same levelPhotonNetwork.AutomaticallySyncScene true; // 确保该变量为 true否则无法同步progressLabel.SetActive(false);controlPanel.SetActive(true);}public void Connect(){progressLabel.SetActive(true);controlPanel.SetActive(false);if (PhotonNetwork.IsConnected) // 若已连接则直接加入到房间{PhotonNetwork.JoinOrCreateRoom(RoomName, new RoomOptions() { MaxPlayers maxPlayersPerRoom }, default);}else{PhotonNetwork.ConnectUsingSettings(); // 用 PhotonServerSettings 来连接PhotonNetwork.GameVersion gameVersion;}}public override void OnJoinRandomFailed(short returnCode, string message) // 若加入随机房间失败{Debug.Log(PUN Basics Tutorial/Launcher:OnJoinRandomFailed() was called by PUN. No random room available, so we create one.\nCalling: PhotonNetwork.CreateRoom);// #Critical: we failed to join a random room, maybe none exists or they are all full. No worries, we create a new room.PhotonNetwork.CreateRoom(RoomName, new RoomOptions() { MaxPlayers maxPlayersPerRoom });}public override void OnJoinedRoom() // 若加入了某房间则加载聊天室场景不要使用 UNITY的加载场景方法{Debug.Log(PUN Basics Tutorial/Launcher: OnJoinedRoom() called by PUN. Now this client is in a room.);PhotonNetwork.LoadLevel(ChatingRoom);}public override void OnConnectedToMaster() // 运行ConnectUsingSettings()后会先连接到 Master节点再创建或加载房间{Debug.Log(PUN Basics Tutorial/Launcher: OnConnectedToMaster() was called by PUN);PhotonNetwork.JoinOrCreateRoom(RoomName, new RoomOptions() { MaxPlayers maxPlayersPerRoom }, default);}public override void OnDisconnected(DisconnectCause cause) // 若失去连接后{progressLabel.SetActive(false);controlPanel.SetActive(true);Debug.LogWarningFormat(PUN Basics Tutorial/Launcher: OnDisconnected() was called by PUN with reason {0}, cause);}}需要注意的是 PhotonNetwork.JoinOrCreateRoom(RoomName, new RoomOptions() { MaxPlayers maxPlayersPerRoom }, default); 方法若该房间名的房间不存在则创建否则加载该房间。在输入框中把该字符串赋值给 PhotonNetwork.NickName 即表示该玩家的名称需非空 PhotonNetwork.NickName defaultName; 聊天室 聊天室的UI如下 添加一个 GameManagerPUN 的物体并给予它对应的脚本组件 GameManagerPUN 脚本如下 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; using Photon.Pun; using Photon.Realtime; public class GameManagerPUN : MonoBehaviourPunCallbacks {public string DialogueText DialogueText;[SerializeField]private InputField _inputField;public GameObject Content;void Start(){GameObject go PhotonNetwork.Instantiate(Sphere, Vector3.zero, Quaternion.identity);go.GetComponentChangeRandomPosition().change(); // 用 PhotonNetwork.Instantiate 创建一个物体让它的位置随机变一下代表显示该房间内的玩家个数}public override void OnLeftRoom(){SceneManager.LoadScene(LobbyScene);}public void LeaveRoom() // 退出按钮的监听器直接调用该代码即可调用 OnLeftRoom() 方法退出大厅{PhotonNetwork.LeaveRoom();}public override void OnPlayerEnteredRoom(Player other) // 自动监听是否有玩家进入{Debug.LogFormat(OnPlayerEnteredRoom() {0}, other.NickName); // not seen if youre the player connectingif (PhotonNetwork.IsMasterClient){Debug.LogFormat(OnPlayerEnteredRoom IsMasterClient {0}, PhotonNetwork.IsMasterClient); // called before OnPlayerLeftRoom}}public override void OnPlayerLeftRoom(Player other) // 自动监听是否有玩家退出{Debug.LogFormat(OnPlayerLeftRoom() {0}, other.NickName); // seen when other disconnectsif (PhotonNetwork.IsMasterClient){Debug.LogFormat(OnPlayerLeftRoom IsMasterClient {0}, PhotonNetwork.IsMasterClient); // called before OnPlayerLeftRoom}}public void SendMessage() // 发送消息记录发送消息者名称与它发送的消息然后创建一个UI物体加载到滚动content中{string res PhotonNetwork.NickName : _inputField.text;GameObject obj PhotonNetwork.Instantiate(DialogueText, Vector3.zero, Quaternion.identity);obj.GetComponentText().text res;obj.GetComponentSentenceAsync().str res;obj.transform.SetParent(Content.transform);_inputField.text ; // 发送玩后清空输入框} }同步文本信息脚本 SentenceAsync 如下需要实现 IPunObservable 接口的 OnPhotonSerializeView 方法 using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; using UnityEngine.UI; public class SentenceAsync : MonoBehaviourPunCallbacks, IPunObservable {public string str;public GameManagerPUN gm;public GameObject pa;void IPunObservable.OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info){if (stream.IsWriting){stream.SendNext(str);}else{str (string)stream.ReceiveNext();if (pa null) // 用于在不同客户端的同步处理{pa GameObject.Find(Content);this.gameObject.transform.SetParent(pa.transform);this.GetComponentText().text str;}}} }没错该同步脚本纠结了我好几个小时才成功处理对。为什么这么麻烦呢 简单同步 同步的基本原理比较复杂 所幸该 Photon Pun2 给我们封装的差不多了我们只需要知道基础的内容即可简单来说假设有客户端 A,B,C他们都连接服务器 X 在客户端 A 处玩家创建了一个球若只是普通创建则只有 A 处的玩家能看到该球。 若希望每个客户端都能看到该球首先需要使用 PhotonNetwork.Instantiate(str, Vector3, Quaternion) 方法进行同步创建。注意创建物体通过给定它的字符串 str该预设体的路径必须在该 PhotonUnityNetworking / Resources 文件夹下 第二步指定该物体需要同步什么信息。对于该球我们只需要同步它的位置信息即可。 物体若需要同步信息则必须创建 Photon View 脚本。 物体若需要同步信息则必须创建 Photon View 脚本。 物体若需要同步信息则必须创建 Photon View 脚本。 重要的信息重复三次 物体若需要同步 transform 信息则直接给它 Photon Transform View 脚本即可 这里Ownership 表示该物体的所有权是否转移比如 A 创建了该物体是否允许 B 更改它的信息。这里还设计到主机与从机的区别。但这里我们不更改别的信息设置 fixed 即可这里 Synchronization 选择 Unreliable On Change 即可Observable Search 选择同步的观察信息可以直接选择 Auto Find Active 或者设置 Manual 然后手动给予它需要同步信息的脚本即可。能被观察到的脚本必须实现 IPunObservable 接口实现 IPunObservable.OnPhotonSerializeView 方法。 较复杂同步 我们搜索一下已经有的脚本发现官方直接支持我们如下的同步脚本 也就是说若需要同步的观察信息只有 Animator, Rigidbody, Transform 那么可以直接挂载相应的脚本进行同步。那如果我们需要同步某数值信息比如 int, float, string 呢该三种信息同步相应来说比较容易 仍然我们需要实现 IPunObservable 接口实现 IPunObservable.OnPhotonSerializeView 方法 void IPunObservable.OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info){if (stream.IsWriting) // 若流正在写我们发送接下来要同步的信息 string str{stream.SendNext(str);}else{str (string)stream.ReceiveNext(); // 接受流的下一个输出并转化为 (string) 类型if (pa null) // 1{pa GameObject.Find(Content);this.gameObject.transform.SetParent(pa.transform);this.GetComponentText().text str;}}}我们发现其他脚本都很好懂那么 1 处是什么意思呢 这里每行对话物体由于挂载在 Canvas 中且挂载 Text 组件所以必须为 Rect Transform 组件 尽管 Rect Transform 组件是继承自 Transform 组件但是它的信息与 Transform 组件截然不同所以官方提供的 Photon Transform View 不能使用(你挂载就会出bug可以F12查看该脚本原码)难道我们去实现能同步 RectTransform 或者 Text 信息的脚本写起来有点麻烦… 但是我们转念一想我们需要同步的信息只有 发送信息的字符串而已 所以我们只同步字符串。由于 PhotonNetwork.Instantiate() 方法已经为我们创建了该同步物体所以别的组件都是创建出来的只是其中的信息没有同步而已我们还需要同步哪个信息 RectTransform? 不需要由于我们使用 ScrollView自动处理它的各种坐标信息 Text? 我们只需给予其 Text.text str 即可其他的字体啥信息都默认即可 还有一个隐藏的需要同步的信息 —— 该物体的 父对象。父对象由于我们没有同步所以它默认会创建在世界根节点的下面不会显示在 ScrollView 下。 由于该 ScrollView 下面的那些默认物体是每个玩家一开始就是一样的所以我们只需要单纯通过 (1) 指定把自己挂载到该父对象上即可。 自定义同步 若需要自定义同步由于 stream.ReceiveNext() 强转类型只支持默认的那三个 int, float, string所以你想同步比如说 Rect Transform 或者 XXXscript 脚本就需要去里面注册某物体类型很麻烦不怎么推荐相当于指定某个类型的序列化和反序列化的规则可以自己去搜集信息。 最终效果 我和室友使用的是两台笔记本的两个客户端在里面进行聊天 经过测试发现若某玩家退出后由该 owner 通过 PhotonNetwork.Instantiate 创建的同步物体会自动 Destroy。猜测可以通过转移所有权的方式保留聊天记录。
- 上一篇: 网站建设当前位置图标建设婚介网站
- 下一篇: 网站建设到发布2012sevser网站建设参考书
相关文章
-
网站建设当前位置图标建设婚介网站
网站建设当前位置图标建设婚介网站
- 技术栈
- 2026年04月20日
-
网站建设单一来源谈判文件社交网站解决方案
网站建设单一来源谈判文件社交网站解决方案
- 技术栈
- 2026年04月20日
-
网站建设单位不给数据库wordpress管账
网站建设单位不给数据库wordpress管账
- 技术栈
- 2026年04月20日
-
网站建设到发布2012sevser网站建设参考书
网站建设到发布2012sevser网站建设参考书
- 技术栈
- 2026年04月20日
-
网站建设倒计时找不到网站后台怎么办
网站建设倒计时找不到网站后台怎么办
- 技术栈
- 2026年04月20日
-
网站建设德尔普站长百科 wordpress
网站建设德尔普站长百科 wordpress
- 技术栈
- 2026年04月20日
