当前位置: 首页 > news >正文

Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)

文章目录

  • Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)
    • 服务端
    • 客户端

Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)

服务端

  • 服务端结构如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SO0Ba1ul-1692427583534)(../AppData/Roaming/Typora/typora-user-images/image-20230809174547636.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)]

  • 绑在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)]

    • 建一个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)]

相关文章:

Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)

文章目录 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)服务端客户端 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四) 服务端 服务端结构如下&#xff1a; UserModel using System; using System.Collections.Generic; usin…...

【Go 基础篇】Go语言获取用户终端输入:实现交互式程序的关键一步

介绍 在许多编程场景中&#xff0c;我们需要编写交互式程序&#xff0c;以便用户可以在终端中输入数据并与程序进行交互。Go语言提供了丰富的方式来获取用户终端输入&#xff0c;使得编写交互式程序变得简单而有趣。本篇博客将深入探讨Go语言中获取用户终端输入的各种方法&…...

学习笔记:Opencv实现拉普拉斯图像锐化算法

2023.8.19 为了在暑假内实现深度学习的进阶学习&#xff0c;Copy大神的代码&#xff0c;记录学习日常 图像锐化的百科&#xff1a; 图像锐化算法-sharpen_lemonHe_的博客-CSDN博客 在环境配置中要配置opencv&#xff1a; pip install opencv-contrib-python Code and lena.png…...

如何在前端实现WebSocket发送和接收UDP消息(多线程模式)

目录 简介&#xff1a;步骤1&#xff1a;创建WebSocket连接步骤2&#xff1a;创建Web Workers步骤3&#xff1a;发送和接收UDP消息&#xff08;多线程模式&#xff09;结束语&#xff1a; 简介&#xff1a; 本文将继续介绍如何在前端应用中利用WebSocket技术发送和接收UDP消息…...

【微服务】一文了解 Nacos

一文了解 Nacos Nacos 在阿里巴巴起源于 2008 2008 2008 年五彩石项目&#xff08;完成微服务拆分和业务中台建设&#xff09;&#xff0c;成长于十年双十一的洪峰考验&#xff0c;沉淀了简单易用、稳定可靠、性能卓越的核心竞争力。 随着云计算兴起&#xff0c; 2018 2018 20…...

量子计算对信息安全的影响:探讨量子计算技术对现有加密方法和信息安全基础设施可能带来的颠覆性影响,以及应对策略

第一章&#xff1a;引言 随着科技的迅猛发展&#xff0c;量子计算作为一项颠覆性的技术正逐渐走入我们的视野。量子计算以其强大的计算能力引发了全球科技界的广泛关注。然而&#xff0c;正如硬币的两面&#xff0c;量子计算技术所带来的不仅仅是计算能力的巨大飞跃&#xff0…...

ajax-axios-url-form-serialize 插件

AJAX AJAX 概念 1.什么是 AJAX ? mdn 使用浏览器的 XMLHttpRequest 对象 与服务器通信 浏览器网页中&#xff0c;使用 AJAX技术&#xff08;XHR对象&#xff09;发起获取省份列表数据的请求&#xff0c;服务器代码响应准备好的省份列表数据给前端&#xff0c;前端拿到数据数…...

【AIGC】单图换脸离线版软件包及使用方法

云端再好&#xff0c;都不如放自己手里啊&#xff0c;想怎么就怎么玩。云端再好&#xff0c;都不如放自己手里啊&#xff0c;想怎么就怎么玩。 Roop作为一个新出的开源项目&#xff0c;配置起来还是有一定难度的。 我已经把各种依赖&#xff0c;模型&#xff0c;环境配置已经…...

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.读取器代码&#xff1a; package com.vz.utils.excel;import com.alibaba.excel.Eas…...

链路聚合详解

链路聚合详解 华为交换机链路聚合&#xff1a;Linux链路聚合bond配置 华为交换机链路聚合&#xff1a; 方式一&#xff1a;配置手工负载分担方式的链路聚合 [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分支语句&#xff1a;伪代码表示&#xff1a;注意符号和表达式之间的空格&#xff1b; if [ 表达式1 ] then分支1 elif [ 表达式2 ] then分支2 elif [ 表达式3 ] then分支3 else其它 fi按整型的方式&#xff0c;if分支语句比较字符串的大小&#xff1a;等于&am…...

2023.8 - java - 泛型

泛型问题的引出&#xff1a; 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…...

【数据结构练习】链表面试题锦集一

目录 前言&#xff1a; 1. 删除链表中所有值为key的节点 方法一&#xff1a;正常删除&#xff0c;头结点另外讨论 方法二:虚拟头结点法 方法三&#xff1a;递归 2.反转链表 方法一&#xff1a;双指针迭代 方法二&#xff1a;递归法解析&#xff1a; 3.链表的中间结点 方法…...

自然语言处理从入门到应用——LangChain:链(Chains)-[通用功能:SequentialChain和TransformationChain]

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 SequentialChain 在调用语言模型之后&#xff0c;下一步是对语言模型进行一系列的调用。若可以将一个调用的输出作为另一个调用的输入时则特别有用。在本节中&#xff0c;我们将介绍如何使用顺序链来实现这一点。顺序…...

什么是卷积神经网络

目录 什么是卷积神经网络 全链接相对笨重&#xff1a;大胖子​编辑 ​编辑 参数众多&#xff1a;容易造成过拟合 ​编辑 卷积核&#xff1a;进行图像特征提取&#xff0c;源于卷积原理&#xff1a;求相交面积 卷积的作用 卷积的意义 ​编辑 通过卷积核减少参数 深度卷积…...

银行数字化转型程度-根据年报词频计算(2012-2021年)

银行数字化转型程度是根据银行年报中的数字化相关词频计算所得的数据。这一数据包括数字化词频关键词、以及数字化转型程度&#xff0c;反映了银行数字化转型的程度和进展情况。从经济学研究的角度来看&#xff0c;这一数据具有重要的参考价值。 首先&#xff0c;银行数字化转…...

微信开发之一键修改群聊备注的技术实现

修改群备注 修改群名备注后&#xff0c;如看到群备注未更改&#xff0c;是手机缓存问题&#xff0c;可以连续点击进入其他群&#xff0c;在点击进入修改的群&#xff0c;再返回即可看到修改后的群备注名&#xff0c;群名称的备注仅自己可见 请求URL&#xff1a; http://域名地…...

[oneAPI] 基于BERT预训练模型的SQuAD问答任务

[oneAPI] 基于BERT预训练模型的SQuAD问答任务 Intel Optimization for PyTorch and Intel DevCloud for oneAPI基于BERT预训练模型的SQuAD问答任务语料介绍数据下载构建 模型 结果参考资料 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Int…...

物理引导的机器学习工作流:气候建模的融合创新与实践

1. 项目概述&#xff1a;当气候建模遇见机器学习如果你像我一样&#xff0c;在气候模拟这个领域摸爬滚打超过十年&#xff0c;就会深刻体会到一种“甜蜜的负担”&#xff1a;我们构建的地球系统模型&#xff08;ESM&#xff09;越来越精细&#xff0c;物理过程越来越复杂&#…...

Hitboxer:开源SOCD清理工具,3分钟提升游戏操作精准度

Hitboxer&#xff1a;开源SOCD清理工具&#xff0c;3分钟提升游戏操作精准度 【免费下载链接】socd Key remapper for epic gamers 项目地址: https://gitcode.com/gh_mirrors/so/socd 你是否在激烈的游戏对抗中经历过这样的挫败&#xff1a;同时按下左右方向键时角色卡…...

Rydberg原子量子门实现原理与优化技术

1. Rydberg原子平台中的量子门实现基础1.1 Rydberg原子特性与量子计算优势Rydberg原子是指外层电子被激发到高主量子数能级的原子态&#xff0c;这类原子具有三个关键特性使其成为量子计算的理想平台&#xff1a;强偶极-偶极相互作用&#xff1a;当两个原子同时处于Rydberg态时…...

三十岁想从零转行现实吗?带你分辨真正有前景的好工作

![](https://img-blog.csdnimg.cn/direct/b0bfa28b59f9478dae4e6feee6659cce.png)我是29岁那年&#xff0c;完成从转行裸辞副业的职业转型。 如果你把职业生涯看成是从现在开始30岁&#xff0c;到你退休那年&#xff0c;中间这么漫长的30年&#xff0c;那么30岁转行完全来得及…...

2026论文降AI怎么挑?亲测好用工具附免费降AI指南

“您的论文AIGC率为42%&#xff0c;超出学校30%的合格线&#xff0c;请修改后重新提交。”赶毕业论文的同学这段时间估计没少收到这样的提醒。2026年知网、万方、维普等主流平台的AI检测算法持续迭代&#xff0c;把AI生成内容改到符合学校要求&#xff0c;已经成了毕业生的刚需…...

sngan_projection论文解读:ICLR2018两大GAN技术的完美结合

sngan_projection论文解读&#xff1a;ICLR2018两大GAN技术的完美结合 【免费下载链接】sngan_projection GANs with spectral normalization and projection discriminator 项目地址: https://gitcode.com/gh_mirrors/sn/sngan_projection sngan_projection是一个实现了…...

淘宝淘金币自动化脚本终极指南:如何每天节省25分钟实现智能任务管理

淘宝淘金币自动化脚本终极指南&#xff1a;如何每天节省25分钟实现智能任务管理 【免费下载链接】taojinbi 淘宝淘金币自动执行脚本&#xff0c;包含蚂蚁森林收取能量&#xff0c;芭芭农场全任务&#xff0c;解放你的双手 项目地址: https://gitcode.com/gh_mirrors/ta/taoji…...

如何在浏览器中一键解密所有加密音乐文件:Unlock-Music完全指南

如何在浏览器中一键解密所有加密音乐文件&#xff1a;Unlock-Music完全指南 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库&#xff1a; 1. https://github.com/unlock-music/unlock-music &#xff1b;2. https://git.unlock-music.dev/um/web 项目地…...

从API Key管理视角看Taotoken平台的安全与审计功能

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 从API Key管理视角看Taotoken平台的安全与审计功能 对于依赖大模型API进行开发的团队而言&#xff0c;API Key的管理与安全是项目稳…...

使用libusb-win32驱动复活老旧USB硬件:以Elektor Magic Eye为例

1. 项目概述&#xff1a;让老硬件在新时代焕发新生手头有一台十多年前的《Elektor》杂志上刊登的“Magic Eye EM84”复古VFD显示屏项目&#xff0c;想把它接到Windows 10电脑上当个酷炫的CPU占用率显示器&#xff0c;却发现官方提供的“AVR309”USB驱动在新系统上彻底罢工了。这…...