Unity中模拟抛物线(非Unity物理)

Unity中模拟抛物线非Unity物理

  • 介绍
  • 剖析问题以及所需公式
    • 重力加速度公式:h = 1/2*g*t*t(h = 1/2 * g * t ^ 2)
    • 速度公式:Vt = V初 + a * t
  • 主要代码
  • 总结

介绍

请添加图片描述

用Unity物理系统去做的抛物线想要控制速度或者想要细微的控制一些情况是非常困难的。所以想要脱离Unity的物理去做一个模拟抛物线的运动,最近在做关于模拟物理抛物线方面的研究。也主要是想要让这个模拟更加有可控性,这样就可以更好的去做游戏中的变化。

如上图gif中分别对应了一个start小白球和一个 end小白球分别代表抛物线经过的方向,并且可以通过设置抛出去的高度来管理这条抛物线。

剖析问题以及所需公式

重力加速度公式:h = 1/2gt*t(h = 1/2 * g * t ^ 2)

速度公式:Vt = V初 + a * t

主要用到了上述这两个公式,通过这两个公式去计算出来模拟抛物线运动。

主要代码

代码中我分别对每一步骤都注释了也很方便能看出来,这里不附带工程了 工程很简单,根据我提供的代码自己搭一下场景即可。

using UnityEngine;

/// <summary>
/// 抛物线
/// </summary>
public class ParabolaPath
{
    /// <summary>
    /// 起始点位
    /// </summary>
    private Vector3 m_start;

    /// <summary>
    /// 目标点位
    /// </summary>
    private Vector3 m_end;

    /// <summary>
    /// 重力
    /// </summary>
    private float m_gravity;

    /// <summary>
    /// 总时间
    /// </summary>
    private float m_totalTime;

    /// <summary>
    /// 初速度
    /// </summary>
    private Vector3 m_velocityStart;

    /// <summary>
    /// 当前位置信息
    /// </summary>
    private Vector3 m_position;

    /// <summary>
    /// 时间
    /// </summary>
    private float m_time;

    /// <summary> 初始化抛物线运动轨迹 </summary>
    /// <param name="start">起点</param>
    /// <param name="end">终点</param>
    /// <param name="height">高度(相对于两个点的最高位置 高出多少)</param>
    /// <param name="gravity">重力加速度(负数)</param>
    /// <returns></returns>
    public ParabolaPath(Vector3 start, Vector3 end, float height = 10, float gravity = -9.8f)
    {
        Init(start, end, height, gravity);
    }

    /// <summary> 初始化抛物线运动轨迹 </summary>
    /// <param name="start">起点</param>
    /// <param name="end">终点</param>
    /// <param name="height">高度(相对于两个点的最高位置 高出多少)</param>
    /// <param name="gravity">重力加速度(负数)</param>
    /// <returns></returns>
    public void Init(Vector3 start, Vector3 end, float height = 10, float gravity = -9.8f)
    {
        //求出最高点 开始点和结束点取最高点然后根据最高点加上对应的高度
        float topY = Mathf.Max(start.y, end.y) + height;

        //上升阶段的竖直距离(上升阶段的高度)
        float d1 = topY - start.y;

        //下降阶段的竖直距离(下降阶段的高度)
        float d2 = topY - end.y;

        //重力公式为 h = 1/2 * g * t^2
        //转换公式 t^2 = 2 * h / g
        float g2 = 2 / -gravity;

        //利用公式 h = g * t * t / 2 来算出上升阶段的时间
        float t1 = Mathf.Sqrt(g2 * d1);

        //利用公式 h = g * t * t / 2 来算出下降阶段的时间
        float t2 = Mathf.Sqrt(g2 * d2);

        //抛物线运行的总时间
        float t = t1 + t2;

        //计算出在水平方向上的两个轴的移动速度
        //vX(同时也是水平方向的初始速度)
        float vX = (end.x - start.x) / t;
        //vZ(同时也是水平方向的初始速度)
        float vZ = (end.z - start.z) / t;

        //计算出竖直方向上的初速度 vY
        //根据V末 = V初 + a * t (到达最高点的时候 V末为0 则V初 = -a * t)
        //V末为0正好上下抵消了 所以V末 = 0  所以公式变为 V初 = -a * t
        //到这里初始速度的3个分量都计算完毕
        float vY = -gravity * t1;

        //起点坐标
        m_start = start;

        //目标点
        m_end = end;

        //重力
        m_gravity = gravity;

        //总时间
        m_totalTime = t;

        //初速度
        m_velocityStart = new Vector3(vX, vY, vZ);

        //目标位置
        m_position = m_start;

        //计时使用
        m_time = 0;
    }

    /// <summary>
    /// 初始位置
    /// </summary>
    public Vector3 start
    {
        get { return m_start; }
    }

    /// <summary>
    /// 结束位置
    /// </summary>
    public Vector3 end
    {
        get { return m_end; }
    }

    /// <summary>
    /// 总时间
    /// </summary>
    public float totalTime
    {
        get { return m_totalTime; }
    }

    /// <summary>
    /// 初始速度
    /// </summary>
    public Vector3 velocityStart
    {
        get { return m_velocityStart; }
    }

    /// <summary>
    /// 当前位置
    /// </summary>
    public Vector3 position
    {
        get { return m_position; }
    }

    /// <summary>
    /// 当前速度
    /// </summary>
    public Vector3 velocity
    {
        get { return GetVelocity(m_time); }
    }

    /// <summary>
    /// 当前时间
    /// </summary>
    public float time
    {
        get { return m_time; }

        set
        {
            value = Mathf.Clamp(value, 0, m_totalTime);

            m_time = value;

            m_position = GetPosition(value);
        }
    }

    /// <summary>
    /// 获取某个时间点的位置
    /// </summary>
    /// <param name="time"></param>
    /// <returns></returns>
    public Vector3 GetPosition(float time)
    {
        if (time == 0)
        {
            return m_start;
        }

        if (time == m_totalTime)
        {
            return m_end;
        }

        //重力影响的相下的移动
        float dY = 0.5f * m_gravity * time * time;

        //开始位置 + 初速度的位置 + 自由落体的位置差
        return m_start + m_velocityStart * time + new Vector3(0, dY, 0);
    }

    /// <summary>
    /// 获取某个时间点的速度
    /// </summary>
    /// <param name="time"></param>
    /// <returns></returns>
    public Vector3 GetVelocity(float time)
    {
        if (time == 0)
        {
            return m_velocityStart;
        }
        //根据 V末 = V初 + at  
        return m_velocityStart + new Vector3(0, m_gravity * time, 0);
    }

}

总结

这是对抛物线的分析以及对抛物线实现的原理和代码,感谢大家的支持。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flutter——最详细(Drawer)使用教程

背景 应用左侧或右侧导航面板&#xff1b; 属性作用elevation相当于阴影的大小 import package:flutter/material.dart;class CustomDrawer extends StatelessWidget {const CustomDrawer({Key? key}) : super(key: key);overrideWidget build(BuildContext context) {return…

【Python】已解决ModuleNotFoundError: No module named ‘tensorflow‘

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决ModuleNotFoundError: No module named ‘tensorflow‘ 一、分析问题背景 ModuleNotFoundError: No module named ‘tensorflow’ 是一个常见的错误&#xff0c;通常在Pytho…

MATLAB常用语句总结7

MATLAB总结7&#xff1a;常见错误归纳 文章目录 MATLAB总结7&#xff1a;常见错误归纳前言一、rand 的使用二、蒙塔卡罗求解方法1.函数的定义2.函数引用 三、函数引用与多变量四、矩阵引用五、非线性函数&#xff1a;fmincon的使用六、线性规划函数1.linprog2.fminbnd、fminsea…

Docker学习笔记(二)镜像、容器、仓库相关命令操作

一、docker镜像操作 列出镜像列表 我们可以使用 docker images 来列出本地主机上的镜像。 各个选项说明: REPOSITORY&#xff1a;表示镜像的仓库源 TAG&#xff1a;镜像的标签 IMAGE ID&#xff1a;镜像ID CREATED&#xff1a;镜像创建时间 SIZE&#xff1a;镜像大小 查…

pdf太大怎么压缩大小,pdf文件太大如何压缩变小

在数字化时代&#xff0c;pdf文件已成为我们工作、学习和生活中不可或缺的一部分。然而&#xff0c;随着文件内容的丰富&#xff0c;pdf文件的体积也日益增大&#xff0c;给存储和传输带来不便。本文将为你详细介绍四种实用的pdf文件压缩方法&#xff0c;帮助你轻松减小pdf容量…

【ROS2】初级:CLI工具 -配置环境

目标&#xff1a;本教程将指导您如何准备您的 ROS 2 环境。 教程级别&#xff1a;初学者 时间&#xff1a;5 分钟 目录 背景 先决条件 任务 源代码设置文件将源添加到您的 shell 启动脚本检查环境变量 摘要 下一步 背景 ROS 2 依赖于使用 shell 环境组合工作空间的概念。“Work…

C# Winform自制多轴力臂(简单易懂,方便扩展)

WinForms框架广泛应用于上位机开发领域&#xff0c;其中对力臂的精准控制是常见需求之一。本文深入探讨了如何创建自定义的多轴力臂图形控件&#xff0c;不仅涵盖了力臂图形控件的角度调节机制&#xff0c;还详细展示了如何实现力臂运动的生动动态效果&#xff0c;为开发者提供…

解决VSCode中导入PyTorch时报错的HTTP错误与Channel冲突

问题描述与解释 在Anaconda中成功安装PyTorch&#xff0c;并进行了验证&#xff1a; (base) C:\Users\Hui>conda activate pytorch(pytorch) C:\Users\\Hui>python Python 3.8.19 (default, Mar 20 2024, 19:55:45) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on …

妙手ERP支持授权TikTok Shop全托管店铺,支持智能编辑、定时发布等操作!

全托管模式可以说是近两年跨境电商的热潮&#xff0c;在全托管模式下&#xff0c;卖家只需备货&#xff0c;平台进行运营、履约。因此&#xff0c;这种模式也迅速成为计划出海的跨境卖家重点关注方向。 一、TikTok Shop全托管 目前&#xff0c;几大主流跨境电商平台都已上线全…

springboot旅游管理系统-计算机毕业设计源码16021

摘 要 本文旨在设计和实现一个基于Spring Boot框架的旅游管理系统。该系统通过利用Spring Boot的快速开发特性和丰富的生态系统&#xff0c;提供了一个高效、可靠和灵活的解决方案。系统将实现旅游景点信息的管理、线路规划、跟团游玩、旅游攻略、酒店信息管理、订单管理和用户…

【操作与配置】VSCode配置C/C++及远程开发

MINGW环境配置 进入网站&#xff0c;如下图下载&#xff1a;MinGW Distro - nuwen.net 运行安装包&#xff0c;使其安装在你指定的位置 将MinGW的bin目录添加到系统的环境变量PATH中 使用 winx 选择进入“系统”点击“高级系统设置”在“系统属性&#xff1a;高级”窗口中&am…

Vue前端打包

关于NGINX 介绍:Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少&#xff0c;并发能力强&#xff0c;在各大型互联网公司都有非常广泛的使用。 NGiMx 官网:https://nginx.org/ conf 配置文件目录 html静态资源文件目录 lo…

学习笔记(linux高级编程)11

进程间通信 》信号通信 应用&#xff1a;异步通信。 中断&#xff0c;&#xff0c; 1~64&#xff1b;32应用编程。 如何响应&#xff1a; Term Default action is to terminate the process. Ign Default action is to ignore the signal. wait Core Default action is …

Ignis 应用: 社交 + 游戏 + 工业4.0,Ignis 构建Web3生态圈

引言 在数字经济快速发展的今天&#xff0c;Web3技术为我们带来了前所未有的变革。作为Ardor平台的主要子链&#xff0c;Ignis公链在推动Web3生态系统建设中扮演了重要角色。本文将通过介绍Vessel Chain、Mythical Beings和Bridge Champ等应用&#xff0c;探讨Ignis公链如何通…

基于循环神经网络的一维信号降噪方法(简单版本,Python)

代码非常简单。 import torch import torch.nn as nn from torch.autograd import Variable from scipy.io.wavfile import write #need install pydub module #pip install pydub import numpy as np import pydub from scipy import signal import IPython import matplot…

基于强化学习DQN的股票预测【股票交易】

强化学习笔记 第一章 强化学习基本概念 第二章 贝尔曼方程 第三章 贝尔曼最优方程 第四章 值迭代和策略迭代 第五章 强化学习实例分析:GridWorld 第六章 蒙特卡洛方法 第七章 Robbins-Monro算法 第八章 多臂老虎机 第九章 强化学习实例分析:CartPole 第十章 时序差分法 第十一…

swiftui中常用组件picker的使用,以及它的可选样式

一个可选项列表就是一个picker组件搞出来的&#xff0c;它有多个样式可以选择&#xff0c;并且可以传递进去一些可选数据&#xff0c;有点像前端页面里面的seleted组件&#xff0c;但是picker组件的样式可以更多。可以看官方英文文档&#xff1a;PickerStyle | Apple Developer…

【Week-G2】人脸图像生成(DCGAN)--pytorch版本

文章目录 0、遇到的问题1、配置环境 & 导入数据2、定义模型3、训练模型4、什么是DCGAN? &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 本文环境&#xff1a; 系统环境&#xff1a;…

从搜索框的提示词中再探防抖和节流

前言 最近逛掘金时&#xff0c;看到了一篇文章。发现是我之前写过的一篇文章主题是防抖和节流的&#xff0c;看防抖时没感觉哪里不一样&#xff0c;但是当我看到节流时发现他的节流怎么这么繁琐(・∀・(・∀・(・∀・*)&#xff1f; 抱着疑惑的想法&#xff0c;我仔细拜读了这…

PyCharm 如何设置作者信息

1、点击pycharm右上角的齿轮&#xff0c;选择settings 2、选择editor 3、选择 Editor File and Code Templates 4、选择作者信息的文件类型&#xff0c;中间选择框选择Python Script 5、然后在右边的输入框中输入相关的信息 # -*- coding: utf-8 -*- """ Time …