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…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...