当前位置: 首页 > 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. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...