unity3D:游戏分解之曲线
一提到曲线,很多新手就头疼了,包括我。查了很多资料,终于有个大概的了解。想深入了解曲线原理的,推荐一个链接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:游戏分解之曲线的更多相关文章
- Unity3d游戏中自定义贝塞尔曲线编辑器[转]
关于贝塞尔曲线曲线我们再前面的文章提到过<Unity 教程之-在Unity3d中使用贝塞尔曲线>,那么本篇文章我们来深入学习下,并自定义实现贝塞尔曲线编辑器,贝塞尔曲线是最基本的曲线,一般 ...
- Unity3D游戏开发初探—2.初步了解3D模型基础
一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被. ...
- Unity3D游戏在iOS上因为trampolines闪退的原因与解决办法
http://7dot9.com/?p=444 http://whydoidoit.com/2012/08/20/unity-serializer-mono-and-trampolines/ 确定具体 ...
- unity3d 游戏插件 溶解特效插件 - Dissolve Shader
unity3d 游戏插件 溶解特效插件 - Dissolve Shader 链接: https://pan.baidu.com/s/1hr7w39U 密码: 3ed2
- 将Unity3D游戏移植到Android平台上
将Unity3D游戏移植到Android平台是一件很容易的事情,只需要在File->Build Settings中选择Android平台,然后点击Switch Platform并Build出ap ...
- 从一点儿不会开始——Unity3D游戏开发学习(一)
一些废话 我是一个windows phone.windows 8的忠实粉丝,也是一个开发者,开发数个windows phone应用和两个windows 8应用.对开发游戏一直抱有强烈兴趣和愿望,但奈何 ...
- unity3d游戏无法部署到windows phone8手机上的解决方法
今天搞了个unity3d游戏,准备部署到自己的lumia 920上,数据线连接正常,操作正常,但是“build”以后,始终无法部署到手机上,也没有在选择的目录下生产任何相关文件.(你的系统必须是win ...
- Unity3D游戏UI开发经验谈
原地址:http://news.9ria.com/2013/0629/27679.html 在Unity专场上,108km创始人梁伟国发表了<Unity3D游戏UI开发经验谈>主题演讲.他 ...
- Unity3D游戏开发之连续滚动背景
Unity3D游戏开发之连续滚动背景 原文 http://blog.csdn.net/qinyuanpei/article/details/22983421 在诸如天天跑酷等2D游戏中,因为游戏须要 ...
随机推荐
- 关于AysncController的一次测试(url重写后静态页文件内容的读取是否需要使用异步?)
因为做网站的静态页缓存,所以做了这个测试 MVC项目 准备了4个Action,分两组,一组是读取本地磁盘的一个html页面文件,一组是延时2秒 public class TestController ...
- 火车站点城市查询(appserv 服务器练习)
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- ST-LINK调试完成
今天真是一波三折啊. 买回来的st-link刚开始不会用,各种百度,还好有两个很好的教程.连接发在下面吧. http://blog.csdn.net/TXF1984/article/details/4 ...
- hadoop高可靠性HA集群
概述 简单hdfs高可用架构图 在hadoop2.x中通常由两个NameNode组成,一个处于active状态,另一个处于standby状态.Active NameNode对外提供服务,而Standb ...
- Ruby中有意思的块
块:是在调用方法时,能与参数一起传递的多个处理的集合 简单点说,跟在方法执行后面的do |变量| end就是一个块,这个块会被传入方法中去执行! 这个非常厉害,非常有意思! 在ruby中,如果需要便利 ...
- Java Web实现IOC控制反转之依赖注入
控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心. 控制反转一般分为两种类型,依赖注入 ...
- BZOJ 1266: [AHOI2006]上学路线route
题目描述 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:"很 ...
- linux 内核的futex pi-support,即pi-futex使用rt_mutex委托
futex的pi-support,也就是为futex添加pi算法解决优先级逆转的能力,使用pi-support的futex又称为pi-futex.在linux内核的同步机制中,有一个pi算法的成例,就 ...
- nginx 高可用
1 nginx负载均衡高可用 1.1 什么是负载均衡高可用 nginx作为负载均衡器,所有请求都到了nginx,可见nginx处于非常重点的位置,如果nginx服务器宕机后端web服务将无法提供服务, ...
- 最大流算法之EK(最短路径增广算法)
这是网络流最基础的部分--求出源点到汇点的最大流(Max-Flow). 最大流的算法有比较多,本次介绍的是其中复杂度较高,但是比较好写的EK算法.(不涉及分层,纯粹靠BFS找汇点及回溯找最小流量得到最 ...