当前位置: 首页 > 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),它需要一个交互界面,一般…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...