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

2024-01-02 14:04

本文主要是介绍提前预测刚体移动轨迹 预测运动轨迹,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

  • 一、效果
  • 二、介绍
  • 三、脚本
    • 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.chinasem.cn/article/562661

相关文章

我在移动打工的日志

客户:给我搞一下录音 我:不会。不在服务范围。 客户:是不想吧 我:笑嘻嘻(气笑) 客户:小姑娘明明会,却欺负老人 我:笑嘻嘻 客户:那我交话费 我:手机号 客户:给我搞录音 我:不会。不懂。没搞过。 客户:那我交话费 我:手机号。这是电信的啊!!我这是中国移动!! 客户:我不管,我要充话费,充话费是你们的 我:可是这是移动!!中国移动!! 客户:我这是手机号 我:那又如何,这是移动!你是电信!!

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

轨迹规划-B样条

B样条究竟是干啥的?白话就是给出一堆点,用样条的方式,给这些点连接起来,并保证丝滑的。 同时B样条分为准均匀和非均匀,以下为准均匀为例。 参考链接1:https://zhuanlan.zhihu.com/p/50626506https://zhuanlan.zhihu.com/p/50626506 参考链接2: https://zhuanlan.zhihu.com/p/536470972h

简单的角色响应鼠标而移动

actor类 //处理移动距离,核心是找到角色坐标在世界坐标的向量的投影(x,y,z),然后在世界坐标中合成,此CC是在地面行走,所以Y轴投影始终置为0; using UnityEngine; using System.Collections; public class actor : MonoBehaviour { public float speed=0.1f; CharacterCo

Unity3D 运动之Move函数和translate

CharacterController.Move 移动 function Move (motion : Vector3) : CollisionFlags Description描述 A more complex move function taking absolute movement deltas. 一个更加复杂的运动函数,每次都绝对运动。 Attempts to

全英文地图/天地图和谷歌瓦片地图杂交/设备分布和轨迹回放/无需翻墙离线使用

一、前言说明 随着风云局势的剧烈变化,对我们搞软件开发的人员来说,影响也是越发明显,比如之前对美对欧的软件居多,现在慢慢的变成了对大鹅和中东以及非洲的居多,这两年明显问有没有俄语或者阿拉伯语的输入法的增多,这要是放在2019年以前,一年也遇不到一个人问这种需求场景的。 地图应用这块也是,之前的应用主要在国内,现在慢慢的多了一些外国的应用场景,这就遇到一个大问题,我们平时主要开发用的都是国内的地

物联网之流水LED灯、正常流水灯、反复流水灯、移动流水灯

MENU 硬件电路设计软件程序设计正常流水LED灯反复流水LED灯移动流水LED灯 硬件电路设计 材料名称数量直插式LED1kΩ电阻杜邦线(跳线)若干面包板1 每一个LED的正极与开发板一个GPIO引脚相连,并串联一个电阻,负极接GND。 当然也可以选择只使用一个电阻。 软件程序设计 正常流水LED灯 因为要用到多个GPIO引脚,所以最好把所有的GPI

12C 新特性,MOVE DATAFILE 在线移动 包括system, 附带改名 NID ,cdb_data_files视图坏了

ALTER DATABASE MOVE DATAFILE  可以改名 可以move file,全部一个命令。 resue 可以重用,keep好像不生效!!! system照移动不误-------- SQL> select file_name, status, online_status from dba_data_files where tablespace_name='SYSTEM'

《C++中的移动构造函数与移动赋值运算符:解锁高效编程的最佳实践》

在 C++的编程世界中,移动构造函数和移动赋值运算符是提升程序性能和效率的重要工具。理解并正确运用它们,可以让我们的代码更加高效、简洁和优雅。 一、引言 随着现代软件系统的日益复杂和对性能要求的不断提高,C++程序员需要不断探索新的技术和方法来优化代码。移动构造函数和移动赋值运算符的出现,为解决资源管理和性能优化问题提供了有力的手段。它们允许我们在不进行不必要的复制操作的情况下,高效地转移资源

创建一个大的DIV,里面的包含两个DIV是可以自由移动

创建一个大的DIV,里面的包含两个DIV是可以自由移动 <body>         <div style="position: relative; background:#DDF8CF;line-height: 50px"> <div style="text-align: center; width: 100%;padding-top: 0px;"><h3>定&nbsp;位&nbsp;