Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)
文章目录
- Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)
- 服务端
- 客户端
Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)
服务端
-
服务端结构如下:
-
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();}} }
-
-
-
客户端
- 客户端页面
-
绑在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);}}
-
后台持续运行
-
建一个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(){} }
-
别忘了按钮绑定
-
相关文章:
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…...
机器学习笔记之优化算法(十七)梯度下降法在强凸函数的收敛性分析
机器学习笔记之优化算法——梯度下降法在强凸函数的收敛性分析 引言回顾:梯度下降法在强凸函数的收敛性二阶可微——梯度下降法在强凸函数的收敛性推论 引言 上一节介绍并证明了:梯度下降法在强凸函数上的收敛速度满足 Q \mathcal Q Q-线性收敛。 本节将…...
shell脚本中linux命令的特殊用法记录
shell脚本中linux命令的特殊用法记录 1、linux命令特殊参数选项1.1、sed -e1.2、echo -e 2、 shell 扩展2.1、[[ ]]支持用~进行正则匹配 3、特殊命令用法3.1、{} 变量替换 1、linux命令特殊参数选项 1.1、sed -e sed -e以严格模式执行脚本,在sed -e 后面的所有命令…...
Nvidia H100:今年55万张够用吗?
原文标题:Nvidia H100: Are 550,000 GPUs Enough for This Year? 作者:Doug Eadline August 17, 2023 The GPU Squeeze continues to place a premium on Nvidia H100 GPUs. In a recent Financial Times article, Nvidia reports that it expects to…...
【Vue2.0源码学习】生命周期篇-初始化阶段(initLifecycle)
文章目录 1. 前言2. initLifecycle函数分析3. 总结 1. 前言 在上篇文章中,我们介绍了生命周期初始化阶段的整体工作流程,以及在该阶段都做了哪些事情。我们知道了,在该阶段会调用一些初始化函数,对Vue实例的属性、数据等进行初始…...
Android开发基础知识总结(三)简单控件(上)
一.文本显示 考虑到结构样式相分离的思想,我们往往在XML中设置文本 <TextViewandroid:layout_width"342dp"android:layout_height"70dp"android:text"房价计算器"android:layout_gravity"center"android:textColor"…...
在Qt窗口中添加右键菜单
在Qt窗口中添加右键菜单 基于鼠标的事件实现流程demo 基于窗口的菜单策略实现Qt::DefaultContextMenuQt::ActionsContextMenuQt::CustomContextMenu信号API 基于鼠标的事件实现 流程 需要使用:事件处理器函数(回调函数) 在当前窗口类中重写鼠标操作相关的的事件处理器函数&a…...
Day8 智慧商城
项目演示 项目收获 创建项目 调整初始化目录 1.删components里的所有文件 2.删views里的所有文件 3.router/index.js 删路由 删规则 import Vue from vue import VueRouter from vue-routerVue.use(VueRouter)const router new VueRouter({routes: [] })export default route…...
LeetCode:Hot100python版本之回溯
回溯算法其实是纯暴力搜索。for循环嵌套是写不出的 组合:没有顺序 排列:有顺序 回溯法可以抽象为树形结构。只有在回溯算法中递归才会有返回值。 46. 全排列 排列是有顺序的。 组合类问题用startindex,排序类问题用used,来标…...
分布式事务理论基础
今天啊,本片博客我们一起来学习一下微服务中的一个重点和难点知识:分布式事务。 我们会基于Seata 这个框架来学习。 1、分布式事务问题 事务,我们应该比较了解,我们知道所有的事务,都必须要满足ACID的原则。也就是 …...
线性代数强化第三章
目录 一,关于A伴随,A逆与初等矩阵 二,分块矩阵 三,矩阵方程 一,关于A伴随,A逆与初等矩阵 如何证明行列式的值不能是0; 此秩为1. 法一: 法二: 不用看是列变换还是行变…...
上海网站群建设/苏州seo网站系统
Gogs简介 Gogs 是一款类似GitHub的开源文件/代码管理系统(基于Git),Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自助 Git 服务。使用 Go 语言开发使得 Gogs 能够通过独立的二进制分发,并且支持 Go 语言支持的 所有平台…...
哪个科技新闻网站好/seo是什么级别
约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性、唯一性。MYSQL中,常用的几种约束:约束类型:主键默认值唯一外键非空关键字:PRIMARY KEYDEFAULTUNIQUEFOREIGN KEYNOT NULL主键(P…...
网站开发框架的工具/一个新手怎么去运营淘宝店铺
MySQL 数据类型在 MySQL 中,有三种主要的类型:文本、数字和日期/时间类型。Text 类型:数据类型描述CHAR(size)保存固定长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的长度。最多 255 个字符。VARCHAR(size)保存可变长度的…...
自助建网站代理/爱站网关键词查询网站
转自:https://www.pinlue.com/article/2020/01/0317/479874426350.html...
建企业网站怎么收费/德国搜索引擎
POJ-1182 食物链(NYOJ-207)食物链 时间限制:1000 ms | 内存限制:65535 KB难度:5描述动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。 现有N个动…...
做网站设计累吗/个人引流推广怎么做
上帝类 - Object类 总共13个方法:Object类存储在java.lang包中,是所有java类(Object类除外)的终极父类。当然,数组也继承了Object类。然而,接口是不继承Object类的,原因在这里指出:Section 9.6.3.4 of the …...