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

devtools/2024/12/23 1:20:28/

前篇: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.ppmy.cn/devtools/119624.html

相关文章

单细胞中的GSVA基因集评分怎么实现?

愿武艺晴小朋友一定得每天都开心 ## 使用GSVA:score的大小来定量评价基因集在样本中的相对大小 library(GSVA) #读取gmt文件 geneset <- read.gmt(file.path("./PreB_pathways_GSVA_score.gmt")) #read.gmt geneset <- split(geneset$gene,geneset$term) gen…

枚举值实现下拉和tag展示的组件封装(vue2+js+elementUI)

枚举值组件EnumBase&#xff08;实现展示数据的时候提供tag样式&#xff0c;也可以变成下拉选择&#xff09; AllowSelect判断是要下拉选择还是展示tag标签 &#xff08;所有prop要使用的时候尽量通过computed进行&#xff0c;避免直接修改prop值&#xff09; <div :class&q…

学Java还是c++好?

Java在互联网行业中的应用非常广泛&#xff0c;就业方面&#xff0c;Java岗位较多&#xff0c;就业市场相对稳定&#xff0c;尤其是在Android应用开发、企业级应用、大数据技术等领域有大量的岗位。 Java的语法相对简单&#xff0c;对于初学者来说更容易上手。有很多成熟的框架…

【SQLite】基础操作

数据查询 SELECT 查询所有数据 SELECT *FROM tableName使用AND操作符 SELECT * FROM tableName WHERE id=? AND name=?使用OR操作符 SELECT * FROM tableName WHERE id=? OR name=?组合使用AND和OR SELECT * FROM tableName WHERE (id=? AND name=?) OR status=?多表查询…

windows10 docker 推送本地镜像

windows10安装好docker后&#xff0c;接下来上传本地镜像文件&#xff1a; 1&#xff0c;设置请非安全参数&#xff0c;处理&#xff1a;https改为http请求 点击设置&#xff0c;打开 Docker Engine 追加&#xff1a; "insecure-registries": ["http://177.18…

实用工具推荐---- PDF 转换

直接上链接&#xff1a;爱PDF |面向 PDF 爱好者的在线 PDF 工具 (ilovepdf.com) 主要功能如下&#xff1a; 全免费&#xff01;&#xff01;&#xff01;&#xff01;

Anaconda 安装

目录 1. [什么是 Anaconda](#什么是-anaconda) 2. [安装 Anaconda](#安装-anaconda) 3. [环境管理](#环境管理) 1. [创建环境](#创建环境) 2. [激活与退出环境](#激活与退出环境) 3. [安装包](#安装包) 4. [删除包](#删除包) 5. [更新包](#更新包) 6. [列出环境中的包…

mysql学习教程,从入门到精通,SQL 表、列别名(Aliases)(30)

1、SQL 表、列别名&#xff08;Aliases&#xff09; 在SQL中&#xff0c;表别名&#xff08;Table Aliases&#xff09;和列别名&#xff08;Column Aliases&#xff09;是两种非常有用的技术&#xff0c;可以使查询语句更加简洁和易读。它们还可以帮助处理复杂的查询&#xf…