Unity开发中导弹路径散射的原理与实现

Unity开发中导弹路径散射的原理与实现

  • 前言
  • 逻辑原理
  • 代码实现
    • 导弹自身脚本
    • 外部控制脚本
  • 应用效果
  • 结语

前言

前面我们学习了导弹的追踪的效果,但是在动画或游戏中,我们经常可以看到导弹发射后的弹道是不规则的,扭扭曲曲的飞行,然后击中目标。
这期我们就讲一下不规则路径飞行的逻辑,在游戏中是如何实现的。

请添加图片描述

逻辑原理

首先迎面走来的是初级的散射效果原理图,在发射点和目标点之间有一个散射经过点,重点来了:**利用三维空间中球形公式,给定球心,随机返回球面上一点。**然后让导弹经过随机点再击打目标,就会形成随机散射的效果。
在这里插入图片描述
多点也是一样的道理,把路径点经过换算之后再赋值导弹路径点,然后形成不规则散射的效果。
在这里插入图片描述
这里可以发现,导弹的路径是折线效果,按标准应该是曲线效果。两者的区别就在于导弹在两点之间的过渡函数,折线是平滑过渡,曲线是贝塞尔曲线过渡,选的过渡函数不同实现的效果也不一样。由于贝塞尔曲线过渡较为复杂,这里就用平滑过渡演示原理

代码实现

导弹自身脚本

这里将散射的范围用变量表示,实现可控的效果,想大范围就大范围、想小范围就小范围。将脚本挂载到导弹的预制体上之后给相应的变量赋值,例如:散射半径、爆炸特效、子弹移动速度,其他变量通过外部脚本赋值。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SpherePoint : MonoBehaviour
{[Header("散射半径")]public float radius;public GameObject FX;//爆炸特效public Transform endPoint;   // 目标点  public List<Transform> wayPoints; // 中间点列表  public float speed = 10f;         // 子弹移动速度  public int currentWaypointIndex = 0; // 当前处理的中间点索引  public Vector3 currentTargetPosition; // 当前目标位置  // Start is called before the first frame updatevoid Start(){if (wayPoints.Count > 0){currentTargetPosition = GetRandomPointOnSphere(wayPoints[0].position, radius);}else{currentTargetPosition = endPoint.position;}}// Update is called once per framevoid Update(){BulletMovement(transform);}/// <summary>/// 随机获取中间点周围的散射经过点/// </summary>/// <param name="center">中间点坐标</param>/// <param name="r">散射半径</param>/// <returns></returns>public static Vector3 GetRandomPointOnSphere(Vector3 center, float r){// 生成随机的经度和纬度  float u = UnityEngine.Random.value * 2 * Mathf.PI; // 经度 [0, 2*PI]  float v = UnityEngine.Random.value * Mathf.PI; // 纬度 [0, PI]  // 将球坐标转换为笛卡尔坐标  float x = center.x + r * Mathf.Sin(v) * Mathf.Cos(u);float y = center.y + r * Mathf.Sin(v) * Mathf.Sin(u);float z = center.z + r * Mathf.Cos(v);//返回指定球心的球面上随机一点return new Vector3(x, y, z);}private void BulletMovement(Transform bulletTran){// 子弹朝向当前目标位置  bulletTran.LookAt(currentTargetPosition);bulletTran.position += bulletTran.forward * speed * Time.deltaTime;      //向前移动// 检查子弹是否到达当前目标位置  if (Vector3.Distance(bulletTran.position, currentTargetPosition) < 0.1f){// 如果当前点不是最后一个中间点,则更新下一个目标位置为下一个中间点  if (currentWaypointIndex < wayPoints.Count){currentWaypointIndex++;if (currentWaypointIndex < wayPoints.Count){currentTargetPosition = GetRandomPointOnSphere(wayPoints[currentWaypointIndex].position, radius);}else{currentTargetPosition = endPoint.position; // 最后一个中间点后,目标位置是终点  }}// 如果已经到达终点,可以选择销毁子弹或其他操作  else if (currentTargetPosition == endPoint.position){GameObject tempFX = Instantiate(FX, bulletTran.position, bulletTran.rotation);  //生成一个爆炸特效 并给予位置和旋转信息Destroy(gameObject);//销毁自己Destroy(tempFX, 0.3f);//销毁爆炸效果currentWaypointIndex = 0;//重置路径索引}}}}

在这里插入图片描述

外部控制脚本

将导弹的击打目标和散射路径点通过脚本告诉导弹。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class InstantiateBullet : MonoBehaviour
{public GameObject bullet;//导弹预制体public Vector3 startPoint; // 导弹出生发射点  public Quaternion missileRotation;//导弹出生时方向public Transform endPoint;   // 目标点  public List<Transform> wayPoints; // 中间点列表  // Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){//鼠标点击左键发射导弹if (Input.GetMouseButtonDown(0)){GameObject bu = Instantiate(bullet, startPoint, missileRotation);bu.GetComponent<SpherePoint>().endPoint = endPoint;bu.GetComponent<SpherePoint>().wayPoints = wayPoints;}}
}

外部脚本我挂载到了Main Camera相机上。

在这里插入图片描述

应用效果

先看个正面的:

请添加图片描述

再来个侧面的:

请添加图片描述

好了,结束。

结语

学会后要多尝试,变成自己的东西,为己所用,赶快自己尝试下吧。有什么问题可以评论区或私信留言,下期见,拜拜。

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/10603.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字生态系统的演进与企业API管理的关键之路

数字生态系统的演进与企业API管理的关键之路 在数字化时代&#xff0c;企业正经历着一场转型的浪潮&#xff0c;而API&#xff08;应用程序编程接口&#xff09;扮演着至关重要的角色。API如同一座桥梁&#xff0c;将组织内部的价值转化为可市场化的产品&#xff0c;从而增强企…

韩国站群服务器在全球网络架构中的重要作用?

韩国站群服务器在全球网络架构中的重要作用? 在全球互联网的蓬勃发展中&#xff0c;站群服务器作为网络架构的核心组成部分之一&#xff0c;扮演着至关重要的角色。韩国站群服务器以其卓越的技术实力、优越的地理位置、稳定的网络基础设施和强大的安全保障能力&#xff0c;成…

LeetCode 题目 118:杨辉三角

题目描述 给定一个非负整数 numRows&#xff0c;生成杨辉三角的前 numRows 行。在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。 杨辉三角解析 在这个详解中&#xff0c;我们将使用 ASCII 图形来说明杨辉三角的构建过程&#xff0c;包括逐行添加新的行的过程。…

250 基于matlab的5种时频分析方法((短时傅里叶变换)STFT

基于matlab的5种时频分析方法&#xff08;(短时傅里叶变换)STFT,Gabor展开和小波变换,Wigner-Ville&#xff08;WVD&#xff09;,伪Wigner-Ville分布(PWVD),平滑伪Wigner-Ville分布&#xff08;SPWVD&#xff09;,每条程序都有详细的说明&#xff0c;设置仿真信号进行时频输出。…

Parted分区大容量磁盘

创建了新的虚拟磁盘10T , 挂载后分区格式化一.fdisk无法创建大容量的分区 Fileserver:~ # fdisk /dev/sdb Welcome to fdisk (util-linux 2.29.2). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device …

使用html和css实现个人简历表单的制作

根据下列要求&#xff0c;做出下图所示的个人简历&#xff08;表单&#xff09; 表单要求 Ⅰ、表格整体的边框为1像素&#xff0c;单元格间距为0&#xff0c;表格中前六列列宽均为100像素&#xff0c;第七列 为200像素&#xff0c;表格整体在页面上居中显示&#xff1b; Ⅱ、前…

git提交代码异常报错error:bad signature 0x00000000

报错信息 error:bad signature 0x00000000 异常原因 git 提交过程中异常关机或重启&#xff0c;造成当前项目工程中的.git/index 文件损坏&#xff0c;无法提交 解决步骤 删除.git/index文件 rm -f .git/index 重启git git reset

Java 【数据结构】 哈希(Hash超详解)HashSetHashMap【神装】

登神长阶 第十神装 HashSet 第十一神装 HashMap 目录 &#x1f454;一.哈希 &#x1f9e5;1.概念 &#x1fa73;2.Object类的hashCode()方法: &#x1f45a;3.String类的哈希码: &#x1f460;4.注意事项: &#x1f3b7;二.哈希桶 &#x1fa97;1.哈希桶原理 &#x…

Bert基础(二十二)--Bert实战:对话机器人

一 、概念简介 1.1 生成式对话机器人 1.1.1什么是生成式对话机器人? 生成式对话机器人是一种能够通过自然语言交互来理解和生成响应的人工智能系统。它们能够进行开放域的对话,即在对话过程中,机器人可以根据用户的需求和上下文信息,自主地生成新的、连贯的回复,而不仅…

如何使用CertCrunchy从SSL证书中发现和识别潜在的主机名称

关于CertCrunchy CertCrunchy是一款功能强大的网络侦查工具&#xff0c;该工具基于纯Python开发&#xff0c;广大研究人员可以利用该工具轻松从SSL证书中发现和识别潜在的主机信息。 支持的在线源 该工具支持从在线源或给定IP地址范围获取SSL证书的相关数据&#xff0c;并检索…

大数据测试

1、前言 大数据测试是对大数据应用程序的测试过程&#xff0c;以确保大数据应用程序的所有功能按预期工作。大数据测试的目标是确保大数据系统在保持性能和安全性的同时&#xff0c;平稳无差错地运行。 大数据是无法使用传统计算技术处理的大型数据集的集合。这些数据集的测试涉…

Foxmail使用经验总结

本篇博客将详尽讲解如何利用Foxmail进行高效的邮件管理&#xff0c;以及一些实用的使用技巧&#xff0c;让邮件管理变得更为高效和有序。 1. 账户设置与管理 多账户整合&#xff1a;Foxmail支持多个邮件账户同时管理&#xff0c;用户可以将个人和工作邮箱整合在同一个界面&am…

实战中使用 QEMU 进行内网穿透

前言 阅读 https://xz.aliyun.com/t/14052 《使用 QEMU 进行内网穿透&#xff1f;》 https://securelist.com/network-tunneling-with-qemu/111803/ 《Network tunneling with… QEMU?》 我将此项技术应用到实战中&#xff0c;取得不错的效果&#xff0c;但是也遇到很多坑&am…

机器学习算法应用——朴素贝叶斯分类器

朴素贝叶斯分类器 朴素贝叶斯分类器&#xff08;Naive Bayes Classifier&#xff09;是一种基于贝叶斯定理和特征条件独立假设的分类方法。它适用于分类任务&#xff0c;特别是文本分类、垃圾邮件识别等领域。 原理 朴素贝叶斯分类器基于以下两个主要假设&#xff1a; 特征条…

JS_ES6(1)

作用域链&#xff1a; 作用域链是底层变量查找的机制&#xff1a;当函数执行时&#xff0c;优先查找当前函数作用域中有无需要用到的变量&#xff0c;如果找不到&#xff0c;逐级查找父级&#xff0c;直到全局 > 嵌套关系形成作用域链&#xff0c;同一作用域链从小到大查找…

taro3兼容支付宝/微信小程序的自定义拖拽排序组件

描述&#xff1a;列表可以完成拖拽排序 此组件是根据支付宝原生文档改编成taro-vue3的形式&#xff0c;只保留了拖拽的部分&#xff0c;其他功能都去除了&#xff0c;测试下来可以兼容支付宝和微信小程序。 支付宝原生文档&#xff1a; https://opendocs.alipay.com/support/…

BGP(border gateway protocol)边界网关协议初识篇

BGP它是一种路径矢量协议&#xff0c;用于决定数据包在互联网中的最佳路径。 1、工作原理&#xff1a; 自治系统&#xff08;AS&#xff09;间路由: BGP主要用于连接不同自治系统之间的路由器&#xff0c;其中每个自治系统&#xff08;AS&#xff09;代表一组具有共同路由的网…

编译 fdk-aac

文章目录 关于 fdk-aac编译 fdk-aac在 FFMpeg 编译中启用 关于 fdk-aac A standalone library of the Fraunhofer FDK AAC code from Android. github &#xff1a; https://github.com/mstorsjo/fdk-aac代码托管 &#xff1a; https://sourceforge.net/projects/opencore-am…

最新巨量X-Bogus、_signature参数逆向分析与算法还原

文章目录 1. 写在前面2. 接口分析3. 断点分析4. 扣代码补环境5. 数据解密 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路…

# 从浅入深 学习 SpringCloud 微服务架构(十六)

从浅入深 学习 SpringCloud 微服务架构&#xff08;十六&#xff09; 一、SpringCloudStream&#xff1a;自定义消息通道 1、在子工程 stream_product &#xff08;子模块&#xff09;中,创建 自定义的消息通道类 MyProcessor.java /*** spring_cloud_demo\stream_product…