提前预测刚体移动轨迹 预测运动轨迹

提前预测刚体移动轨迹 预测运动轨迹

  • 一、效果
  • 二、介绍
  • 三、脚本
    • RigidbodyExtension.cs 计算工具类
    • DrawLine.cs 画线工具类
  • 四、资源分享

一、效果

在这里插入图片描述

二、介绍

通过计算Unity物理系统的运动方位来判断下一步移动的位置,主要用于物体运动的提前预测,通常使用于炮弹发射,机枪发射,足球篮球网球的运动等多种真实运动的物体。

三、脚本

RigidbodyExtension.cs 计算工具类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;namespace Dweiss
{public static class RigidbodyExtension{public static Vector3[] CalculateMovement(this Rigidbody that,int stepCount, float timeBeteenStep){return that.CalculateMovement(stepCount, timeBeteenStep, Vector3.zero, Vector3.zero);}public static Vector3[] CalculateMovement(this Rigidbody that,int stepCount, float timeBeteenStep, Vector3 addedSpeed){return that.CalculateMovement(stepCount, timeBeteenStep, addedSpeed, Vector3.zero);}/// <summary>/// /// </summary>/// <param name="that"></param>/// <param name="stepCount">Number of steps</param>/// <param name="timeBeteenStep">number of frames to skip</param>/// <param name="addedSpeed"></param>/// <param name="addedForce"></param>/// <returns></returns>public static Vector3[] CalculateMovement(this Rigidbody that,int stepCount, float timeBeteenStep, Vector3 addedSpeed, Vector3 addedForce){//var ret = new Vector3[stepCount];// var addedV = (addedForce / that.mass) * Time.fixedDeltaTime;var v = (that.isKinematic == false ? that.velocity : Vector3.zero);// + addedSpeed + addedV;var a = (that.useGravity && that.isKinematic == false ? Physics.gravity : Vector3.zero);return CalculateMovement(that.transform.position, v, a, stepCount, timeBeteenStep, addedSpeed, addedForce, that.mass, that.drag);//var x = that.transform.position;//var calc = new Vector3[] { x, v };//for (var i = 0; i < stepCount; ++i)//{//    calc = CalculateNewPos(calc[0], calc[1], a, that.drag, timeBeteenStep);//    ret[i] = calc[0];//}//return ret;}public static Vector3[] CalculateMovement(Vector3 position, Vector3 velocity, Vector3 acc, int stepCount, float timeBeteenStep, Vector3 addedSpeed, Vector3 addedForce, float mass, float drag){var ret = new Vector3[stepCount];var addedV = (addedForce / mass) * Time.fixedDeltaTime;var v = velocity + addedSpeed + addedV;var a = acc;var x = position;var calc = new Vector3[] { x, v };for (var i = 0; i < stepCount; ++i){calc = CalculateNewPos(calc[0], calc[1], a, drag, timeBeteenStep);ret[i] = calc[0];}return ret;}private static Vector3[] CalculateNewPos(Vector3 x, Vector3 v, Vector3 a, float drag, float deltaTimeCount){var dt = Time.fixedDeltaTime;var aDt = a * dt;var dragDt = 1 - drag * dt;dragDt = dragDt < 0 ? 0 : dragDt;var acc = .5f * a * dt * dt;for (int i = 0; i < deltaTimeCount; ++i){v = (v + aDt) * dragDt;x = x + v * dt + acc;}return new Vector3[]{ x, v };}private static Vector3 CalculateVDrag(Vector3 v, Vector3 a, float drag, int deltaTimeCount){var dt = Time.fixedDeltaTime;for(int i=0; i < deltaTimeCount; ++i)v = (v + a * dt) * (1 - drag * dt);return v;}Doesn't supports public static Vector3[] CalculateTime(this Rigidbody that, Vector3 targetPos){return CalculateTime(that, targetPos, Vector3.zero, Vector3.zero);}public static Vector3[] CalculateTime(this Rigidbody that, Vector3 targetPos,Vector3 addedSpeed){return CalculateTime(that, targetPos, addedSpeed, Vector3.zero);}public static Vector3[] CalculateTime(this Rigidbody that, Vector3 targetPos, Vector3 addedSpeed, Vector3 addedForce){var addedV = (addedForce / that.mass) * Time.fixedDeltaTime;var v = that.velocity + addedSpeed + addedV;var a = (that.useGravity && that.isKinematic == false ? Physics.gravity : Vector3.zero);var x0 = that.transform.position;//x = x0 +vt + .5*a*t^2//-b +- SQR(b*b - 4*a*c)/2*a // a= .5*a//b=v//a=x0-x//t12 = -v +- SQR(v*v -4 * .5 * a * (x0-x))/ 2 * .5 * avar x = x0 - targetPos;var sqr = (v.PointMul(v) - 4 * .5f * a.PointMul(x)).Sqrt();var t1 = (-v + sqr).PointDiv(2 * .5f * a);var t2 = (-v - sqr).PointDiv(2 * .5f * a);// a=0: (x0-x) + vt -> t = (x-x0)/vvar tWhenA0 = x.PointDiv(v);//a = 0if (float.IsNaN(t1.x)) { t2.x = t1.x = tWhenA0.x; }if (float.IsNaN(t1.y)) { t2.y = t1.y = tWhenA0.y; }if (float.IsNaN(t1.z)) { t2.z = t1.z = tWhenA0.z; }// a = 0 && v = 0if (float.IsNaN(t1.x) && x0.x == targetPos.x) { t2.x = t1.x = 0; }if (float.IsNaN(t1.y) && x0.y == targetPos.y) { t2.y = t1.y = 0; }if (float.IsNaN(t1.z) && x0.z == targetPos.z) { t2.z = t1.z = 0; }return new Vector3[] { t1, t2 };}public static Vector3 Sqrt(this Vector3 v){return new Vector3(Mathf.Sqrt(v.x), Mathf.Sqrt(v.y), Mathf.Sqrt(v.z));}public static Vector3 PointMul(this Vector3 v1, Vector3 v2){return new Vector3(v1.x*v2.x, v1.y*v2.y, v1.z*v2.z);}public static Vector3 PointDiv(this Vector3 v1, Vector3 v2){return new Vector3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z);}}
}

DrawLine.cs 画线工具类

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Dweiss;[RequireComponent(typeof(LineRenderer))]
public class DrawLine : MonoBehaviour {/// <summary>/// 引导线/// </summary>public LineRenderer _lr;/// <summary>/// 刚体/// </summary>public Rigidbody _rb;/// <summary>/// 跨度/// </summary>public float timeBeteenStep = 1;/// <summary>/// 跨度数量/// </summary>public int stepCount = 30;/// <summary>/// 加速度/// </summary>public Vector3 addedV, addedF;void Start() {//找引导线_lr = GetComponent<LineRenderer>();//找刚体_rb = GetComponent<Rigidbody>();}public void AddPower(Vector3 dir){CalcTime();_rb.velocity += addedV;addedV = Vector3.zero;_rb.AddForce(dir, ForceMode.Force);addedF = Vector3.zero;}private void CalcTime(){Vector3[] t = _rb.CalculateTime(new Vector3(0, 0, 0),addedV, addedF);var timeT = new Vector3[]{new Vector3(Time.time + t[0].x, Time.time + t[0].y, Time.time + t[0].z),new Vector3(Time.time + t[1].x, Time.time + t[1].y, Time.time + t[1].z)};}#region 抛物曲线/// <summary>/// 移动走向曲线/// </summary>private void DrawMovementLine(){var res = _rb.CalculateMovement(stepCount, timeBeteenStep, addedV, addedF);_lr.positionCount = stepCount + 1;_lr.SetPosition(0, transform.position);for (int i = 0; i < res.Length; ++i){_lr.SetPosition(i + 1, res[i]);}}#endregionvoid Update (){DrawMovementLine();if (Input.GetKeyDown(KeyCode.W)){AddPower((Vector3.right + Vector3.up) * 500f);}}
}

四、资源分享

CSDN下载链接

在我的资源中搜索 RigidBodyExtension

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

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

相关文章

华为vrrp+mstp+ospf+dhcp+dhcp relay配置案例

1、左边是vlan 10主桥&#xff0c;右边是vlan 20的主桥&#xff0c;并且互为备桥 2、 vlan 10 vrrp网关默认用左边&#xff0c;vlan 20的vrrp 网关默认用右边&#xff0c;对应mstp生成树 3、两边都track检测&#xff0c;不通就把vrrp减掉60&#xff0c;这样就会自动切另一边了 …

Hadoop入门学习笔记——七、Hive语法

视频课程地址&#xff1a;https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接&#xff1a;https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记&#xff08;汇总&#xff09; 目录 七、Hive语法7.1. 数据库相关操作7.1.1. 创建数据库7.1.2…

kubernetes集群 应用实践 zookeeper部署

kubernetes集群 应用实践 zookeeper部署 零、环境说明 一、zookeeper持久存储准备 zookeeper属于有状态应用&#xff0c;需要为zookeeper部署后端存储服务。 1.1 在NFS服务器添加一块硬盘vdc [rootnfsserver ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT …

【Python】基于flaskMVT架构与session实现博客前台登录登出功能

目录 一、MVT说明 1.Model层 2.View层 3.Template层 二、功能说明 三、代码框架展示 四、具体代码实现 models.py 登录界面前端代码 博客界面前端代码&#xff08;profile.html&#xff09; main.py 一、MVT说明 MVT架构是Model-View-Template的缩写&#xff0c;是…

持续集成交付CICD:Linux 部署 Jira 9.12.1

目录 一、实验 1.环境 2.K8S master节点部署Jira 3.Jira 初始化设置 4.Jira 使用 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构版本IP备注master1K8S master节点1.20.6192.168.204.180 jenkins slave &#xff08;从节点&#xff09; jira9.12.1…

使用vue-qr,报错in ./node_modules/vue-qr/dist/vue-qr.js

找到node_modules—>vue-qr/dist/vue-qr.js文件&#xff0c;搜…e,将…去掉&#xff0c;然后重新运行项目。

Confluent 与阿里云将携手拓展亚太市场,提供消息流平台服务

10 月 31 日&#xff0c;杭州云栖大会上&#xff0c;阿里云云原生应用平台负责人丁宇宣布&#xff0c;Confluent 成为阿里云技术合作伙伴&#xff0c;合作全新升级&#xff0c;一起拓展和服务亚太市场。 本次合作伙伴签约&#xff0c;阿里云与消息流开创领导者 Confluent 将进一…

git入门指南:新手快速上手git(Linux环境如何使用git)

目录 前言 1. 什么是git&#xff1f; 2. git版本控制器 3. git在Linux中的使用 安装git 4. git三板斧 第一招&#xff1a;add 第二招&#xff1a;commit 第三招&#xff1a;push 5. 执行状态 6. 删除 总结 前言 Linux的基本开发工具介绍完毕&#xff0c;接下来介绍一…

重构云计算,打造 AI 原生时代的云计算产品与技术体系,实现 AI 零距离

概述 自 ChatGPT 大模型横空出世以来&#xff0c;文心一言、通义千问等诸多大模型接踵而来&#xff0c;感觉这个世界每天都在发生着翻天覆地的变化。 今年很有幸&#xff0c;参与了云栖的盛宴&#xff0c;当时被震惊到瞠目结舌&#xff0c;12 月 20 日百度云智能云智算大会&a…

Flink实时电商数仓(五)

FlinkSQL的join Regular join普通join&#xff0c;两条流的数据都时存放在内存的状态中&#xff0c;如果两条流数据都很大&#xff0c;对内存压力很大。Interval Join: 适合两条流到达时间有先后关系的&#xff1b;一条流的存活时间短&#xff0c;一条流的存活时间长。Lookup …

(一)深入理解Mysql底层数据结构和算法

什么是索引 索引是帮助MySQL高效获取数据的排好序的数据结构 数据结构有哪些 数据结构模拟网站&#xff1a;Data Structure Visualization 二叉树 不适合做自增ID的数据结构。如下示意图&#xff0c;假设采用二叉树作为表自增主键ID的数据存储结果如下&#xff1a;当查询i…

docker笔记1-安装与基础命令

docker的用途&#xff1a; 可以把应用程序代码及运行依赖环境打包成镜像&#xff0c;作为交付介质&#xff0c;在各种环境部署。可以将镜像&#xff08;image&#xff09;启动成容器&#xff08;container&#xff09;&#xff0c;并提供多容器的生命周期进行管理&#xff08;…

异常处理和单元测试python

一、实验题目 异常处理和单元测试 二、实验目的 了解异常的基本概念和常用异常类。掌握异常处理的格式、处理方法。掌握断言语句的作用和使用方法。了解单元测试的基本概念和作用。掌握在Python中使用测试模块进行单元测试的方法和步骤。 三、实验内容 编程实现如下功能&a…

HTTP小记1

目录 post不一定比get安全 HTTP与HTTPS区别 HTTP/1.1的优点 长连接的好处 HTTP/1.1性能 post不一定比get安全 post用bady传输数据&#xff0c;get用url传输数据&#xff0c;但这并不能说get就是比post安全的。 在浏览器地址栏可以看到使用get请求明文传输的数据&#xff…

C++11并发与多线程

C11并发与多线程 1. 线程是进程中的实际运作单位 并发&#xff1a;两个或者更多的任务&#xff08;独立的活动&#xff09;同时发生&#xff08;进行&#xff09;&#xff1a;一个程序同时执行多个独立的任务 进程&#xff1a;一个可执行程序运行起来了&#xff0c;就叫创建了…

蓝桥杯2019年11月青少组Python程序设计省赛真题

1、试编写一个程序,输入一个整数,输出它的各个数位之和。 2、试编写一个程序,输入一个带有小数的数字,输出它的各个数位之和。 3、小兰要为1-2020住户制作门牌号,例如制作1107号门牌,需要制作2块1字符,一块0"字符一块7"字符,求制作1-2020需要多少块2. 4、编程画…

【量化金融】证券投资学

韭菜的自我修养 第一章&#xff1a; 基本框架和概念1.1 大盘底部形成的技术条件1.2 牛市与熊市1.3 交易系统1.3.1 树懒型交易系统1.3.2 止损止损的4个技术 第二章&#xff1a;证券家族4兄弟2.1 债券&#xff08;1&#xff09;债券&#xff0c;是伟大的创新&#xff08;2&#x…

【零基础入门Python】Python参数

✍面向读者&#xff1a;所有人 ✍所属专栏&#xff1a;零基础入门Pythonhttps://blog.csdn.net/arthas777/category_12455877.html 目录 print&#xff08;&#xff09;中的Python结束参数 print&#xff08;&#xff09;中的Python|sep参数 Python的格式转换规则 使用格式…

【数据结构入门精讲 | 第十五篇】散列表知识点及考研408、企业面试练习(2)

在上一篇文章中我们学习了散列表的相关知识点及进行了选择题、编程题的练习&#xff0c;这篇文章中我们将进行编程题的练习&#xff0c;带领读者以练代学、更好地掌握知识点。 目录 R7-1 QQ帐户的申请与登陆R7-2 词频统计R7-3 新浪微博热门话题R7-4 航空公司VIP客户查询R7-1 字…

生成allure报告出现:ALLURE REPORT UNKNOWN

问题&#xff1a;点击浏览器查看时无法查看到报告 错误代码&#xff1a; if __name__ "__main__":pytest.main([./test_study/test_fixture.py])os.system("allure generate ./temps -o ./temps --clean") 结果导向&#xff1a; 解决&#xff1a;因为…