Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)
文章目录
- Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)
- 服务端
- 客户端
Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)
服务端
-
服务端结构如下:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SO0Ba1ul-1692427583534)(../AppData/Roaming/Typora/typora-user-images/image-20230809174547636.png)]](https://img-blog.csdnimg.cn/81b15b1e7cd544ec917fe58527b69a76.png)
-
UserModel
using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace PhotonServerFirst.Model.User {public class UserModel{public int ID;public int Hp;public float[] Points = new float[] { -4, 1, -2 }; public UserInfo userInfo;}public class UserInfo{public static UserInfo[] userList = new UserInfo[] {new UserInfo(){ ModelID = 0, MaxHp = 100, Attack = 20, Speed = 3 },new UserInfo(){ ModelID = 1, MaxHp = 70, Attack = 40, Speed = 4 }};public int ModelID;public int MaxHp;public int Attack;public int Speed;} }-
Messaage
namespace Net {public class Message{public byte Type;public int Command;public object Content;public Message() { }public Message(byte type, int command, object content){Type = type;Command = command;Content = content;}}//消息类型public class MessageType{//unity//类型public static byte Type_Audio = 1;public static byte Type_UI = 2;public static byte Type_Player = 3;//声音命令public static int Audio_PlaySound = 100;public static int Audio_StopSound = 101;public static int Audio_PlayMusic = 102;//UI命令public static int UI_ShowPanel = 200;public static int UI_AddScore = 201;public static int UI_ShowShop = 202;//网络public const byte Type_Account = 1;public const byte Type_User = 2;//注册账号public const int Account_Register = 100;public const int Account_Register_Res = 101;//登陆public const int Account_Login = 102;public const int Account_Login_res = 103;//选择角色public const int User_Select = 104; public const int User_Select_res = 105; public const int User_Create_Event = 106;//删除角色public const int User_Remove_Event = 107;} } -
PSPeer
using System; using System.Collections.Generic; using Net; using Photon.SocketServer; using PhotonHostRuntimeInterfaces; using PhotonServerFirst.Bll;namespace PhotonServerFirst {public class PSPeer : ClientPeer{public PSPeer(InitRequest initRequest) : base(initRequest){}//处理客户端断开的后续工作protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail){//关闭管理器BLLManager.Instance.accountBLL.OnDisconnect(this);BLLManager.Instance.userBLL.OnDisconnect(this);}//处理客户端的请求protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters){PSTest.log.Info("收到客户端的消息");var dic = operationRequest.Parameters;//打包,转为PhotonMessageMessage message = new Message();message.Type = (byte)dic[0];message.Command = (int)dic[1];List<object> objs = new List<object>();for (byte i = 2; i < dic.Count; i++){objs.Add(dic[i]);}message.Content = objs.ToArray();//消息分发switch (message.Type){case MessageType.Type_Account:BLLManager.Instance.accountBLL.OnOperationRequest(this, message); break;case MessageType.Type_User:BLLManager.Instance.userBLL.OnOperationRequest(this, message);break;}}} }-
UserBLL
using Net; using PhotonServerFirst.Model.User; using PhotonServerFirst.Dal; using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace PhotonServerFirst.Bll.User {class UserBLL : IMessageHandler{public void OnDisconnect(PSPeer peer){//下线UserModel user = DALManager.Instance.userDAL.GetUserModel(peer);//移除角色DALManager.Instance.userDAL.RemoveUser(peer);//通知其他角色该角色已经下线foreach (PSPeer otherpeer in DALManager.Instance.userDAL.GetuserPeers()){SendMessage.Send(otherpeer, MessageType.Type_User, MessageType.User_Remove_Event, user.ID);}}public void OnOperationRequest(PSPeer peer, Message message){switch (message.Command){case MessageType.User_Select://有人选了角色//创建其他角色CreateOtherUser(peer, message);//创建自己的角色CreateUser(peer, message);//通知其他角色创建自己CreateUserByOthers(peer, message); break;}}//创建目前已经存在的角色void CreateOtherUser(PSPeer peer, Message message){//遍历已经登陆的角色foreach (UserModel userModel in DALManager.Instance.userDAL.GetUserModels()){//给登录的客户端响应,让其创建这些角色 角色id 模型id 位置SendMessage.Send(peer, MessageType.Type_User, MessageType.User_Create_Event, userModel.ID, userModel.userInfo.ModelID, userModel.Points);}}//创建自己角色void CreateUser(PSPeer peer, Message message){object[] obj = (object[])message.Content;//客户端传来模型idint modelId = (int)obj[0];//创建角色int userId = DALManager.Instance.userDAL.AddUser(peer, modelId);//告诉客户端创建自己的角色SendMessage.Send(peer, MessageType.Type_User, MessageType.User_Select_res, userId, modelId, DALManager.Instance.userDAL.GetUserModel(peer).Points);}//通知其他角色创建自己void CreateUserByOthers(PSPeer peer, Message message){UserModel userModel = DALManager.Instance.userDAL.GetUserModel(peer);//遍历全部客户端,发送消息foreach (PSPeer otherpeer in DALManager.Instance.userDAL.GetuserPeers()){if (otherpeer == peer){continue;}SendMessage.Send(otherpeer, MessageType.Type_User, MessageType.User_Create_Event, userModel.ID, userModel.userInfo.ModelID, userModel.Points);}}} } -
BLLManager
using PhotonServerFirst.Bll.User; using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace PhotonServerFirst.Bll {public class BLLManager{private static BLLManager bLLManager;public static BLLManager Instance{get{if(bLLManager == null){bLLManager = new BLLManager();}return bLLManager;}}//登录注册管理public IMessageHandler accountBLL;//角色管理public IMessageHandler userBLL;private BLLManager(){accountBLL = new PhsotonServerFirst.Bll.Account.AccountBLL();userBLL = new UserBLL();}} }-
UserDAL
using System; using System.Collections.Generic; using System.Linq; using System.Text; using PhotonServerFirst.Model.User;namespace PhotonServerFirst.Dal.User {class UserDAL{//角色保存集合private Dictionary<PSPeer, UserModel> peerUserDic = new Dictionary<PSPeer, UserModel>();private int userId = 1;/// <summary>///添加一名角色/// </summary>/// <param name="peer">连接对象</param>/// <param name="index">几号角色</param>/// <returns>用户id</returns>public int AddUser(PSPeer peer, int index){UserModel model = new UserModel();model.ID = userId++;model.userInfo = UserInfo.userList[index];model.Hp = model.userInfo.MaxHp;if (index == 1){model.Points = new float[] { 0, 2, -2 };}peerUserDic.Add(peer, model);return model.ID;}///<summary>///移除一名角色/// </summary>public void RemoveUser(PSPeer peer){peerUserDic.Remove(peer);}///<summary>///得到用户模型///</summary>///<param name="peer">连接对象</param>///<returns>用户模型</returns>public UserModel GetUserModel(PSPeer peer){return peerUserDic[peer];}///<summary>///得到全部的用户模型///</summary>public UserModel[] GetUserModels() {return peerUserDic.Values.ToArray();}///<summary>///得到全部有角色的连接对象///</summary>public PSPeer[] GetuserPeers(){return peerUserDic.Keys.ToArray();}} } -
DALManager
using PhotonServerFirst.Bll; using PhotonServerFirst.Dal.User; using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace PhotonServerFirst.Dal {class DALManager{private static DALManager dALManager;public static DALManager Instance{get{if (dALManager == null){dALManager = new DALManager();}return dALManager;}}//登录注册管理public AccountDAL accountDAL;//用户管理public UserDAL userDAL;private DALManager(){accountDAL = new AccountDAL();userDAL = new UserDAL();}} }
-
-
-
客户端
- 客户端页面
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fYrrhFIg-1692427583535)(../AppData/Roaming/Typora/typora-user-images/image-20230809134945235.png)]](https://img-blog.csdnimg.cn/2354edc0b30b4036806aa0aa0e7ad69d.png)
-
绑在panel上
using System.Collections; using System.Collections.Generic; using UnityEngine; using Net;public class SelectPanel : MonoBehaviour {// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}public void SelectHero(int modelId){//告诉服务器创建角色PhotonManager.Instance.Send(MessageType.Type_User, MessageType.User_Select, modelId);//摧毁选择角色页面Destroy(gameObject);//显示计分版UImanager.Instance.SetActive("score", true);}} -
后台持续运行
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L95228mk-1692427583536)(../AppData/Roaming/Typora/typora-user-images/image-20230809152745663.png)]](https://img-blog.csdnimg.cn/adbe5d86a7f44a3e90ac10569b70abc2.png)
-
建一个usermanager,绑定以下脚本
using System.Collections; using System.Collections.Generic; using UnityEngine; using Net;public class UserManager : ManagerBase {void Start(){MessageCenter.Instance.Register(this);}public override void ReceiveMessage(Message message){base.ReceiveMessage(message);//打包object[] obs = (object[])message.Content;//消息分发switch(message.Command){case MessageType.User_Select_res:selectUser(obs);break;case MessageType.User_Create_Event:CreateotherUser(obs);break;case MessageType.User_Remove_Event:RemoveUser(obs);break;}} public override byte GetMessageType(){return MessageType.Type_User;}//选择了自己的角色void selectUser(object[] objs){int userId =(int)objs[0];int modelId = (int)objs[1];float[] point = (float[])objs[2];if (userId > 0){//创建角色GameObject UserPre = Resources.Load<GameObject>("User/" + modelId);UserControll user = Instantiate(UserPre,new Vector3(point[0],point[1],point[2]),Quaternion.identity).GetComponent<UserControll>();UserControll.ID =userId;//保存到集合中UserControll.idUserDic.Add(userId, user);}else {Debug.Log("创建角色失败");}}//创建其他角色void CreateotherUser(object[] objs){//打包int userId = (int)objs[0];int modelId = (int)objs [1];float[] point = (float[])objs[2];GameObject UserPre = Resources.Load<GameObject>("User/" + modelId);UserControll user = Instantiate(UserPre, new Vector3(point[0],point[1], point[2]),Quaternion.identity).GetComponent<UserControll>();UserControll.idUserDic.Add(userId, user);}//删除一名角色void RemoveUser(object[] objs){int userId = (int)objs[0];UserControll user = UserControll.idUserDic[userId];UserControll.idUserDic.Remove(userId);Destroy(user.gameObject);}} -
给物体上绑定
using System.Collections; using System.Collections.Generic; using UnityEngine;public class UserControll : MonoBehaviour {//保存了所有角色的集合public static Dictionary<int, UserControll> idUserDic = new Dictionary<int, UserControll>();//当前客户端角色的idpublic static int ID;private Animator ani;// Start is called before the first frame updatevoid Start(){ani = GetComponent<Animator>();}// Update is called once per framevoid Update(){} } -
别忘了按钮绑定
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hdlPzRk2-1692427583536)(../AppData/Roaming/Typora/typora-user-images/image-20230809174710292.png)]](https://img-blog.csdnimg.cn/0a590472c3374b96a0bb1b8b6b4217b9.png)
-
相关文章:
Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)
文章目录 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)服务端客户端 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四) 服务端 服务端结构如下: UserModel using System; using System.Collections.Generic; usin…...
【Go 基础篇】Go语言获取用户终端输入:实现交互式程序的关键一步
介绍 在许多编程场景中,我们需要编写交互式程序,以便用户可以在终端中输入数据并与程序进行交互。Go语言提供了丰富的方式来获取用户终端输入,使得编写交互式程序变得简单而有趣。本篇博客将深入探讨Go语言中获取用户终端输入的各种方法&…...
学习笔记:Opencv实现拉普拉斯图像锐化算法
2023.8.19 为了在暑假内实现深度学习的进阶学习,Copy大神的代码,记录学习日常 图像锐化的百科: 图像锐化算法-sharpen_lemonHe_的博客-CSDN博客 在环境配置中要配置opencv: pip install opencv-contrib-python Code and lena.png…...
如何在前端实现WebSocket发送和接收UDP消息(多线程模式)
目录 简介:步骤1:创建WebSocket连接步骤2:创建Web Workers步骤3:发送和接收UDP消息(多线程模式)结束语: 简介: 本文将继续介绍如何在前端应用中利用WebSocket技术发送和接收UDP消息…...
【微服务】一文了解 Nacos
一文了解 Nacos Nacos 在阿里巴巴起源于 2008 2008 2008 年五彩石项目(完成微服务拆分和业务中台建设),成长于十年双十一的洪峰考验,沉淀了简单易用、稳定可靠、性能卓越的核心竞争力。 随着云计算兴起, 2018 2018 20…...
量子计算对信息安全的影响:探讨量子计算技术对现有加密方法和信息安全基础设施可能带来的颠覆性影响,以及应对策略
第一章:引言 随着科技的迅猛发展,量子计算作为一项颠覆性的技术正逐渐走入我们的视野。量子计算以其强大的计算能力引发了全球科技界的广泛关注。然而,正如硬币的两面,量子计算技术所带来的不仅仅是计算能力的巨大飞跃࿰…...
ajax-axios-url-form-serialize 插件
AJAX AJAX 概念 1.什么是 AJAX ? mdn 使用浏览器的 XMLHttpRequest 对象 与服务器通信 浏览器网页中,使用 AJAX技术(XHR对象)发起获取省份列表数据的请求,服务器代码响应准备好的省份列表数据给前端,前端拿到数据数…...
【AIGC】单图换脸离线版软件包及使用方法
云端再好,都不如放自己手里啊,想怎么就怎么玩。云端再好,都不如放自己手里啊,想怎么就怎么玩。 Roop作为一个新出的开源项目,配置起来还是有一定难度的。 我已经把各种依赖,模型,环境配置已经…...
8.19论文阅读
文章目录 Graph-Segmenter: Graph Transformer with Boundary-aware Attention for Semantic Segmentation方法 SCSC: Spatial Cross-scale Convolution Module to Strengthen both CNNs and Transformers方法 Deformable Mixer Transformer with Gating for Multi-Task Learni…...
HAProxy
目录 HAProxy HAProxy介绍 主要特性 LVS、nginx、HAProxy区别 nginx LVS HAProxy 负载均衡策略 Haproxy搭建 Web 群集 Haproxy服务器 编译安装 Haproxy Haproxy服务器配置 添加haproxy 系统服务 节点服务器部署 日志定义 HAProxy HAProxy介绍 HAProxy是可提供高…...
基于EasyExcel的Excel读取
1.引入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.11</version> </dependency>2.读取器代码: package com.vz.utils.excel;import com.alibaba.excel.Eas…...
链路聚合详解
链路聚合详解 华为交换机链路聚合:Linux链路聚合bond配置 华为交换机链路聚合: 方式一:配置手工负载分担方式的链路聚合 [CORE1] interface Eth-Trunk 1 [CORE1-Eth-Trunk1] trunkport GigabitEthernet 0/0/5 to 0/0/6 [CORE1-Eth-Trunk1] p…...
Shell编程学习之if分支语句的应用
Shell编程中的if分支语句:伪代码表示:注意符号和表达式之间的空格; if [ 表达式1 ] then分支1 elif [ 表达式2 ] then分支2 elif [ 表达式3 ] then分支3 else其它 fi按整型的方式,if分支语句比较字符串的大小:等于&am…...
2023.8 - java - 泛型
泛型问题的引出: jdk 1.5 引出泛型 // package 泛型; public class index {public static void main (String[] args){test t new test();t.setContent("aaa");int a (int) t.getContent();System.out.println(a);} }class test{Object content;publi…...
【数据结构练习】链表面试题锦集一
目录 前言: 1. 删除链表中所有值为key的节点 方法一:正常删除,头结点另外讨论 方法二:虚拟头结点法 方法三:递归 2.反转链表 方法一:双指针迭代 方法二:递归法解析: 3.链表的中间结点 方法…...
自然语言处理从入门到应用——LangChain:链(Chains)-[通用功能:SequentialChain和TransformationChain]
分类目录:《自然语言处理从入门到应用》总目录 SequentialChain 在调用语言模型之后,下一步是对语言模型进行一系列的调用。若可以将一个调用的输出作为另一个调用的输入时则特别有用。在本节中,我们将介绍如何使用顺序链来实现这一点。顺序…...
什么是卷积神经网络
目录 什么是卷积神经网络 全链接相对笨重:大胖子编辑 编辑 参数众多:容易造成过拟合 编辑 卷积核:进行图像特征提取,源于卷积原理:求相交面积 卷积的作用 卷积的意义 编辑 通过卷积核减少参数 深度卷积…...
银行数字化转型程度-根据年报词频计算(2012-2021年)
银行数字化转型程度是根据银行年报中的数字化相关词频计算所得的数据。这一数据包括数字化词频关键词、以及数字化转型程度,反映了银行数字化转型的程度和进展情况。从经济学研究的角度来看,这一数据具有重要的参考价值。 首先,银行数字化转…...
微信开发之一键修改群聊备注的技术实现
修改群备注 修改群名备注后,如看到群备注未更改,是手机缓存问题,可以连续点击进入其他群,在点击进入修改的群,再返回即可看到修改后的群备注名,群名称的备注仅自己可见 请求URL: http://域名地…...
[oneAPI] 基于BERT预训练模型的SQuAD问答任务
[oneAPI] 基于BERT预训练模型的SQuAD问答任务 Intel Optimization for PyTorch and Intel DevCloud for oneAPI基于BERT预训练模型的SQuAD问答任务语料介绍数据下载构建 模型 结果参考资料 比赛:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Int…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
