一提到曲线,很多新手就头疼了,包括我。查了很多资料,终于有个大概的了解。想深入了解曲线原理的,推荐一个链接http://www.cnblogs.com/jay-dong/archive/2012/09/26/2704188.html

之前写了一篇博文《unity3D:游戏分解之角色移动和相机跟随》,里面用到了曲线插值,这里算是对上篇博文的一个补充

先看一下曲线的效果

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

 public static Vector3[] PathControlPointGenerator(Vector3[] path)
{
Vector3[] suppliedPath;
Vector3[] vector3s; //create and store path points:
suppliedPath = path; //populate calculate path;
int offset = ;
vector3s = new Vector3[suppliedPath.Length + offset];
Array.Copy(suppliedPath, , vector3s, , suppliedPath.Length); //populate start and end control points:
//vector3s[0] = vector3s[1] - vector3s[2];
vector3s[] = vector3s[] + (vector3s[] - vector3s[]);
vector3s[vector3s.Length - ] = vector3s[vector3s.Length - ] + (vector3s[vector3s.Length - ] - vector3s[vector3s.Length - ]); //is this a closed, continuous loop? yes? well then so let's make a continuous Catmull-Rom spline!
if (vector3s[] == vector3s[vector3s.Length - ])
{
Vector3[] tmpLoopSpline = new Vector3[vector3s.Length];
Array.Copy(vector3s, tmpLoopSpline, vector3s.Length);
tmpLoopSpline[] = tmpLoopSpline[tmpLoopSpline.Length - ];
tmpLoopSpline[tmpLoopSpline.Length - ] = tmpLoopSpline[];
vector3s = new Vector3[tmpLoopSpline.Length];
Array.Copy(tmpLoopSpline, vector3s, tmpLoopSpline.Length);
} return (vector3s);
} //andeeee from the Unity forum's steller Catmull-Rom class ( http://forum.unity3d.com/viewtopic.php?p=218400#218400 ):
public static Vector3 Interp(Vector3[] pts, float t)
{
int numSections = pts.Length - ;
int currPt = Mathf.Min(Mathf.FloorToInt(t * (float)numSections), numSections - );
float u = t * (float)numSections - (float)currPt; if(currPt == )
{
int dsd = ;
} Vector3 a = pts[currPt];
Vector3 b = pts[currPt + ];
Vector3 c = pts[currPt + ];
Vector3 d = pts[currPt + ]; return .5f * (
(-a + 3f * b - 3f * c + d) * (u * u * u)
+ (2f * a - 5f * b + 4f * c - d) * (u * u)
+ (-a + c) * u
+ 2f * b
);
}

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

 using System;
using System.Collections.Generic;
using UnityEngine; namespace Fish.Study.Curve
{
/// <summary>
/// 曲线测试
/// </summary>
public class CurveTest : MonoBehaviour
{
//路点
public GameObject[] GameObjectList;
//各路点的坐标
public List<Vector3> TransDataList = new List<Vector3>(); void Start()
{
} //Gizmos
void OnDrawGizmos()
{
//1个点是不能画出曲线的,2个点实际上是直线
if (GameObjectList.Length <= ) return; TransDataList.Clear();
for (int i = ; i < GameObjectList.Length; ++i)
{
TransDataList.Add(GameObjectList[i].transform.position);
} if (TransDataList != null && TransDataList.Count > )
{
DrawPathHelper(TransDataList.ToArray(), Color.red);
}
} public Vector3[] GetCurveData()
{
if (TransDataList != null && TransDataList.Count > )
{
var v3 = (TransDataList.ToArray());
Vector3[] vector3s = PathControlPointGenerator(v3);
return vector3s;
} return null;
} //NGUI iTween.cs中的方法,输入路径点
public static Vector3[] PathControlPointGenerator(Vector3[] path)
{
Vector3[] suppliedPath;
Vector3[] vector3s; //create and store path points:
suppliedPath = path; //populate calculate path;
int offset = ;
vector3s = new Vector3[suppliedPath.Length + offset];
Array.Copy(suppliedPath, , vector3s, , suppliedPath.Length); //populate start and end control points:
vector3s[] = vector3s[] + (vector3s[] - vector3s[]);
vector3s[vector3s.Length - ] = vector3s[vector3s.Length - ] + (vector3s[vector3s.Length - ] - vector3s[vector3s.Length - ]); //is this a closed, continuous loop? yes? well then so let's make a continuous Catmull-Rom spline!
if (vector3s[] == vector3s[vector3s.Length - ])
{
Vector3[] tmpLoopSpline = new Vector3[vector3s.Length];
Array.Copy(vector3s, tmpLoopSpline, vector3s.Length);
tmpLoopSpline[] = tmpLoopSpline[tmpLoopSpline.Length - ];
tmpLoopSpline[tmpLoopSpline.Length - ] = tmpLoopSpline[];
vector3s = new Vector3[tmpLoopSpline.Length];
Array.Copy(tmpLoopSpline, vector3s, tmpLoopSpline.Length);
} return (vector3s);
} //曲线插值函数
public static Vector3 Interp(Vector3[] pts, float t)
{
int numSections = pts.Length - ;
int currPt = Mathf.Min(Mathf.FloorToInt(t * (float)numSections), numSections - );
float u = t * (float)numSections - (float)currPt; Vector3 a = pts[currPt];
Vector3 b = pts[currPt + ];
Vector3 c = pts[currPt + ];
Vector3 d = pts[currPt + ]; return .5f * (
(-a + 3f * b - 3f * c + d) * (u * u * u)
+ (2f * a - 5f * b + 4f * c - d) * (u * u)
+ (-a + c) * u
+ 2f * b
);
} //画曲线
private void DrawPathHelper(Vector3[] path, Color color)
{
Vector3[] vector3s = PathControlPointGenerator(path); //Line Draw:
Vector3 prevPt = Interp(vector3s, );
int SmoothAmount = path.Length * ;
for (int i = ; i <= SmoothAmount; i++)
{
float pm = (float)i / SmoothAmount;
Vector3 currPt = Interp(vector3s, pm); Gizmos.color = color;
Gizmos.DrawSphere(currPt, 0.2f);
prevPt = currPt;
}
}
}
}

unity3D:游戏分解之曲线的更多相关文章

  1. Unity3d游戏中自定义贝塞尔曲线编辑器[转]

    关于贝塞尔曲线曲线我们再前面的文章提到过<Unity 教程之-在Unity3d中使用贝塞尔曲线>,那么本篇文章我们来深入学习下,并自定义实现贝塞尔曲线编辑器,贝塞尔曲线是最基本的曲线,一般 ...

  2. Unity3D游戏开发初探—2.初步了解3D模型基础

    一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被. ...

  3. Unity3D游戏在iOS上因为trampolines闪退的原因与解决办法

    http://7dot9.com/?p=444 http://whydoidoit.com/2012/08/20/unity-serializer-mono-and-trampolines/ 确定具体 ...

  4. unity3d 游戏插件 溶解特效插件 - Dissolve Shader

    unity3d 游戏插件 溶解特效插件 - Dissolve Shader   链接: https://pan.baidu.com/s/1hr7w39U 密码: 3ed2

  5. 将Unity3D游戏移植到Android平台上

    将Unity3D游戏移植到Android平台是一件很容易的事情,只需要在File->Build Settings中选择Android平台,然后点击Switch Platform并Build出ap ...

  6. 从一点儿不会开始——Unity3D游戏开发学习(一)

    一些废话 我是一个windows phone.windows 8的忠实粉丝,也是一个开发者,开发数个windows phone应用和两个windows 8应用.对开发游戏一直抱有强烈兴趣和愿望,但奈何 ...

  7. unity3d游戏无法部署到windows phone8手机上的解决方法

    今天搞了个unity3d游戏,准备部署到自己的lumia 920上,数据线连接正常,操作正常,但是“build”以后,始终无法部署到手机上,也没有在选择的目录下生产任何相关文件.(你的系统必须是win ...

  8. Unity3D游戏UI开发经验谈

    原地址:http://news.9ria.com/2013/0629/27679.html 在Unity专场上,108km创始人梁伟国发表了<Unity3D游戏UI开发经验谈>主题演讲.他 ...

  9. Unity3D游戏开发之连续滚动背景

    Unity3D游戏开发之连续滚动背景 原文  http://blog.csdn.net/qinyuanpei/article/details/22983421 在诸如天天跑酷等2D游戏中,因为游戏须要 ...

随机推荐

  1. js中元素(图片)切换和隐藏显示问题

    这个知识点其实也简单,(当然是在理清思路的情况下),在没预习的情况下听的还真是艰难,上课以来唯一的一次懵逼了一天,感觉乱乱的,全是新属性,所以今晚的我破天荒的熬夜敲代码,一定要弄懂! 现在就来梳理下头 ...

  2. SQL SERVER大话存储结构(1)_数据页类型及页面指令分析

                如果转载,请注明博文来源: www.cnblogs.com/xinysu/   ,版权归 博客园 苏家小萝卜 所有.望各位支持!          SQLServer的数据页大 ...

  3. input 显示/隐藏密码

    js代码: // 显示/隐藏密码 $('.open').on('click',function(){ if($("#psw").prop('type')=='password'){ ...

  4. iOS 发布证书提示 此证书的签发者无效 解决办法

    1. 打开钥匙串  查看发布证书 都是提示 此证书的签发者无效   解决办法 : 2. 到了 第 4 步骤 再去 查看 发布证书 就会 显示  此证书有效 3.  如果还不可以 就 把 Apple W ...

  5. hdu4614 Vases and Flowers 线段树+二分

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614 题意: 给你N个花瓶,编号是0  到 N - 1 ,初始状态花瓶是空的,每个花瓶最多插一朵花. ...

  6. ——————————JavaScript中,对String字符串的一些操作——————————

    ————————————————————————————————————————————————————————————————————————————————————————————— <ht ...

  7. Linux的环境变量设置和查看

    一.Linux的变量种类 按变量的生存周期来划分,Linux变量可分为两类: 1.永久的:需要修改配置文件,变量永久生效. 2.临时的:使用export命令声明即可,变量在关闭shell时失效. 二. ...

  8. jquery之属性操作

    jQuery之属性操作 相信属性这个词对大家都不陌生.今天我就给大家简单地介绍一下JQuery一些属性的操作 属性一共分三大类 一.基本属性 1.attr 2.removeAttr 3.prop 4. ...

  9. RegExp(正则表达式)常用知识点小结

    原文地址:→看过来 正则表达式用到的地方很多,但是每次很久不用就全忘光了,每次都要重新看一遍文档,为了节省时间,把它的一些基本要点画总结在一张图片中,这样方便以后查看. PS:细节的东西还是需要看详细 ...

  10. SQLServer 延迟事务持久性

    SQL Server 2014新功能 -- 延迟事务持久性(Delayed Transaction Durability) SQL Server事务提交默认是完全持久性的(Full Durable), ...