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

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

文章目录

  • Unity进阶–通过PhotonServer实现人物移动和攻击–PhotonServer(五)
    • DLc: 消息类和通信类
    • 服务器
    • 客户端

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;//攻击 targetidpublic 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;//打包,转为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://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 updatevoid 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.pointPhotonManager.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){//移动的用户idint 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>();//当前客户端角色的idpublic static int ID;private Animator ani;//private NavMeshAgent agent;//目标位置private Vector3 targetPos;private bool isRun;//角色idpublic int id;private bool isDie;// Start is called before the first frame updatevoid Start(){ani = GetComponent<Animator>();//agent = GetComponent<NavMeshAgent>();}// Update is called once per framevoid 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>();//当前客户端角色的idpublic static int ID;private Animator ani;//private NavMeshAgent agent;//目标位置private Vector3 targetPos;private bool isRun;//角色idpublic int id;private bool isDie;// Start is called before the first frame updatevoid Start(){ani = GetComponent<Animator>();//agent = GetComponent<NavMeshAgent>();}// Update is called once per framevoid 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;}}

相关文章:

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

文章目录 Unity进阶–通过PhotonServer实现人物移动和攻击–PhotonServer(五)DLc&#xff1a; 消息类和通信类服务器客户端 Unity进阶–通过PhotonServer实现人物移动和攻击–PhotonServer(五) DLc&#xff1a; 消息类和通信类 Message namespace Net {public class Message{p…...

中间件: Redis安装与部署

单机部署 yum install -y epel-release yum install -y redissed -i "s/bind 127.0.0.1/bind 0.0.0.0/g" /etc/redis.conf sed -i "s/# requirepass foobared/requirepass abcd1234/g" /etc/redis.conf systemctl restart redis集群部署 启动6个redis节点…...

Java日志框架-JUL

JUL全称Java util logging 入门案例 先来看着入门案例&#xff0c;直接创建logger对象&#xff0c;然后传入日志级别和打印的信息&#xff0c;就能在控制台输出信息。 可以看出只输出了部分的信息&#xff0c;其实默认的日志控制器是有一个默认的日志级别的&#xff0c;默认就…...

【Java】智慧工地SaaS平台源码:AI/云计算/物联网/智慧监管

智慧工地是指运用信息化手段&#xff0c;围绕施工过程管理&#xff0c;建立互联协同、智能生产、科学管理的施工项目信息化生态圈&#xff0c;并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析&#xff0c;提供过程趋势预测及专家预案&#xff0c;实现工程…...

Dodaf架构的学习分享

一.Dodaf的内容 Dodaf的背景 DODAF&#xff08;Department of Defense Architecture Framework&#xff09;起源于美国国防部&#xff0c;是一个用于支持复杂系统设计、规划和实施的架构框架。以下是DODAF的背景和起源&#xff1a; 复杂系统需求&#xff1a;在军事和国防领域&…...

听GPT 讲Prometheus源代码--discovery

Prometheus是一个开源的系统监控和警报工具包&#xff0c;以下是Prometheus源代码中一些主要的文件夹及其作用&#xff1a; cmd/&#xff1a;这个目录包含了Prometheus主要的命令行工具&#xff0c;如prometheus/&#xff0c;promtool/等。每个子目录都代表一个可执行的命令行应…...

HTTP 介绍

HTTP 介绍 HTTP 协议一般指 HTTP&#xff08;超文本传输协议&#xff09;。超文本传输协议&#xff08;英语&#xff1a;HyperText Transfer Protocol&#xff0c;缩写&#xff1a;HTTP&#xff09;是一种用于分布式、协作式和超媒体信息系统的应用层协议&#xff0c;是因特网…...

Rust语言深入解析:后向和前向链接算法的实现与应用

内容 - 第一部分 (1/3)&#xff1a; Rust&#xff0c;作为一个旨在提供安全、并行和高性能的系统编程语言&#xff0c;为开发者带来了独特的编程模式和工具。其中&#xff0c;对于数据结构和算法的实现&#xff0c;Rust提供了一套强大的机制。本文将详细介绍如何在Rust中实现后…...

快速提高写作生产力——使用PicGo+Github搭建免费图床,并结合Typora

文章目录 简述PicGo下载PicGo获取Token配置PicGo结合Typora总结 简述PicGo PicGo: 一个用于快速上传图片并获取图片 URL 链接的工具 PicGo 本体支持如下图床&#xff1a; 七牛图床 v1.0腾讯云 COS v4\v5 版本 v1.1 & v1.5.0又拍云 v1.2.0GitHub v1.5.0SM.MS V2 v2.3.0-b…...

Java方法的参数可以有默认值吗?

在日常web开发这种&#xff0c;controller层接受参数时可以通过RequestParam(requiredfalse)设置参数非必填。 所以就想Java的方法可以有非必填这种操作吗&#xff1f;网上搜了一下&#xff0c;发现不支持这种操作。 可以通过方法重载的方式来变相实现。不需要传这个参数就会…...

电子商务的安全防范

(1)安全协议问题&#xff1a;我国大多数尚处在 SSL&#xff08;安全套接层协议&#xff09;的应用上&#xff0c;SET 协议的应用还只是刚刚试验成功&#xff0c;在信息的安全保密体制上还不成熟&#xff0c;对安全协议 还没有全球性的标准和规范&#xff0c;相对制约了国际性…...

STM32开关输入控制220V灯泡亮灭源代码(附带PROTEUSd电路图)

//main.c文件 /* USER CODE BEGIN Header */ /********************************************************************************* file : main.c* brief : Main program body************************************************************************…...

Spring Boot配置文件

目录 1.配置文件的作用 2.配置文件的格式 3.properties配置文件说明 3.1 properties基本语法 3.2 读取配置文件信息 3.3 properties 缺点分析 4.yml 配置⽂件说明 4.1 yml 基本语法 4.2 yml 使⽤进阶 4.2.1 yml 配置不同数据类型及 null 4.2.2 配置对象 5.propert…...

函数(2)

6. 函数的声明和定义 6.1 函数声明&#xff1a; 1. 告诉编译器有一个函数叫什么&#xff0c;参数是什么&#xff0c;返回类型是什么。但是具体是不是存在&#xff0c;函数 声明决定不了。 2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。 3. 函数的声明一般要放…...

Linux笔试题(4)

67、在局域网络内的某台主机用ping命令测试网络连接时发现网络内部的主机都可以连同,而不能与公网连通,问题可能是__C_ A.主机ip设置有误 B.没有设置连接局域网的网关 C.局域网的网关或主机的网关设置有误 D.局域网DNS服务器设置有误 解析&#xff1a;在局域网络内的某台主…...

Selenium的使用:WEB功能测试

Selenium是ThrougthWorks公司一个强大的开源WEB功能测试工具系列&#xff0c;本系统包括多款软件 Selenium语言简单&#xff0c;用(Command,target,value)三种元素组成一个行为&#xff0c;并且有协助录制脚本工具&#xff0c;但Selenese有一些严格的限制&#xff1a; …...

Kubernetes(K8s)从入门到精通系列之十七:minikube启动K8s dashboard

Kubernetes K8s从入门到精通系列之十七:minikube启动K8s dashboard 一、安装minikube的详细步骤二、查看Pod三、启动dashboard四、创建代理访问dashboard五、远程访问dashboard一、安装minikube的详细步骤 Kubernetes(K8s)从入门到精通系列之十六:linux服务器安装minikube的详…...

C++ 网络编程项目fastDFS分布式文件系统(五)--nginx+fastdfs

目录 1. 文件上传下载流程 2. Nginx和fastDFS的整合 3. 数据库表 3.1 数据库操 3.2 数据库建表 1. 文件上传下载流程 fileID 需要是一个哈希来判定。 2. 文件下载流程 3. 优化 优化思路 : 直接让客户端连接 fastDFS 的存储节点 , 实现文件下载 举例 , 访问一个…...

开发者本地搭建性能监测工具(Windows)

ElasticSearch 8.9.0 开发模式安装 JDK安装 官方提供版本与JDK支持关系&#xff1a;https://www.elastic.co/cn/support/matrix#matrix_jvm 我们安装Elasticsearch 8.9.x&#xff0c;看到支持的最低JDK版本是17。 JDK&#xff08;Windows/Mac含M1/M2 Arm原生JDK&#xff09;…...

嵌入式Linux开发实操(八):UART串口开发

串口可以说是非常好用的一个接口,它同USB、CAN、I2C、SPI等接口一样,为SOC/MCU构建了丰富的接口功能。那么在嵌入式linux中又是如何搭建和使用UART接口的呢? 一、Console接口即ttyS0 ttyS0通常做为u-boot(bootloader的一种,像是Windows的BIOS),它需要一个交互界面,一般…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...