NGUI研究院之在Unity中使用贝塞尔曲线(六)
来源:互联网 发布:sql重复列只显示一条 编辑:程序博客网 时间:2024/06/06 02:29
原创文章如需转载请注明:转载自雨松MOMO程序研究院本文链接地址:NGUI研究院之在Unity中使用贝塞尔曲线(六)
鼎鼎大名的贝塞尔曲线相信大家都耳熟能详。这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦。贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是起点,一个是终点。在这条曲线之上还会有两个可以任意移动的点来控制贝塞尔曲线的角度。如下图所示,点1 和点4 就是起点和终点,点2 和点3 就是控制曲线角度的两个动态点。
如下图所示。使用拖动条来让曲线发生旋转,大家会看的更加清晰。目前我们看到的被塞尔曲线是在平面中完成的,其实贝塞尔曲线是完全支持3D中完成,这里是为了让大家看的更加清楚MOMO将忽略Z曲线的Z轴。UnityAPI文档中有贝塞尔曲线的方法,可是只支持编辑器中使用,也就是说无法在程序中使用。那么本篇文章我们利用贝塞尔曲线的数学原理以及LineRenderer组件来完成在Unity中使用贝塞尔曲线。
创建一个U3D的工程,创建一个新游戏对象,绑定LineRenderer组件。
Bezier.cs 这里是贝塞尔曲线的公式C#版本
001
using
UnityEngine;
002
003
[System.Serializable]
004
005
public
class
Bezier : System.Object
006
007
{
008
009
public
Vector3 p0;
010
011
public
Vector3 p1;
012
013
public
Vector3 p2;
014
015
public
Vector3 p3;
016
017
public
float
ti = 0f;
018
019
private
Vector3 b0 = Vector3.zero;
020
021
private
Vector3 b1 = Vector3.zero;
022
023
private
Vector3 b2 = Vector3.zero;
024
025
private
Vector3 b3 = Vector3.zero;
026
027
private
float
Ax;
028
029
private
float
Ay;
030
031
private
float
Az;
032
033
private
float
Bx;
034
035
private
float
By;
036
037
private
float
Bz;
038
039
private
float
Cx;
040
041
private
float
Cy;
042
043
private
float
Cz;
044
045
// Init function v0 = 1st point, v1 = handle of the 1st point , v2 = handle of the 2nd point, v3 = 2nd point
046
047
// handle1 = v0 + v1
048
049
// handle2 = v3 + v2
050
051
public
Bezier( Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3 )
052
053
{
054
055
this
.p0 = v0;
056
057
this
.p1 = v1;
058
059
this
.p2 = v2;
060
061
this
.p3 = v3;
062
063
}
064
065
// 0.0 >= t <= 1.0
066
067
public
Vector3 GetPointAtTime(
float
t )
068
069
{
070
071
this
.CheckConstant();
072
073
float
t2 = t * t;
074
075
float
t3 = t * t * t;
076
077
float
x =
this
.Ax * t3 +
this
.Bx * t2 +
this
.Cx * t + p0.x;
078
079
float
y =
this
.Ay * t3 +
this
.By * t2 +
this
.Cy * t + p0.y;
080
081
float
z =
this
.Az * t3 +
this
.Bz * t2 +
this
.Cz * t + p0.z;
082
083
return
new
Vector3( x, y, z );
084
085
}
086
087
private
void
SetConstant()
088
089
{
090
091
this
.Cx = 3f * ( (
this
.p0.x +
this
.p1.x ) -
this
.p0.x );
092
093
this
.Bx = 3f * ( (
this
.p3.x +
this
.p2.x ) - (
this
.p0.x +
this
.p1.x ) ) -
this
.Cx;
094
095
this
.Ax =
this
.p3.x -
this
.p0.x -
this
.Cx -
this
.Bx;
096
097
this
.Cy = 3f * ( (
this
.p0.y +
this
.p1.y ) -
this
.p0.y );
098
099
this
.By = 3f * ( (
this
.p3.y +
this
.p2.y ) - (
this
.p0.y +
this
.p1.y ) ) -
this
.Cy;
100
101
this
.Ay =
this
.p3.y -
this
.p0.y -
this
.Cy -
this
.By;
102
103
this
.Cz = 3f * ( (
this
.p0.z +
this
.p1.z ) -
this
.p0.z );
104
105
this
.Bz = 3f * ( (
this
.p3.z +
this
.p2.z ) - (
this
.p0.z +
this
.p1.z ) ) -
this
.Cz;
106
107
this
.Az =
this
.p3.z -
this
.p0.z -
this
.Cz -
this
.Bz;
108
109
}
110
111
// Check if p0, p1, p2 or p3 have changed
112
113
private
void
CheckConstant()
114
115
{
116
117
if
(
this
.p0 !=
this
.b0 ||
this
.p1 !=
this
.b1 ||
this
.p2 !=
this
.b2 ||
this
.p3 !=
this
.b3 )
118
119
{
120
121
this
.SetConstant();
122
123
this
.b0 =
this
.p0;
124
125
this
.b1 =
this
.p1;
126
127
this
.b2 =
this
.p2;
128
129
this
.b3 =
this
.p3;
130
131
}
132
133
}
134
135
}
MyBezier.cs 把它直接挂在摄像机上 ,控制拖动条来控制贝塞尔曲线、
01
using
UnityEngine;
02
03
public
class
MyBezier : MonoBehaviour
04
05
{
06
07
//贝塞尔曲线算法类
08
public
Bezier myBezier;
09
10
//曲线的对象
11
public
GameObject Yellowline;
12
13
//曲线对象的曲线组件
14
private
LineRenderer YellowlineRenderer;
15
16
//拖动条用来控制贝塞尔曲线的两个点
17
public
float
hSliderValue0;
18
public
float
hSliderValue1;
19
20
void
Start()
21
{
22
//得到曲线组件
23
YellowlineRenderer = Yellowline.GetComponent<LineRenderer>();
24
//为了让曲线更加美观,设置曲线由100个点来组成
25
YellowlineRenderer.SetVertexCount(100);
26
}
27
28
void
OnGUI()
29
{
30
//拖动条得出 -5.0 - 5.0之间的一个数值
31
hSliderValue0 = GUI.HorizontalSlider(
new
Rect(25, 25, 100, 30), hSliderValue0, -5.0F, 5.0F);
32
hSliderValue1 = GUI.HorizontalSlider(
new
Rect(25, 70, 100, 30), hSliderValue1, -5.0F, 5.0F);
33
}
34
35
void
Update()
36
{
37
//在这里来计算贝塞尔曲线
38
//四个参数 表示当前贝塞尔曲线上的4个点 第一个点和第四个点
39
//我们是不需要移动的,中间的两个点是由拖动条来控制的。
40
myBezier =
new
Bezier(
new
Vector3( -5f, 0f, 0f ),
new
Vector3( hSliderValue1, hSliderValue0 , 0f ),
new
Vector3( hSliderValue1, hSliderValue0, 0f ),
new
Vector3( 5f, 0f, 0f ) );
41
42
//循环100遍来绘制贝塞尔曲线每个线段
43
for
(
int
i =1; i <= 100; i++)
44
{
45
//参数的取值范围 0 - 1 返回曲线没一点的位置
46
//为了精确这里使用i * 0.01 得到当前点的坐标
47
Vector3 vec = myBezier.GetPointAtTime( (
float
)(i *0.01) );
48
//把每条线段绘制出来 完成白塞尔曲线的绘制
49
YellowlineRenderer.SetPosition(i -1,vec);
50
}
51
52
}
53
54
}
OK 这里贝塞尔曲线的原理就已经完毕。下面我们学习在NGUI中如何使用贝塞尔曲线。刚刚我们说过贝塞尔曲线是由2个固定点 加两个动态点来完成的,其实我们在开发中往往只需要3个点。1 起点 2 中间点 3 结束点 拖动这三个点都可以重新计算曲线的轨迹这样才比较完美。如下图所示,这三个点都是可以任意拖动的,拖动结束后,黑色的线为用户拖拽点连接的直角线段,我们根据这三个点组成的直角线段计算它们之间的贝塞尔曲线,也就是图中黄色的线段。
简单的进行拖拽一下,是不是感觉贝塞尔曲线很酷炫呢?哇咔咔。
我们来看看代码实现的部分,其实原理和上面完全一样。
BallMove.cs绑定在这三个可以拖拽的点上,让拖动小球后小球可跟随手指移动。
01
using
UnityEngine;
02
using
System.Collections;
03
04
public
class
BallMove : MonoBehaviour
05
{
06
07
void
OnDrag (Vector2 delta)
08
{
09
10
float
movex = transform.localPosition.x + (delta.x / 3);
11
float
movey = transform.localPosition.y + (delta.y / 3);
12
//避免越界操作,这里可以进行一些判断
13
transform.localPosition =
new
Vector3(movex,movey ,transform.localPosition.z);
14
}
15
16
}
如此一来触摸小球后,小球将跟随用户手指移动。下面我们将监听用户触摸小球后的坐标来计算它们三点之间的贝塞尔曲线。
BallInit.cs挂在摄像机上
01
using
UnityEngine;
02
using
System.Collections;
03
04
public
class
BallInit : MonoBehaviour {
05
06
//黑色直角线段
07
LineRenderer lineRenderer0;
08
LineRenderer lineRenderer1;
09
//贝塞尔曲线
10
LineRenderer BezierRenderer;
11
12
//三个小球触摸对象
13
public
GameObject mark0;
14
public
GameObject mark1;
15
public
GameObject mark2;
16
17
//算法公式类
18
private
Bezier myBezier;
19
20
void
Start ()
21
{
22
//分别得到黑色直角线段 与黄色贝塞尔曲线的 线段组件
23
lineRenderer0 = GameObject.Find(
"line0"
).GetComponent<LineRenderer>();
24
lineRenderer1 = GameObject.Find(
"line1"
).GetComponent<LineRenderer>();
25
BezierRenderer = GameObject.Find(
"Bezier"
).GetComponent<LineRenderer>();
26
//黑色直角是有两个线段组成
27
lineRenderer0.SetVertexCount(2);
28
lineRenderer1.SetVertexCount(2);
29
//为了让贝塞尔曲线细致一些 设置它有100个点组成
30
BezierRenderer.SetVertexCount(100);
31
32
}
33
34
void
Update ()
35
{
36
37
//mark0 表示中间的小球
38
//mark1 表示右边的小球
39
//mark2 表示左边的小球
40
41
//中间的标志点分别减去左右两边的标志点,计算出曲线的X Y 的点
42
float
y = (mark0.transform.position.y - mark2.transform.position.y) ;
43
float
x = (mark0.transform.position.x - mark2.transform.position.x) ;
44
45
//因为我们是通过3个点来确定贝塞尔曲线, 所以参数3 设置为0 即可。
46
//这样参数1 表示起点 参数2表示中间点 参数3 忽略 参数4 表示结束点
47
myBezier =
new
Bezier( mark2.transform.position,
new
Vector3(x,y,0f),
new
Vector3(0f,0f,0f), mark1.transform.position );
48
49
//绘制贝塞尔曲线
50
for
(
int
i =1; i <= 100; i++)
51
{
52
Vector3 vec = myBezier.GetPointAtTime( (
float
)(i * 0.01) );
53
BezierRenderer.SetPosition(i -1,vec);
54
}
55
56
//绘制直角黑色标志线段
57
lineRenderer0.SetPosition(0,mark0.transform.position);
58
lineRenderer0.SetPosition(1,mark2.transform.position);
59
lineRenderer1.SetPosition(0,mark0.transform.position);
60
lineRenderer1.SetPosition(1,mark1.transform.position);
61
}
62
}
NGUI部分的源码就不放出来,MOMO将第一个例子的源码放出来,最近生活与工作都有点郁闷,哎~~~ 日子是熬出来,程序也是写出来的,走一步看一步,加油!雨松MOMO祝大家学习愉快,哇咔咔。
下载地址:http://vdisk.weibo.com/s/aceMi
参考文章:http://forum.unity3d.com/threads/5082-Bezier-Curve
- NGUI研究院之在Unity中使用贝塞尔曲线(六)
- NGUI研究之在Unity中使用贝塞尔曲线
- 在Unity中使用贝塞尔曲线
- Unity中使用贝塞尔曲线
- unity中使用贝塞尔曲线
- Unity3D研究院之在Unity中打开第三方数据库配合Android开发(三十二)
- Unity3D研究院之在Unity中打开第三方数据库配合Android开发(三十二)
- Unity3D研究院之在Unity中打开第三方数据库配合Android开发(转)
- Unity游戏中使用贝塞尔曲线
- unity使用贝塞尔曲线
- Unity使用贝塞尔曲线
- (转载)NGUI研究院之为什么Scene视图中不显示Polygon Collider2D(十七)
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- NGUI研究院之开发项目的一些使用心得比较细节(五)
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- hdu4454 Stealing a Cake
- IOException while loading persisted sessions: java.io.EOFException
- 量体裁衣:HTML5并非大势所趋
- Linq to sql 添加,修改,删除,事务操作
- HandlerThread用法小结
- NGUI研究院之在Unity中使用贝塞尔曲线(六)
- java对象的创建过程
- cocos2d-x CCDirector在Windows平台,Android平台,ios平台分析和用途-沈大海cocos2d-x教程10
- Win8 ListView数据控件
- Android 弹出菜单 ---- PathButton
- 微软全球最具价值技术专家,CSDN著名技术专家,资深软件构架师YinCheng的博客
- Dynamics CRM 2011,Office 2013,Windows 8,IE 10 的兼容问题
- linux 与 单片机 串口通信
- java.lang.OutOfMemoryError: Java heap space