Unity中绘制抛物线

10 篇文章 0 订阅
效果如下:
 


之所以加个2,是因为我以前写过一个抛物线的文章,之前的文章请看这: Unity绘制抛物线代码 上一篇文章只是简单地绘制了一个抛物线,但是无法随意移动或者旋转,最近因为做个项目可能会用到这个抛物线,所以我做了一些修改,现在抛物线可以跟随着起始点移动、旋转,还加入了碰撞盒检测的功能。

[C#]  纯文本查看  复制代码
?
 
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class ParabolaRay : MonoBehaviour
{
     /*
     抛物线公式:y=a*x*x+b*x+c,由于z轴方向为正方向,所以:y=a*z*z+b*z+c,我们把抛出点设为原点(0,0),所以抛物线为y=a*z*z+b*z。
     */
     public float a; //控制抛物线的开口和大小
     private float k; //k为抛物线上抛出点的切线 y=kx+d 的斜率,我们把抛出点设为原点,所以:y = kx,k = 2ax +b
     private float b; // 我们把抛出点设为坐标原点,所以由k = 2ax + b,b = k;
     public LineRenderer line; //抛物线的LineRenderer组件
     public int density; //抛物线的精度
     public float space = 5; //每个节点间的间隔
                        // y = a*space*space+b*space
 
     public GameObject sphere;
     List<GameObject> points = new List<GameObject>();
     Vector3 prevPoint;
     void Start()
     {
         for ( int i = 0; i < density; i++)
         {
             points.Add(Instantiate(sphere));
         }
         line.SetVertexCount(density+1);
         prevPoint = transform.position;
     }
 
     // Update is called once per frame
     void Update()
     {
         Vector3 f = transform.forward;
         f.y = 0;
         k = transform.forward.y/f.magnitude; //算出切线斜率(注意物体的旋转角度,当forward为垂直方向时,也就是f.magnitude的值为0的时候,应该为一条直线,这里没有考虑这个情况)
         b = k;
 
         bool cast = false ;
         for ( int i = 0; i < density; i++)
         {
             Vector3 p = GetPosition(i * space);
             points[i].transform.position = p;
             cast = Cast(p);
             if (cast)
             {
                 break ;
             }
         }
         if (!cast)
         {
 
         }
     }
     /// <summary>
     /// 根据z确定点坐标
     /// </summary>
     /// <param name="z"></param>
     /// <returns></returns>
     Vector3 GetPosition( float z)
     {
         float y = a * z * z + b * z;
         Vector3 f = transform.forward;
         f.y = 0;
         f = f.normalized;
 
         Vector3 pos = transform.position + f * z; //水平方向坐标
         pos.y = transform.position.y + y; //加上垂直方向坐标
         return pos;
     }
     
     /// <summary>
     /// 进行抛物线检测
     /// </summary>
     /// <param name="currentPoint"></param>
     /// <returns></returns>
     bool Cast(Vector3 currentPoint)
     {
         Vector3 d = currentPoint - prevPoint;
         RaycastHit hit;
         if (Physics.Raycast(prevPoint, d.normalized, out hit, d.magnitude))
         {
             SetLine(hit.point);
             prevPoint = transform.position;
             return true ;
         }
         else
         {
             prevPoint = currentPoint;
             return false ;
         }
     }
 
     /// <summary>
     /// 设置抛物线上每个点
     /// </summary>
     /// <param name="endPos"></param>
     void SetLine(Vector3 endPos)
     {
         Vector3 s = transform.position;
         endPos.y = 0;
         s.y = 0;
 
         float j = Vector3.Distance(s, endPos) / density;
 
         for ( int i = 0; i < density; i++)
         {
             line.SetPosition(i, GetPosition(i * j));
         }
         line.SetPosition(density, endPos);
         sphere.transform.position = endPos;
     }
}



在上面的代码中,我们把起始点作为坐标原点,把起始点的正方向作为抛物线的切线,然后我们只需要设置a值就能求出抛物线的方程了。

关于抛物线的斜率,三维空间和二维空间的斜率求法还是有区别的,如下图:   

我们应该把向量的 垂直方向的长度/水平方向的长度 作为切线的斜率,但是这里要考虑到 向量与Y轴平行的情况 ,我的脚本里还没有加入这种情况的判断。
另外一点就是抛物线检测碰撞盒,我们可以把抛物线划分为若干段线段,每个线段进行一次检测,当检测到碰撞盒的时候,我们可以停止检测。

最后如果大佬觉得有什么地方不对的话,欢迎指正!
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
Unity是一款强大的游戏开发引擎,支持创建各种3D和2D游戏。在Unity,要创建抛物线效果的网格(mesh),可以使用以下步骤: 1. 首先,在Unity创建一个空物体作为抛物线网格的父物体。 2. 在该空物体上添加一个Mesh Filter(网格过滤器)组件,并设置其Mesh属性为一个新创建的Mesh实例。 3. 继续在该空物体上添加一个Mesh Renderer(网格渲染器)组件,这样就可以在游戏场景看到抛物线网格的显示效果。 4. 在代码,先创建一个空的Mesh实例,并获取其顶点、法线、三角形索引等属性的引用。 5. 使用for循环来生成抛物线上的顶点位置。 6. 将顶点位置数据赋值给Mesh实例的vertices属性。 7. 计算并赋值Mesh实例的法线数据,以确保抛物线网格正确渲染光照效果。 8. 生成并赋值Mesh实例的三角形索引数据,用于指定顶点之间的连接顺序。 9. 调用Mesh实例的RecalculateBounds()方法来重新计算其边界,以确保抛物线网格在场景正确显示。 10. 使用Mesh Filter组件的sharedMesh属性引用生成的Mesh实例,进而实现抛物线网格的显示。 通过以上步骤,我们可以在Unity创建一个抛物线的网格。这个网格可以用于渲染游戏场景的物体,或者用于创建一些特殊的游戏效果,如飞行轨迹、弹道轨迹等。而Mesh这个类则是Unity用于创建和操纵网格的重要组件,通过设置其顶点、法线、纹理等属性,我们可以根据需求生成不同形状和效果的网格。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值