Unity进阶–通过PhotonServer实现人物移动和攻击–PhotonServer(五)

2023-10-27

Unity进阶–通过PhotonServer实现人物移动和攻击–PhotonServer(五)

DLc: 消息类和通信类

  • Message

    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_UI = 0;
       
            //账号登录注册
            public const byte Type_Account = 1;
            //用户
            public const byte Type_User = 2;
            //攻击
            public const byte Type_Battle = 3;
    
            //注册账号
            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 = 204; 
            public const int User_Select_res = 205; 
            public const int User_Create_Event = 206;
            //删除角色
            public const int User_Remove_Event = 207;
    
            //攻击和移动
            //移动point[]
            public const int Battle_Move = 301;
            //移动响应id point[]
            public const int Battle_Move_Event = 302;
            //攻击 targetid
            public const int Battle_Attack = 303;
            //攻击响应id targetid 剩余血量
            public const int Battle_Attack_Event = 304;
    
    
        }
    }
    
    
    • peer类

      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:
                          //PSTest.log.Info("收到客户端的登陆消息");
                          BLLManager.Instance.accountBLL.OnOperationRequest(this, message); 
                          break;
                      case MessageType.Type_User:
                          BLLManager.Instance.userBLL.OnOperationRequest(this, message);
                          break;
                      case MessageType.Type_Battle:
                          PSTest.log.Info("收到攻击移动命令");
                          BLLManager.Instance.battleMoveBLL.OnOperationRequest(this, message);
                          break;
                  }
              }
          }
      }
      
      
  • 客户端对接类

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using ExitGames.Client.Photon;
    using Net;
    
    public class PhotonManager : MyrSingletonBase<PhotonManager>, IPhotonPeerListener
    {
        private  PhotonPeer peer;
        
        void Awake() {
            base.Awake();
            DontDestroyOnLoad(this);
        }
        // Start is called before the first frame update
        void Start()
        {
            peer = new PhotonPeer(this, ConnectionProtocol.Tcp);
            peer.Connect("127.0.0.1:4530", "PhotonServerFirst");
        }
    
        void Update()
        {
            peer.Service();
        }
    
        private void OnDestroy() {
            base.OnDestroy();
            //断开连接
            peer.Disconnect();    
        }
    
        public void DebugReturn(DebugLevel level, string message)
        {
    
        }
    
        /// <summary>
        /// 接收服务器事件
        /// </summary>
        /// <param name="eventData"></param>
        public void OnEvent(EventData eventData)
        {
            
            //拆包
            Message msg = new Message();
            msg.Type = (byte)eventData.Parameters[0];
            msg.Command = (int)eventData. Parameters[1];
            List<object> list = new List<object>();
            for (byte i = 2; i < eventData.Parameters.Count; i++){
                list.Add(eventData.Parameters[i]);
            }
            msg.Content = list.ToArray();
            MessageCenter.SendMessage(msg);
        }
    
        /// <summary>
        /// 接收服务器响应
        /// </summary>
        /// <param name="operationResponse"></param>
        public void OnOperationResponse(OperationResponse operationResponse)
        {
            if (operationResponse.OperationCode == 1){
                Debug.Log(operationResponse.Parameters[1]);
            }
    
        }
    
        /// <summary>
        /// 状态改变
        /// </summary>
        /// <param name="statusCode"></param>
        public void OnStatusChanged(StatusCode statusCode)
        {
            Debug.Log(statusCode);
        }
    
        /// <summary>
        /// 发送消息
        /// </summary>
        public void Send(byte type, int command, params object[] objs)
        {
            Dictionary<byte, object> dic = new Dictionary<byte,object>();
            dic.Add(0,type);
            dic.Add(1,command);
            byte i = 2;
            foreach (object o in objs){
                dic.Add(i++, o);
            }
            peer.OpCustom(0, dic, true);
        }
    
    }
    
    

服务器

  • BLL管理

    using PhotonServerFirst.Bll.BattleMove;
    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;
            //移动和攻击管理
            public IMessageHandler battleMoveBLL;
        private BLLManager()
        {
            accountBLL = new PhsotonServerFirst.Bll.Account.AccountBLL();
            userBLL = new UserBLL();
            battleMoveBLL = new BattleMoveBLL();
        }
    
    }
    

    }

  • 移动BLL

    using Net;
    using PhotonServerFirst.Dal;
    using PhotonServerFirst.Model.User;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace PhotonServerFirst.Bll.BattleMove
    {
        class BattleMoveBLL : IMessageHandler
        {
            public void OnDisconnect(PSPeer peer)
            {
                
            }
    
            public void OnOperationRequest(PSPeer peer, Message message)
            {
                object[] objs = (object[])message.Content; 
                switch (message.Command)
                {
                    case MessageType.Battle_Move:
                        PSTest.log.Info("BattleMove收到移动命令");
                        Move(peer, objs);
                        break;
                    case MessageType.Battle_Attack:
                        Attack(peer, objs);
                        break;
                }
    
            }
    
            private void Attack(PSPeer peer, object[] objs)
            {
                //targetid
                //id targetid 剩余血量
                int targetid = (int)objs[0];
                //攻击者
                UserModel user = DALManager.Instance.userDAL.GetUserModel(peer);
                //被攻击者
                UserModel targetUser = DALManager.Instance.userDAL.GetUserModel(targetid);
                //计算伤害
                targetUser.Hp -= user.userInfo.Attack;
                foreach (PSPeer otherpeer in DALManager.Instance.userDAL.GetuserPeers())
                {
                    SendMessage.Send(otherpeer, MessageType.Type_Battle, MessageType.Battle_Attack_Event, user.ID, targetUser.ID, targetUser.Hp);
                }
            }
    
                private void Move(PSPeer peer, object[] objs)
                {
                    //位置
                    float[] points = (float[])objs[0];
                    //将要移动的客户端
                    UserModel user = DALManager.Instance.userDAL.GetUserModel(peer); 
                    user.Points = points;
                    //通知所有客户端移动
                    foreach (PSPeer otherpeer in DALManager.Instance.userDAL.GetuserPeers())
                    {
                    PSTest.log.Info("通知所有客户端移动");
                        SendMessage.Send(otherpeer, MessageType.Type_Battle, MessageType.Battle_Move_Event, user.ID, points);
    
                    }
                }
        }
    }
    
    

客户端

  • 逻辑类

    using System.Collections;
    using System.Collections.Generic;
    using Net;
    using UnityEngine;
    
    public class BattleManager : ManagerBase
    {
        void Start() {
            MessageCenter.Instance.Register(this);
        }
        private UserControll user;
        public UserControll User{
            get{
                if (user == null){
                    user = UserControll.idUserDic[UserControll.ID];
                }
                return user;
            }
        }
    
        void Update()
        {
            if (Input.GetMouseButtonDown(0)){
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
                bool res = Physics.Raycast(ray, out hit);
                if (res)
                {
                    if (hit.collider.tag =="Ground"){
                        //Debug.Log("点击到地面");
                        //移动到hit.point
                        PhotonManager.Instance.Send(MessageType.Type_Battle, MessageType.Battle_Move, new float[] { hit.point.x,hit.point.y, hit.point.z });
                        //Debug.Log(hit.point);
                    }
                    if (hit.collider.tag =="User"){
                        //Debug.Log("点击到玩家");
                        //获取距离
                        float dis = Vector3.Distance(hit.collider.transform.position, User.transform.position);
                        if (dis > 0 && dis < 3f){
                            UserControll targetUser = hit.collider.GetComponent<UserControll>();
                            PhotonManager.Instance.Send(MessageType.Type_Battle, MessageType.Battle_Attack, targetUser.id);
                        }
                    }
               }
            }
        }
    
        public override void ReceiveMessage(Message message){
            base.ReceiveMessage(message);
            object[] objs = (object[])message.Content;
            switch (message. Command)
            {
                case MessageType.Battle_Move_Event:
                Debug.Log("移动");
                    Move(objs);
                    break;
                case MessageType.Battle_Attack_Event:
                    Attack(objs);
                    break;
            }
        }
    
    
        //移动
        void Move(object[] objs){
            //移动的用户id
            int userid = (int)objs[0];
            //移动的位置
            float[] points = (float[])objs[1];
            UserControll.idUserDic[ userid].Move(new Vector3(points[0],points[1],points[2]));
        }
    
        public override byte GetMessageType(){
            return MessageType.Type_Battle;
        }
    
        public void Attack(object[] objs){
            //攻击者id被攻击者id 当前剩余血量
            int userid = (int)objs[0];
            int targetid = (int)objs[1];
            int hp = (int)objs[2];
            //攻击
            UserControll.idUserDic[userid].Attack(targetid);
            if (hp <= 0)
            {
                UserControll.idUserDic[targetid].Die();
            }
        }
    
    }
    
    
  • 角色绑定的类

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;
    
    public class UserControll : MonoBehaviour
    {
        //保存了所有角色的集合
        public static Dictionary<int, UserControll> idUserDic = new Dictionary<int, UserControll>();
        //当前客户端角色的id
        public static int ID;
        private Animator ani;
        //private NavMeshAgent agent;
        //目标位置
        private Vector3 targetPos;
        private bool isRun;
        //角色id
        public int id;
        private bool isDie;
    
        // Start is called before the first frame update
        void Start()
        {
            ani = GetComponent<Animator>();
            //agent = GetComponent<NavMeshAgent>();
        }
    
        // Update is called once per frame
        void Update()
        {
            if(isDie){
                return;
            }
            if (isRun){
                //计算距离
                float dis = Vector3.Distance(transform. position,targetPos);
                if (dis > 0.5f)
                {
                    //移动
                    //agent.isStopped = false;
                   // ani.SetBoo1( "IsRun", true);
                    //agent.SetDestination(targetPos);
                    transform.position = targetPos;
                }
                else
                {
                    //停止
                    //agent.isStopped = true;
                   // ani.setBoo1("IsRun", false);
                    isRun = false;
                }
            }
    
        }
        public void Move(Vector3 target){
            targetPos = target;
            isRun = true;
        }
    
        public void Attack( int targetId){
            //获得要攻击的角色
            UserControll targetUser = idUserDic[targetId];
            transform.LookAt(targetUser.transform);
            //ani.SetTrigger( "Attack");
        }
    
        public void Die(){
            //ani. setTrigger("Die");
            isDie = true;
        }
    
    }
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;
    
    public class UserControll : MonoBehaviour
    {
        //保存了所有角色的集合
        public static Dictionary<int, UserControll> idUserDic = new Dictionary<int, UserControll>();
        //当前客户端角色的id
        public static int ID;
        private Animator ani;
        //private NavMeshAgent agent;
        //目标位置
        private Vector3 targetPos;
        private bool isRun;
        //角色id
        public int id;
        private bool isDie;
    
        // Start is called before the first frame update
        void Start()
        {
            ani = GetComponent<Animator>();
            //agent = GetComponent<NavMeshAgent>();
        }
    
        // Update is called once per frame
        void Update()
        {
            if(isDie){
                return;
            }
            if (isRun){
                //计算距离
                float dis = Vector3.Distance(transform. position,targetPos);
                if (dis > 0.5f)
                {
                    //移动
                    //agent.isStopped = false;
                   // ani.SetBoo1( "IsRun", true);
                    //agent.SetDestination(targetPos);
                    transform.position = targetPos;
                }
                else
                {
                    //停止
                    //agent.isStopped = true;
                   // ani.setBoo1("IsRun", false);
                    isRun = false;
                }
            }
    
        }
        public void Move(Vector3 target){
            targetPos = target;
            isRun = true;
        }
    
        public void Attack( int targetId){
            //获得要攻击的角色
            UserControll targetUser = idUserDic[targetId];
            transform.LookAt(targetUser.transform);
            //ani.SetTrigger( "Attack");
        }
    
        public void Die(){
            //ani. setTrigger("Die");
            isDie = true;
        }
    
    }
    
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity进阶–通过PhotonServer实现人物移动和攻击–PhotonServer(五) 的相关文章

随机推荐

  • Simulink单元测试

    本文使用Matlab2018a版本 一 主要使用Simulink中的Analysis下的Test Harness和Test Manager 1 创建Test Harness 前提 有测试模型 1 在测试模型里 直接右击 gt Test Ha
  • Ubuntu 18.04安装CUDA 11.4.0 cuDNN 8.2.2

    CUDA和cuDNN为NVIDIA支持GPU运算以及深度神经网络计算加速的算法库 通常需要安装以支持利用GPU加速神经网络的训练和推理 安装前需要确定主机显卡为NVIDIA显卡 且驱动安装无误 通过nvidia smi查看显卡信息和适合的C
  • 使用pyLDAvis可视化LDA结果,与解决FileNotFoundError: [Errno 2] No such file or directory: ‘https://cdn.jsdel....

    建议安装 pip install pyLDAvis 2 1 2 否则会报错 FileNotFoundError Errno 2 No such file or directory https cdn jsdelivr net gh bmab
  • java math类 平方_Java Math类

    首页 gt 基础教程 gt 常用类 gt 常用 Number Math类 Java Math类 Java 的 Math 包含了用于执行基本数学运算的属性和方法 如初等指数 对数 平方根和三角函数 这些方法基本可以分为三类 三角函数方法 指数
  • 深入理解Java虚拟机jvm-对象如何进入老年代

    HotSpot虚拟机中多数收集器都采用了分代收集来管理堆内存 那内存回收时就必须能决策哪些存 活对象应当放在新生代 哪些存活对象放在老年代中 为做到这点 虚拟机给每个对象定义了一个对象年龄 Age 计数器 存储在对象头中 对象通常在Eden
  • 视频插帧—学习笔记(算法+配置+云服务+Google-Colab)

    恰好碰到同学项目需要 了解了一下关于利用深度学习视频插帧的相关知识 在这里做一个简单的记录 目录 一 方法 论文 1 DAIN Depth Aware Video Frame Interpolation 2 FLAVR Flow Agnos
  • 自己动手实现简易STL

    自己动手实现简易STL STL六个组件 迭代器 算法 容器 迭代器部分 适配器 仿函数 额外的工作 小结 之前学习C 看侯老师的书的时候实现了一下STL的基本组件 包括了6个组件 allocator iterator container t
  • buuctf/re/近日总结/rome,pyre等(详细解释)

    rome 检测到无壳 32位 直接用IDA打开 转到main函数 int func int result eax int v1 4 esp 14h ebp 44h unsigned int8 v2 esp 24h ebp 34h BYREF
  • Pandas方法(未完待续....)

    DataFrame方法参数解释 dropna axis 0 how any thresh None subset None inplace False axis 默认0 0代表行 1代表列 how 有all 或者 any all全部为NA则
  • 体验vSphere 6之1-安装VMware ESXi 6 RC版

    体验vSphere 6之1 安装VMware ESXi 6 RC版 在2015年 各个公司都会发布一系列新的产品 例如Microsoft会发布Windows 10 VMware会发布vSphere 6系列 现在这些产品都已经有了测试版 今天
  • LLVM系列第十六章:写一个简单的编译器

    系列文章目录 LLVM系列第一章 编译LLVM源码 LLVM系列第二章 模块Module LLVM系列第三章 函数Function LLVM系列第四章 逻辑代码块Block LLVM系列第五章 全局变量Global Variable LLV
  • 用 flex 和 瀑布流 解决高度不同的元素浮动导致页面混乱问题

    当元素的高度各不相同并且设置了浮动 页面展示如下 flex布局 瀑布流布局 瀑布流动态加载图片 flex布局 红框所画图片在第一行放不下 属于第二行的元素 但是由于浮动的特性 导致它出现在了这个位置 如果想让它另起一行顶头展示 可以使用fl
  • 1.3 Linux文件系统

    一 Linux文件系统结构 Linux下都是文件 所以没有Windows一样的盘 有的只有文件夹 cd 进入根目录 ls 查看根目录 下的文件及文件夹 bin 存储了很多系统命令 usr sbin 也存储了许多系统命令 sbin 超级用户
  • MODBUS协议中的CRC校验

    一 RTU 檢查碼 CRC 計算器 第一种 RTU 檢查碼 CRC 計算器 大小端转换后 CRC检查码为 AB 89 说明 这个计算器还是可以用的 第二种 On line CRC calculation and free library 二
  • odoo.service.server: Thread <Thread(odoo.service.cron.cron0, started daemon 139767179863808)> virtua

    这个日志消息表示在 Odoo 服务器的某个线程中达到了虚拟实时限制 具体来说 这是在执行某个任务时 线程使用了超过允许的时间限制 日志中的详细信息包括 时间戳 2023 09 03 14 24 55 333 19479 警告级别 WARNI
  • spring mvc踩坑 - jackson解析框架返回json多一层双引号

    问题 两套业务逻辑代码相同 但返回的数据不同 导致相同的前端代码用eval解析时出错 其中一个多了一层双引号 分别为 aaa 1 aaa 1 服务端代码 RequestMapping method RequestMethod POST pa
  • sqli labs less 21

    这题与less 20 相似 只不过cookie需要经过base64 编码之后才能注入 这一题就是比较麻烦其他没啥 还有就是 闭合语句 admin2 union select 1 2 3 base64编码为 YWRtaW4yJykgdW5pb
  • 单向循环链表(如何实现约瑟夫环)

    约瑟夫问题 总共有n个人排成一圈 从某个人开始 按顺时针方向依次编号 从编号为1的人开始顺时针报数1 下一个报号2 报到m的人退出圈子然后重新从1开始顺时针报数 这样不断循环下去 圈子里的人将不断减少 要求全部人员输出退出顺序 includ
  • chatGPT对企业的发展有什么影响

    ChatGPT目前正在全世界范围内掀起风暴 成为炙手可热的一个名词 作为基于人工智能的工具的最新产品 目前ChatGPT呈现给我们的似乎只是足够有趣 且从目前已知的信息来看 它似乎还没有任何商业运作相关的计划 大多应用聚焦在其可以撰写论文
  • Unity进阶–通过PhotonServer实现人物移动和攻击–PhotonServer(五)

    文章目录 Unity进阶 通过PhotonServer实现人物移动和攻击 PhotonServer 五 DLc 消息类和通信类 服务器 客户端 Unity进阶 通过PhotonServer实现人物移动和攻击 PhotonServer 五 D