首页 > 其他分享 >Unity实战案例全解析:RTS游戏的框选和阵型功能(4)阵型功能

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

时间:2024-09-29 14:20:08浏览次数:3  
标签:阵型 targetsPos soldierOffset Add nowRigth Unity targetPos RTS nowForward

前篇: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]);
            }

标签:阵型,targetsPos,soldierOffset,Add,nowRigth,Unity,targetPos,RTS,nowForward
From: https://blog.csdn.net/2301_77947509/article/details/142633981

相关文章

  • Python pyecharts:数据可视化的强大工具
    在数据分析和可视化领域,Python提供了许多优秀的库。其中,pyecharts是一个功能强大的数据可视化模块,它基于Echarts库,能够生成各种精美的图表。本文将深入探讨Pythonpyecharts模块的高级用法,展示其在数据可视化方面的强大功能。一、pyecharts简介pyecharts是一个用......
  • 【Unity】(UI)抽屉式折叠面板
    UI中实现一个抽屉式折叠面板成果展示Scene部分主要包括两个部分:Option和Content。option对应的是选项按钮;Content对应的是展开的内容;这里由于此篇写法的问题。需要将option中Button从0开始依次编号。物体请按照固定的距离进行摆放。如Option中每个子物体的位置分别为(0,0,0)(0,-......
  • [使用目前最新版]HybridCLR6.9.0+YooAsset2.2.4实现纯C# Unity热更新方案 (一)
    1.前言什么是热更新游戏或者软件更新时,无需重新下载客户端进行安装,而是在应用程序启动的情况下,在内部进行资源或者代码更新Unity目前常用热更新解决方案HybridCLR,Xlua,ILRuntime等Unity目前常用资源管理解决方案AssetBundles,Addressable,YooAsset等在这里我们采用HybridCLR......
  • A Closer Look into Mixture-of-Experts in Large Language Models
    本文是LLM系列文章,针对《ACloserLookintoMixture-of-ExpertsinLargeLanguageModels》的翻译。仔细研究大型语言模型中的专家混合摘要1引言2前言:混合专家3概述4静态参数分析5动态行为分析6讨论7相关工作8结论9局限性摘要专家混合(MoE)因其......
  • [ECharts] There is a chart instance already initialized on the dom.
    [ECharts]Thereisachartinstancealreadyinitializedonthedom.  报错解释:这个错误表示在同一个DOM元素上已经初始化了一个ECharts图表实例,而你又尝试去在同一个DOM上初始化另一个图表实例。ECharts不允许在同一个DOM上叠加多个实例。解决方法:   在尝试初始化新......
  • Echarts图表知识点汇总及请求django服务器后端跨域问题解决
    1.引入echartsvue3中通过npm引入:npminstallecharts--saveimport*asechartsfrom'echarts';//基于准备好的dom,初始化echarts实例varmyChart=echarts.init(document.getElementById('main'));//绘制图表myChart.setOption({title:{text:'ECha......
  • 教你一招:解决微信小程序 echarts提示框tooltip圆点不显示问题
    最近在微信小程序中插入折线图时需要在提示框中添加单位,于是用了tooltip自定义提示框内容。发现设置了之后小圆点不见了,看了很多文章,有说要加params[i].marker的,有说直接写HTML的,可能是版本问题,我都没有成功。最后将解决办法记录如下:letoption={//...其他配置项......
  • 解锁微信小程序新技能:ECharts动态折线图搭配WebSocket,数据刷新快人一步!
    在微信小程序中,数据可视化展示越来越受到开发者的重视。本文将为您介绍如何在微信小程序中使用ECharts绘制折线图,并通过WebSocket实现实时更新图表数据。一、准备工作创建微信小程序项目 首先,我们需要创建一个微信小程序项目。如果您已经熟悉如何创建项目,可以跳过此步骤。......
  • 一文详解WebRTC、RTSP、RTMP、SRT
     背景好多开发者,希望对WebRTC、RTSP、RTMP、SRT有个初步的了解,知道什么场景该做怎样的方案选择,本文就四者区别做个大概的介绍。WebRTC提到WebRTC,相信好多开发者第一件事想到的就是低延迟,WebRTC(WebReal-TimeCommunication)是一项实时通讯技术,它允许网络应用或者站点在不借助中间媒......
  • 【春秋招必看】Unity相关笔试面试题(内有完整答案)第五期
    欢迎来到光光的奇妙冒险,我是你们的煎饼光子老师。今天是我们的第五期笔试面试题总结。C#部分:1、以上代码,谁的效率更高?为什么?答案:代码2的效率更高因为List的本质是数组,在初始化时,如果不默认为其指明分配多少容量,它会不断扩容扩容会带来效率的降低和垃圾的产生效率的降......