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;
      
                  //打包,转为PhotonMessage
                  Message 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;
                        //客户端传来模型id
                        int 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 update
        void Start()
        {
            
        }
    
        // Update is called once per frame
        void 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>();
          //当前客户端角色的id
          public static int ID;
          private Animator ani;
      
          // Start is called before the first frame update
          void Start()
          {
              ani = GetComponent<Animator>();
          }
      
          // Update is called once per frame
          void Update()
          {
              
          }
      }
      
      
    • 别忘了按钮绑定

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hdlPzRk2-1692427583536)(../AppData/Roaming/Typora/typora-user-images/image-20230809174710292.png)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/83202.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习笔记|基于Delay实现的LED闪烁|u16是什么|a--和--a的区别|STC32G单片机视频开发教程(冲哥)|第六集(上):实现LED闪烁

文章目录 摘要软件更新什么是闪烁Tips:u16是什么? 语法分析&#xff1a;验证代码Tips&#xff1a;a--和--a的区别&#xff08;--ms 的用法&#xff09;测试代码&#xff1a; 摘要 1.基于Delay实现的LED闪烁 2.函数的使用 3,新建文件&#xff0c;使用模块化编程 软件更新 打…

微信ipad协议

前言 微信协议就是基于微信IPad协议的智能控制系统&#xff0c;利用人工智能AI技术、云计算技术、虚拟技术、边缘计算技术、大数据技术&#xff0c; 打造出智能桌面系统RDS、 智能聊天系统ACS 、智能插 件系统PLUGIN 、云计算服务CCS 、 任务管理系统TM、设备管理服务DM、 应…

分布式链路追踪——Dapper, a Large-Scale Distributed Systems Tracing Infrastructure

要解决的问题 如何记录请求经过多个分布式服务的信息&#xff0c;以便分析问题所在&#xff1f;如何保证这些信息得到完整的追踪&#xff1f;如何尽可能不影响服务性能&#xff1f; 追踪 当用户请求到达前端A&#xff0c;将会发送rpc请求给中间层B、C&#xff1b;B可以立刻作…

HttpRunner接口自动化框架搭建,干货满满!

前言 除了前面讲述的unittest、pytest等等自动化框架外&#xff0c;HttpRunner也是当前流行自动化框架之一。 一、先简单来介绍下httprunner框架 1、它是面向HTTP协议的测试框架&#xff0c;独立于语言之外&#xff0c;无需编写代码脚本&#xff0c;只需要去维护yaml/json文…

Windows安装Go开发环境

Windows安装Go开发环境 一、Go语言下载地址 https://golang.google.cn/dl/ 二、设置工作空间GOPATH目录(Go语言开发的项目路径) 首先进入我的C盘&#xff08;你放到其他盘也行&#xff09;&#xff0c;新建一个文件夹&#xff0c;名字叫做mygo&#xff08;这个就是你的工作目…

通讯录的实现

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大一&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 望小伙伴们点赞&#x1f44d;收藏✨加关注哟&#x1f495;&#x1…

LED电子显示屏信号传输方式

LED电子显示屏广泛应用在休闲文化广场、繁华商贸中心、商业街、火车站、地铁、商场、等场所。由于其应用领域的多样性、复杂性&#xff0c;对音视频信号传输的稳定、可靠、流畅性也提出了更高的要求。单屏播放&#xff0c;亦或是组网联播等场合下全彩LED显示屏的信号采用的传输…

独立站SEO是什么意思?自主网站SEO的含义?

什么是独立站SEO优化&#xff1f;自建站搜索引擎优化是指什么&#xff1f; 独立站SEO&#xff0c;作为网络营销的重要一环&#xff0c;正在逐渐引起人们的关注。在当今数字化时代&#xff0c;独立站已经成为许多企业、个人宣传推广的首选平台之一。那么&#xff0c;究竟什么是…

C++对象模型实验(clang虚函数表结构)

摘要&#xff1a;本科期间有对比过msvc&#xff0c;gcc&#xff0c;clang的内存布局&#xff0c;距今已经6-7年了&#xff0c;当时还是使用的c11。时间过得比较久了&#xff0c;这部分内容特别是内存对齐似乎C17发生了一些变化&#xff0c;因此再实践下C类模型。本文描述了C不同…

docker优点简介和yum方式安装

一.docker简介 二.docker的优点 1.交付和部署速度快 2.高效虚拟化 3.迁移性和扩展性强 4.管理简单 三.docker的基本概念 1.镜像 2.容器 3.仓库 四.docker的安装部署 &#xff08;1&#xff09;点击容器 ​&#xff08;2&#xff09;选择docker-ce&#xff0c;根据相…

[C语言]分支语句和循环语句

[C语言]分支语句和循环语句 文章目录 [C语言]分支语句和循环语句C语言语句分类分支语句if语法结构else的匹配规则switch语句switch语句中的breakswitch语句中default 循环语句while循环while循环中的break和continuefor循环for循环中的break和continuefor循环的变种do while循环…

【腾讯云Cloud Studio实战训练营】用Vue+Vite快速构建完成交互式3D小故事

&#x1f440;前置了解&#xff1a;(官网 https://cloudstudio.net/) 什么是Cloud Studio&#xff1f; Cloud Studio 是基于浏览器的集成式开发环境&#xff08;IDE&#xff09;&#xff0c;为开发者提供了一个永不间断的云端工作站。用户在使用 Cloud Studio 时无需安装&#…

refresh大揽

注意在每一步大操作之前都有一个前期准备 prepareRefresh&#xff08;&#xff09; 设置spring启动的时间 设置spring关闭和开启的标志位 获取环境对象&#xff0c;并设置一些属性值&#xff0c;是系统环境的不是xml设置的 设置监听器&#xff0c;以及需要发布事件的集合。 Con…

浅析Java设计模式之四策略模式

title: 浅析Java设计模式之四策略模式 date: 2018-12-29 17:26:17 categories: 设计模式 description: 浅析Java设计模式之四策略模式 1. 目录 1. 目录2. 概念 2.1. 应用场景2.2. 优缺点 2.2.1. 优点2.2.2. 缺点 3. 模式结构4. 样例 4.1. 定义策略4.2. 定义具体策略4.3. 定义…

【自动电压调节器】无功功率控制的终端电压控制研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【IMX6ULL驱动开发学习】07.驱动程序分离的思想之平台总线设备驱动模型和设备树

一、驱动程序分离的思想 【IMX6ULL驱动开发学习】05.字符设备驱动开发模板&#xff08;包括读写函数、poll机制、异步通知、定时器、中断、自动创建设备节点和环形缓冲区&#xff09;_阿龙还在写代码的博客-CSDN博客 之前编写驱动程序的代码存在不少弊端&#xff1a;移植性差…

Redis从基础到进阶篇(一)

目录 一、了解NoSql 1.1 什么是Nosql 1.2 为什么要使用NoSql 1.3 NoSql数据库的优势 1.4 常见的NoSql产品 1.5 各产品的区别 二、Redis介绍 2.1什么是Redis 2.2 Redis优势 2.3 Redis应用场景 2.4 Redis下载 三、Linux下安装Redis 3.1 环境准备 3.2 Redis的…

广告牌安全传感器,实时监测事故隐患尽在掌握

在现代城市中&#xff0c;广告牌作为商业宣传的重要媒介&#xff0c;已然成为城市中一道独特的风景线。然而&#xff0c;随着城市迅速发展&#xff0c;广告牌的安全问题也引起了大众关注。广告招牌一般悬挂于建筑物高处&#xff0c;量大面大。由于设计、材料、施工方法的缺陷&a…

windows电脑系统自带的画图工具如何实现自由拼图

1.首先选中你要拼接的第一张图片&#xff0c;右键选着编辑&#xff0c;会自动打开自带的画图工具 然后就是打开第一张图片&#xff0c;如下图所示 接着就是将画布托大&#xff0c;如下图所示。 然后点击选择&#xff0c;选择下面的空白区域&#xff0c;选着区域的范围要比准备拼…

企微配置回调服务

1、企微配置可信域名 2、企微获取成员userID 3、企微获取用户敏感数据 4、企微配置回调服务 文章目录 一、简介1、概述2、相关文档地址 二、企微配置消息服务器1、配置消息接收参数2、参数解析3、参数拼接规则 三、代码编写—使用已有库1、代码下载2、代码修改3、服务代码编写 …