Unity 简单载具路线 Waypoint 导航
前言
在游戏开发和导航系统中,"waypoint" 是指路径中的一个特定位置或点。它通常用于定义一个物体或角色在场景中移动的目标位置或路径的一部分。通过一系列的 waypoints,可以指定复杂的移动路径和行为。以下是一些 waypoint 的具体用途:
-
导航和路径规划:
- Waypoints 用于定义角色或物体从一个位置移动到另一个位置的路径。
- 例如,在游戏中,敌人可能会沿着一系列 waypoints 巡逻。
-
动画和过场:
- Waypoints 可用于定义相机或对象在场景中移动的路径。
- 例如,在过场动画中,摄像机可能会沿着预定义的路径移动,以展示场景的不同部分。
-
人工智能(AI)行为:
- AI 角色可以使用 waypoints 来确定移动路径和行为模式。
- 例如,AI 角色可以沿着一系列 waypoints 移动,以模拟巡逻或探索行为。
-
动态事件触发:
- Waypoints 可以用作触发点,当角色或物体到达某个 waypoint 时触发特定事件或行为。
- 例如,玩家到达某个 waypoint 时,可能会触发一段对话或开始一个任务。
Unity 简单载具路线 Waypoint 导航
实现
假设我们有一辆载具,需要通过给定的数个路径点(waypoint)来进行移动和转向。
简单粗暴的一种方法是使用Animation动画系统来为载具制作做动画,但是这个方法的致命缺点是非常不灵活,一旦需要改动路径点和模型,几乎就得重新做动画。
好在,DOTween (HOTween v2) | 动画 工具 | Unity Asset Store 插件的出现让脚本解决变得异常的简单快捷,这个插件能够完美解决各种各样的过场动画和事件调用:
DOTween (HOTween v2) (demigiant.com)https://dotween.demigiant.com/index.php
- 这里需要先事先安装一下DOTween,没什么难度,免费!
- 在场景中增加你的路径点,做一个父物体,然后为子物体增加多个路径点,这里每个路径点建议使用带有方向的模型或者图片,这样便于查看
- 为你的载具添加文末的脚本,并挂在载具上(如果你不想挂在载具上,那简单改一下代码的变量为你的期望物体上就行)。
- 在inspector中绑定好你需要的路径点集合的父物体(wayPointsParent变量),这里我在父物体上额外加了一个LineRender组件,用于后续连线效果:
- 运行程序!车子就会动起来了!调节每一个变量,让车子移动的更自然!
每个变量都有它的意义,比如你可以规定整个路程的总时间、转一次弯需要多少时间,转弯的起始距离阈值以及每到一个waypoint的事件调用等等,并可以更具每个人的需要自行修改和拓展!
using System;
using UnityEngine;
using DG.Tweening;
using UnityEngine.Events;/// <summary>
/// Author: Lizhenghe.Chen https://bunnychen.top/about
/// </summary>
public class CarMover : MonoBehaviour
{public LineRenderer wayPointsParent;[Header("Total move time in seconds")] public int totalMoveTime = 300;[Header("Rotation duration in seconds")]public float rotationDuration = 2;[Header("Distance threshold to start rotating")]public float rotationStartDistance = 1;[Header("Show line renderer")] public bool showLineRenderer = true;// Duration for each segment[SerializeField] private int moveDuration = 5;// Array of transforms for the car to move towards[SerializeField] private Transform[] waypoints;[SerializeField] private Transform currentWaypoint;[SerializeField] private int currentWaypointIndex;public UnityEvent onWaypointReached;private MaterialPropertyBlock _propBlock;private static readonly int BaseColor = Shader.PropertyToID("_BaseColor");private static readonly int EmissionColor = Shader.PropertyToID("_EmissionColor");private void OnValidate(){// Get the waypoints from the parent object, do not include the parent object itselfif (wayPointsParent == null) return;waypoints = new Transform[wayPointsParent.transform.childCount];for (var i = 0; i < waypoints.Length; i++){waypoints[i] = wayPointsParent.transform.GetChild(i);}//foreach waypoint, set the current waypoint to look at the next waypointfor (var i = 0; i < waypoints.Length - 1; i++){waypoints[i].LookAt(waypoints[i + 1]);}moveDuration = totalMoveTime / waypoints.Length;}private void Start(){OnValidate();if (showLineRenderer) SetLineRenderer();SetWaypointsSequence();onWaypointReached.AddListener(SetPreviousWaypointColor);}private void SetWaypointsSequence(){// Create a new Sequence for movementvar moveSequence = DOTween.Sequence();// Loop through the waypoints and append DOMove tweens to the moveSequenceforeach (var waypoint in waypoints){moveSequence.AppendCallback(() =>{currentWaypoint = waypoint;currentWaypointIndex = Array.IndexOf(waypoints, waypoint);onWaypointReached?.Invoke();});// Move to the waypointmoveSequence.Append(transform.DOMove(waypoint.position, moveDuration).SetEase(Ease.Linear));// Create a rotation tween that starts when the car is within the specified distance to the waypointmoveSequence.AppendCallback(() =>{// Start rotation when close to the waypointif (Vector3.Distance(transform.position, waypoint.position) < rotationStartDistance){// make the rotation same to the waypoint's rotationtransform.DORotateQuaternion(waypoint.rotation, rotationDuration).SetEase(Ease.Linear);}});}// Optionally, set some other properties on the sequencemoveSequence.SetLoops(0); // Infinite loop// moveSequence.SetAutoKill(false); // Prevent the sequence from being killed after completion}private void SetLineRenderer(){//set the line renderer's position count to the number of waypoints and set the positions to the waypoints' positionswayPointsParent.positionCount = waypoints.Length;for (var i = 0; i < waypoints.Length; i++){wayPointsParent.SetPosition(i, waypoints[i].position);}}private void SetPreviousWaypointColor(){_propBlock ??= new MaterialPropertyBlock();if (currentWaypointIndex == 0) return;// Set the color of the current waypoint to green, and the next waypoint to redwaypoints[currentWaypointIndex - 1].GetComponent<MeshRenderer>().GetPropertyBlock(_propBlock);_propBlock.SetColor(BaseColor, Color.green);_propBlock.SetColor(EmissionColor, Color.green);waypoints[currentWaypointIndex - 1].GetComponent<MeshRenderer>().SetPropertyBlock(_propBlock);waypoints[currentWaypointIndex - 1].gameObject.SetActive(false);}
}
相关文章:

Unity 简单载具路线 Waypoint 导航
前言 在游戏开发和导航系统中,"waypoint" 是指路径中的一个特定位置或点。它通常用于定义一个物体或角色在场景中移动的目标位置或路径的一部分。通过一系列的 waypoints,可以指定复杂的移动路径和行为。以下是一些 waypoint 的具体用途&…...

科普文:微服务之服务网格Service Mesh
一、ServiceMesh概念 背景 随着业务的发展,传统单体应用的问题越来越严重: 单体应用代码库庞大,不易于理解和修改持续部署困难,由于单体应用各组件间依赖性强,只要其中任何一个组件发生更改,将重新部署整…...

第四十九章 解决 IRIS 中的 SOAP 问题 - 发送消息时出现问题
文章目录 第四十九章 解决 IRIS 中的 SOAP 问题 - 发送消息时出现问题 第四十九章 解决 IRIS 中的 SOAP 问题 - 发送消息时出现问题 如果在向 IRIS Web 服务或客户端发送或接收 SOAP 消息时遇到问题,请考虑以下常见场景列表: SOAP 消息可能包含极长的字…...

STM32-HAL-FATFS(文件系统)(没做完,stm32f103zet6(有大佬的可以在评论区说一下次板子为什么挂载失败了))
1STM32Cube配置 1-1配置时钟 1-2配置调试端口 1-3配置uart 1-4配置SDIO(注意参数)(其中他的初始化的异常函数给注释,SD卡文件写了) 配置了还要打开中断和DMA可在我的其他文章中看一样的 1-5配置FatFs (只改了图选中…...

线性代数基础概念:矩阵
目录 线性代数基础概念:矩阵 1. 矩阵的定义 2. 矩阵的运算 3. 矩阵的特殊类型 4. 矩阵的秩 5. 矩阵的初等变换 6. 矩阵的特征值与特征向量 7. 矩阵的应用 8. 矩阵总结 总结 线性代数基础概念:矩阵 矩阵是线性代数中的另一个重要概念࿰…...

【优化论】约束优化算法
约束优化算法是一类专门处理目标函数在存在约束条件下求解最优解的方法。为了更好地理解约束优化算法,我们需要了解一些核心概念和基本方法。 约束优化的核心概念 可行域(Feasible Region): 比喻:想象你在一个园艺场…...

7寸微型FPV无人机技术详解
对于7寸微型FPV(First Person View,第一人称视角)无人机技术的详解,可以从以下几个方面进行介绍: 一、定义与基本概念 FPV无人机,全称为“第一人称视角无人机”,它利用安装在无人机上的摄像头…...

大数据面试题之Presto[Trino](2)
目录 描述Presto中的Connector是什么? Presto如何实现数据源的插件化? 如何在单机上安装Presto? 描述在集群环境中部署Presto的步骤。 如何为Presto配置JVM参数? 如何优化Presto的配置以提高性能? Presto的日…...

STM32和DHT11使用显示温湿度度(代码理解)+单总线协议
基于STM32CT,利用DHT11采集温湿度数据,在OLED上显示。一定要阅读DHT11数据手册。 1、 DHT11温湿度传感器 引脚说明 1、VDD 供电3.3~5.5V DC 2、DATA 串行数据,单总线 3、NC 空脚 4、GND 接地,电源负极 硬件电路 微…...

EVM-MLIR:以MLIR编写的EVM
1. 引言 EVM_MLIR: 以MLIR编写的EVM。 开源代码实现见: https://github.com/lambdaclass/evm_mlir(Rust) 为使用MLIR和LLVM,将EVM-bytecode,转换为,machine-bytecode。LambdaClass团队在2周…...

深入Django(八)
掌握Django的管理后台 引言 在前七天的教程中,我们介绍了Django的基础架构、模型、视图、模板、URL路由、表单系统以及数据库迁移。今天,我们将深入了解Django的管理后台,这是一个功能强大的内置管理界面,用于创建、更新、查看和…...

华为开发者大会2024纪要:鸿蒙OS的全新篇章与AI大模型的革命
华为开发者大会2024纪要:鸿蒙OS的全新篇章与AI大模型的革命 在科技的浪潮中,华为再次引领潮流,2024年的开发者大会带来了一系列令人瞩目的创新成果。从鸿蒙操作系统的全新Beta版到盘古大模型的震撼发布,华为正以前所未有的速度重塑智能生态。以下是本次大会的亮点,让我们…...

吴恩达深度学习笔记:机器学习策略(2)(ML Strategy (2)) 2.7-2.8
目录 第三门课 结构化机器学习项目(Structuring Machine Learning Projects)第二周:机器学习策略(2)(ML Strategy (2))2.7 迁移学习(Transfer learning) 第三门课 结构化机器学习项目࿰…...

云计算渲染时代:选择Blender或KeyShot进行高效渲染
在云渲染技术日益成熟的背景下,挑选一款贴合项目需求的3D渲染软件显得尤为关键。当前,Blender与KeyShot作为业界领先的全能渲染解决方案,广受推崇。它们虽皆能创造出令人信服的逼真视觉效果,但在特色功能上各有所长。本篇文章旨在…...

html5中的iframe
HTML5中的iframe 浏览上下文是浏览器展示文档的环境,通常是一个tab标签页,一个窗体或者是浏览器页面的一部分。每个浏览上下文都有一个活动文档的源和一个记录所有展示文档的有序历史。浏览上下文的通讯被严格限制,只有两个同源的浏览器上下…...

海睿思问数(TableGPT):开创企业新一代指标应用模式
1 指标建设对企业经营管理数字化的价值分析 指标是将海量数据中关键信息提炼和挖掘出来,以数据为载体展示企业经营管理和分析中的统计量。它通过分析数据,形成一个具有度量值的汇总结果,使得业务状态可以被描述、量化和分解。指标通常由度量…...

LM-Cocktail:一种创新的模型合并方法打破预训练语言模型微调后的性能局限,实现语言模型在一般任务与特定领域的均衡高性能
LM-Cocktail:一种创新的模型合并方法打破预训练语言模型微调后的性能局限,实现语言模型在一般任务与特定领域的均衡高性能 使语言模型的微调类似于调制一杯精致的鸡尾酒。模型合并可用于提高单个模型的性能。我们发现此方法对于大型语言模型和密集嵌入模型也很有用,并设计了…...

默认导出(default)和命名导出
1.默认导出 优点: 简洁的导入语法: 导入时不需要使用花括号,可以直接重命名。单一职责: 模块导出一个主要功能或对象时,默认导出更符合逻辑。 适用场景: 模块只有一个导出: 如一个组件、一个…...

开发个人Go-ChatGPT--1 项目介绍
开发个人Go-ChatGPT--1 项目介绍 开发个人Go-ChatGPT--1 项目介绍知识点大纲文章目录项目地址 开发个人Go-ChatGPT–1 项目介绍 本文将以一个使用Ollama部署的ChatGPT为背景,主要还是介绍和学习使用 go-zero 框架,开发个人Go-ChatGPT的服务器后端&#…...

皮卡超级壁纸 | 幸运壁纸幸运壁纸app是一款涵盖了热门影视剧、动漫、风景等等资源的装饰工具,
软件下载链接:壁纸下载方式在链接中文章底部 皮卡超级壁纸 皮卡超级壁纸是一款专为手机用户设计的壁纸应用,它提供了丰富多样的高清壁纸资源,让用户的手机界面焕然一新。这款应用以其海量的壁纸库和用户友好的操作界面,在市场上…...

普通集群与镜像集群配置
目录 一. 环境准备 二. 开始配置集群 三. RabbitMQ镜像集群配置 四. 安装并配置负载均衡器HA 一. 环境准备 关闭防火墙和selinux,进行时间同步 主机名系统IP服务rabbitmq-1 Rocky_linux9.4 192.168.226.22RabbitMQ,MySQLrabbitmq-2Rocky_linux9.41…...

2024科技文化节程序设计竞赛
补题链接 https://www.luogu.com.cn/contest/178895#problems A. 签到题 忽略掉大小为1的环,答案是剩下环的大小和减环的数量 #include<bits/stdc.h> #include<iostream> #include<cstdio> #include<vector> #include<map> #incl…...

玩转Easysearch语法
Elasticsearch 是一个基于Apache Lucene的开源分布式搜索和分析引擎,广泛应用于全文搜索、结构化搜索、分析等多种场景。 Easysearch 作为Elasticsearch 的国产化替代方案,不仅保持了与原生Elasticsearch 的高度兼容性,还在功能、性能、稳定性…...

【密码学】RSA公钥加密算法
文章目录 RSA定义RSA加密与解密加密解密 生成密钥对一个例子密钥对生成加密解密 对RSA的攻击通过密文来求得明文通过暴力破解来找出D通过E和N求出D对N进行质因数分解通过推测p和q进行攻击 中间人攻击 一些思考公钥密码比对称密码的机密性更高?对称密码会消失&#x…...

【ARMv8/v9 GIC 系列 5.1 -- GIC GICD_CTRL Enable 1 of N Wakeup Function】
请阅读【ARM GICv3/v4 实战学习 】 文章目录 GIC Enable 1 of N Wakeup Function基本原理工作机制配置方式应用场景小结GIC Enable 1 of N Wakeup Function 在ARM GICv3(Generic Interrupt Controller第三代)规范中,引入了一个名为"Enable 1 of N Wakeup"的功能。…...

C++怎么解决不支持字符串枚举?
首先,有两种方法:使用命名空间和字符串常量与使用 enum class 和辅助函数。 表格直观展示 特性使用命名空间和字符串常量使用 enum class 和辅助函数类型安全性低 - 编译器无法检查字符串有效性,运行时发现错误高 - 编译期类型检查…...

中英双语介绍四大会计师事务所(Big Four accounting firms)
中文版 “四大会计师事务所”(Big Four accounting firms)是全球最具影响力和规模最大的四家专业服务公司,它们在审计、税务、咨询和财务咨询等领域占据着主导地位。这四家公司分别是普华永道(PwC)、德勤(…...

ubuntu 查看联网配置
在Ubuntu中,你可以使用多种命令来查看联网配置。以下是一些常用的方法和命令: 查看网络接口配置: 使用 ip 命令可以查看网络接口的配置信息,包括IP地址、子网掩码等。 ip addr show或者,你也可以使用传统的 ifconfig 命…...

【数据分享】全国乡村旅游重点镇(乡)数据(Excel/Shp格式/免费获取)
之前我们分享过从我国文化和旅游部官网整理的2018-2023年我国50个重点旅游城市星级饭店季度经营状况数据(可查看之前发布的文章)!文化和旅游部官网上也分享有很多与旅游相关的常用数据,我们基于官网发布的名单文件整理得到全国乡村…...

停车场小程序的设计
管理员账户功能包括:系统首页,个人中心,车主管理,商家管理,停车场信息管理,预约停车管理,商场收费管理,留言板管理 微信端账号功能包括:系统首页,停车场信息…...