博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
unity3D:游戏分解之曲线
阅读量:5807 次
发布时间:2019-06-18

本文共 6792 字,大约阅读时间需要 22 分钟。

一提到曲线,很多新手就头疼了,包括我。查了很多资料,终于有个大概的了解。想深入了解曲线原理的,推荐一个链接

之前写了一篇博文,里面用到了曲线插值,这里算是对上篇博文的一个补充

先看一下曲线的效果

 

在使用NGUI的过程中,发现iTween.cs里面有两个很有用的方法,一个是输入指定路点数组,一个就是曲线的插值算法。今天我们主要就用到这两个方法来实现曲线效果。

1 public static Vector3[] PathControlPointGenerator(Vector3[] path) 2     { 3         Vector3[] suppliedPath; 4         Vector3[] vector3s; 5  6         //create and store path points: 7         suppliedPath = path; 8  9         //populate calculate path;10         int offset = 2;11         vector3s = new Vector3[suppliedPath.Length + offset];12         Array.Copy(suppliedPath, 0, vector3s, 1, suppliedPath.Length);13 14         //populate start and end control points:15         //vector3s[0] = vector3s[1] - vector3s[2];16         vector3s[0] = vector3s[1] + (vector3s[1] - vector3s[2]);17         vector3s[vector3s.Length - 1] = vector3s[vector3s.Length - 2] + (vector3s[vector3s.Length - 2] - vector3s[vector3s.Length - 3]);18 19         //is this a closed, continuous loop? yes? well then so let's make a continuous Catmull-Rom spline!20         if (vector3s[1] == vector3s[vector3s.Length - 2])21         {22             Vector3[] tmpLoopSpline = new Vector3[vector3s.Length];23             Array.Copy(vector3s, tmpLoopSpline, vector3s.Length);24             tmpLoopSpline[0] = tmpLoopSpline[tmpLoopSpline.Length - 3];25             tmpLoopSpline[tmpLoopSpline.Length - 1] = tmpLoopSpline[2];26             vector3s = new Vector3[tmpLoopSpline.Length];27             Array.Copy(tmpLoopSpline, vector3s, tmpLoopSpline.Length);28         }29 30         return (vector3s);31     }32 33     //andeeee from the Unity forum's steller Catmull-Rom class ( http://forum.unity3d.com/viewtopic.php?p=218400#218400 ):34     public static Vector3 Interp(Vector3[] pts, float t)35     {36         int numSections = pts.Length - 3;37         int currPt = Mathf.Min(Mathf.FloorToInt(t * (float)numSections), numSections - 1);38         float u = t * (float)numSections - (float)currPt;39 40         if(currPt == 0)41         {42             int dsd = 0;43         }44 45         Vector3 a = pts[currPt];46         Vector3 b = pts[currPt + 1];47         Vector3 c = pts[currPt + 2];48         Vector3 d = pts[currPt + 3];49 50         return .5f * (51             (-a + 3f * b - 3f * c + d) * (u * u * u)52             + (2f * a - 5f * b + 4f * c - d) * (u * u)53             + (-a + c) * u54             + 2f * b55         );56     }

 

直接上完整代码,把这个脚本放到相机上,然后在场景中拖几个物件作为路点,就可以实现上面的效果

1 using System;  2 using System.Collections.Generic;  3 using UnityEngine;  4   5 namespace Fish.Study.Curve  6 {  7     ///   8     /// 曲线测试  9     ///  10     public class CurveTest : MonoBehaviour 11     { 12         //路点 13         public GameObject[] GameObjectList; 14         //各路点的坐标 15         public List
TransDataList = new List
(); 16 17 void Start() 18 { 19 } 20 21 //Gizmos 22 void OnDrawGizmos() 23 { 24 //1个点是不能画出曲线的,2个点实际上是直线 25 if (GameObjectList.Length <= 1) return; 26 27 TransDataList.Clear(); 28 for (int i = 0; i < GameObjectList.Length; ++i) 29 { 30 TransDataList.Add(GameObjectList[i].transform.position); 31 } 32 33 if (TransDataList != null && TransDataList.Count > 1) 34 { 35 DrawPathHelper(TransDataList.ToArray(), Color.red); 36 } 37 } 38 39 public Vector3[] GetCurveData() 40 { 41 if (TransDataList != null && TransDataList.Count > 1) 42 { 43 var v3 = (TransDataList.ToArray()); 44 Vector3[] vector3s = PathControlPointGenerator(v3); 45 return vector3s; 46 } 47 48 return null; 49 } 50 51 //NGUI iTween.cs中的方法,输入路径点 52 public static Vector3[] PathControlPointGenerator(Vector3[] path) 53 { 54 Vector3[] suppliedPath; 55 Vector3[] vector3s; 56 57 //create and store path points: 58 suppliedPath = path; 59 60 //populate calculate path; 61 int offset = 2; 62 vector3s = new Vector3[suppliedPath.Length + offset]; 63 Array.Copy(suppliedPath, 0, vector3s, 1, suppliedPath.Length); 64 65 //populate start and end control points: 66 vector3s[0] = vector3s[1] + (vector3s[1] - vector3s[2]); 67 vector3s[vector3s.Length - 1] = vector3s[vector3s.Length - 2] + (vector3s[vector3s.Length - 2] - vector3s[vector3s.Length - 3]); 68 69 //is this a closed, continuous loop? yes? well then so let's make a continuous Catmull-Rom spline! 70 if (vector3s[1] == vector3s[vector3s.Length - 2]) 71 { 72 Vector3[] tmpLoopSpline = new Vector3[vector3s.Length]; 73 Array.Copy(vector3s, tmpLoopSpline, vector3s.Length); 74 tmpLoopSpline[0] = tmpLoopSpline[tmpLoopSpline.Length - 3]; 75 tmpLoopSpline[tmpLoopSpline.Length - 1] = tmpLoopSpline[2]; 76 vector3s = new Vector3[tmpLoopSpline.Length]; 77 Array.Copy(tmpLoopSpline, vector3s, tmpLoopSpline.Length); 78 } 79 80 return (vector3s); 81 } 82 83 //曲线插值函数 84 public static Vector3 Interp(Vector3[] pts, float t) 85 { 86 int numSections = pts.Length - 3; 87 int currPt = Mathf.Min(Mathf.FloorToInt(t * (float)numSections), numSections - 1); 88 float u = t * (float)numSections - (float)currPt; 89 90 Vector3 a = pts[currPt]; 91 Vector3 b = pts[currPt + 1]; 92 Vector3 c = pts[currPt + 2]; 93 Vector3 d = pts[currPt + 3]; 94 95 return .5f * ( 96 (-a + 3f * b - 3f * c + d) * (u * u * u) 97 + (2f * a - 5f * b + 4f * c - d) * (u * u) 98 + (-a + c) * u 99 + 2f * b100 );101 }102 103 //画曲线104 private void DrawPathHelper(Vector3[] path, Color color)105 {106 Vector3[] vector3s = PathControlPointGenerator(path);107 108 //Line Draw:109 Vector3 prevPt = Interp(vector3s, 0);110 int SmoothAmount = path.Length * 20;111 for (int i = 1; i <= SmoothAmount; i++)112 {113 float pm = (float)i / SmoothAmount;114 Vector3 currPt = Interp(vector3s, pm);115 116 Gizmos.color = color;117 Gizmos.DrawSphere(currPt, 0.2f);118 prevPt = currPt;119 }120 }121 }122 }

 

转载于:https://www.cnblogs.com/fishyu/p/6817509.html

你可能感兴趣的文章
python----slots属性安全类
查看>>
《Programming WPF》翻译 第5章 1.不使用样式
查看>>
.NET垃圾回收:非托管资源,IDispose和析构函数的结合
查看>>
H2内存数据库 支持存储到文件
查看>>
css3处理sprite背景图压缩来解决H5网页在手机浏览器下图标模糊的问题
查看>>
BlockCanary 一个轻量的,非侵入式的性能监控组件(阿里)
查看>>
【HDU 1228】A + B
查看>>
CentOS 7搭建SVN服务器
查看>>
Atitit.远程接口 监控与木马 常用的api 标准化v2 q216
查看>>
Floyd最短路算法
查看>>
Class.forName(String name)方法,到底会触发那个类加载器进行类加载行为?
查看>>
CentOS 6.6 FTP install
查看>>
C#------判断btye[]是否为空
查看>>
图解Ajax工作原理
查看>>
oracle导入导出小记
查看>>
聊一聊log4j2配置文件log4j2.xml
查看>>
NeHe OpenGL教程 第七课:光照和键盘
查看>>
修改上一篇文章的node.js代码,支持默认页及支持中文
查看>>
Php实现版本比较接口
查看>>
删除设备和驱动器中软件图标
查看>>