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

Unity实战案例全解析:RTS游戏的框选和阵型功能(4)阵型功能

前篇:Unity实战案例全解析:RTS游戏的框选和阵型功能(3)生成范围检测框 +重置框选操作-CSDN博客

本案例来源于unity唐老狮,有兴趣的小伙伴可以去泰克在线观看该课程

我只是对重要功能进行分析和做出笔记分享,并未无师自通,吃水不忘打井人

本案例的实现流程图 

本节实现效果

分析

选中士兵数量和布阵方式

如何实现呢?如果没有分析出算法就用switch语句一个一个去规定,如果分析出了算法直接根据框选中的士兵数量实现即可

容易忽略的关键变量

士兵前进的方向该如何确定?

可以根据当前的位置frontPos指向target

如果是第一移动,那frontPos就设置为当前士兵的位置

当下次一达到目的地以后,就将上一个位置 =当前的目标位置即可

最后每一次重置框选后,可以重置一下frontPo

  nowRigth = Quaternion.Euler(0, 90, 0) * nowForward;

s

 

 计算布局函数

这里面定义了一个偏移量用来设置士兵之间的间隔

   //士兵之间的间隔距离private float soldierOffset = 3;

还定义了一个当前朝向的右向量用来计算位置

    /// <summary>/// 根据鼠标点击的目标点 计算出 阵型的其它点位/// </summary>/// <param name="targetPos"></param>/// <returns></returns>private List<Vector3> GetTargetPos(Vector3 targetPos){//需要计算目标点 的 面朝向和 右朝向Vector3 nowForward = Vector3.zero;Vector3 nowRigth = Vector3.zero;//是一批士兵 上一次已经移动过一次了 有上一次的位置if(frontPos != Vector3.zero)nowForward = (targetPos - frontPos).normalized;//有上一次的点 就直接计算else//没有上一次的点 就用第一个士兵的位置 作为上一次的点来计算nowForward = (targetPos - soldierObjs[0].transform.position).normalized;//根据面朝向 得到右朝向 旋转y轴 90度nowRigth = Quaternion.Euler(0, 90, 0) * nowForward;List<Vector3> targetsPos = new List<Vector3>();switch (soldierObjs.Count){case 1:targetsPos.Add(targetPos);break;case 2:targetsPos.Add(targetPos + nowRigth * soldierOffset / 2);targetsPos.Add(targetPos - nowRigth * soldierOffset / 2);break;case 3:targetsPos.Add(targetPos);targetsPos.Add(targetPos + nowRigth * soldierOffset);targetsPos.Add(targetPos - nowRigth * soldierOffset);break;case 4:targetsPos.Add(targetPos + nowForward * soldierOffset / 2 - nowRigth * soldierOffset / 2);targetsPos.Add(targetPos + nowForward * soldierOffset / 2 + nowRigth * soldierOffset / 2);targetsPos.Add(targetPos - nowForward * soldierOffset / 2 - nowRigth * soldierOffset / 2);targetsPos.Add(targetPos - nowForward * soldierOffset / 2 + nowRigth * soldierOffset / 2);break;case 5:targetsPos.Add(targetPos + nowForward * soldierOffset / 2);targetsPos.Add(targetPos + nowForward * soldierOffset / 2 - nowRigth * soldierOffset);targetsPos.Add(targetPos + nowForward * soldierOffset / 2 + nowRigth * soldierOffset);targetsPos.Add(targetPos - nowForward * soldierOffset / 2 - nowRigth * soldierOffset);targetsPos.Add(targetPos - nowForward * soldierOffset / 2 + nowRigth * soldierOffset);break;case 6:targetsPos.Add(targetPos + nowForward * soldierOffset / 2);targetsPos.Add(targetPos + nowForward * soldierOffset / 2 - nowRigth * soldierOffset);targetsPos.Add(targetPos + nowForward * soldierOffset / 2 + nowRigth * soldierOffset);targetsPos.Add(targetPos - nowForward * soldierOffset / 2 - nowRigth * soldierOffset);targetsPos.Add(targetPos - nowForward * soldierOffset / 2 + nowRigth * soldierOffset);targetsPos.Add(targetPos - nowForward * soldierOffset / 2);break;case 7:targetsPos.Add(targetPos + nowForward * soldierOffset);targetsPos.Add(targetPos + nowForward * soldierOffset - nowRigth * soldierOffset);targetsPos.Add(targetPos + nowForward * soldierOffset + nowRigth * soldierOffset);targetsPos.Add(targetPos - nowRigth * soldierOffset);targetsPos.Add(targetPos + nowRigth * soldierOffset);targetsPos.Add(targetPos);targetsPos.Add(targetPos - nowForward * soldierOffset);break;case 8:targetsPos.Add(targetPos + nowForward * soldierOffset);targetsPos.Add(targetPos + nowForward * soldierOffset - nowRigth * soldierOffset);targetsPos.Add(targetPos + nowForward * soldierOffset + nowRigth * soldierOffset);targetsPos.Add(targetPos - nowRigth * soldierOffset);targetsPos.Add(targetPos + nowRigth * soldierOffset);targetsPos.Add(targetPos);targetsPos.Add(targetPos - nowForward * soldierOffset - nowRigth * soldierOffset);targetsPos.Add(targetPos - nowForward * soldierOffset + nowRigth * soldierOffset);break;case 9:targetsPos.Add(targetPos + nowForward * soldierOffset);targetsPos.Add(targetPos + nowForward * soldierOffset - nowRigth * soldierOffset);targetsPos.Add(targetPos + nowForward * soldierOffset + nowRigth * soldierOffset);targetsPos.Add(targetPos - nowRigth * soldierOffset);targetsPos.Add(targetPos + nowRigth * soldierOffset);targetsPos.Add(targetPos);targetsPos.Add(targetPos - nowForward * soldierOffset - nowRigth * soldierOffset);targetsPos.Add(targetPos - nowForward * soldierOffset + nowRigth * soldierOffset);targetsPos.Add(targetPos - nowForward * soldierOffset);break;case 10:targetsPos.Add(targetPos + nowForward * soldierOffset - nowRigth * soldierOffset / 2);targetsPos.Add(targetPos + nowForward * soldierOffset + nowRigth * soldierOffset / 2);targetsPos.Add(targetPos + nowForward * soldierOffset - nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos + nowForward * soldierOffset + nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos + nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowRigth * soldierOffset / 2);targetsPos.Add(targetPos + nowRigth * soldierOffset / 2);targetsPos.Add(targetPos - nowForward * soldierOffset - nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowForward * soldierOffset + nowRigth * soldierOffset * 1.5f);break;case 11:targetsPos.Add(targetPos + nowForward * soldierOffset - nowRigth * soldierOffset / 2);targetsPos.Add(targetPos + nowForward * soldierOffset + nowRigth * soldierOffset / 2);targetsPos.Add(targetPos + nowForward * soldierOffset - nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos + nowForward * soldierOffset + nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos + nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowRigth * soldierOffset / 2);targetsPos.Add(targetPos + nowRigth * soldierOffset / 2);targetsPos.Add(targetPos - nowForward * soldierOffset - nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowForward * soldierOffset + nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowForward * soldierOffset);break;case 12:targetsPos.Add(targetPos + nowForward * soldierOffset - nowRigth * soldierOffset / 2);targetsPos.Add(targetPos + nowForward * soldierOffset + nowRigth * soldierOffset / 2);targetsPos.Add(targetPos + nowForward * soldierOffset - nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos + nowForward * soldierOffset + nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos + nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowRigth * soldierOffset / 2);targetsPos.Add(targetPos + nowRigth * soldierOffset / 2);targetsPos.Add(targetPos - nowForward * soldierOffset - nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowForward * soldierOffset + nowRigth * soldierOffset * 1.5f);targetsPos.Add(targetPos - nowForward * soldierOffset - nowRigth * soldierOffset / 2);targetsPos.Add(targetPos - nowForward * soldierOffset + nowRigth * soldierOffset / 2);break;}//计算完毕后  记录当前次的位置 frontPos = targetPos;return targetsPos;}
}

实际移动函数 

使用射线检测得到目标点target

   if( Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo, 1000, 1 << LayerMask.NameToLayer("Ground")) ){//通过目标点 计算出 真正的 阵型目标点//计算目标点List<Vector3> targetsPos = GetTargetPos(hitInfo.point);//命令士兵朝向各自的目标点 移动for (int i = 0; i < soldierObjs.Count; i++)soldierObjs[i].Move(targetsPos[i]);}


http://www.mrgr.cn/news/39008.html

相关文章:

  • 前端一文搞懂Promise 再也不害怕面试官问的问题啦~
  • cuda基础知识
  • 用CMake添加gtest测试用例gtest_discover_tests指令函数的分析
  • 扣子创建的智能体,发布成api,使用java进行调用
  • 关于PHP 匿名函数在处理数据结构中的应用
  • 深入解析网络通信的四大关键要素:网卡、MAC地址、IP地址、子网掩码与端口
  • 【Bug】解决 Ubuntu 中 “error: Unable to Find Python3 Executable” 错误
  • 代替@Autowire去注入,使你的代码更简便
  • 【Kubernetes】常见面试题汇总(三十八)
  • CDGA|利用人工智能与边缘计算显著提升数据治理效率与效果的实践案例
  • MES管理系统解决方案对中小企业有哪些帮助
  • Python编码系列—Python访问者模式:为对象结构添加新功能的艺术
  • 好用的电容笔有哪些推荐?2024盘点五款高性价比平替电容笔!
  • 视频美颜SDK与直播美颜工具API的架构设计与实现
  • Comfyui 学习笔记3
  • 强化学习入门——Pybullet初体验
  • 股票接口api,如何用excel获得股票实时数据
  • 基于PHP+MySQL组合开发的分类信息网站源码系统 带完整代码包以及搭建部署教程
  • MongoDB 工具包安装(mongodb-database-tools)
  • 安卓13默认使用大鼠标 与配置分析 andriod13默认使用大鼠标 与配置分析