unity3D:游戏分解之曲线

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

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

先看一下曲线的效果

在使用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) * u
54             + 2f * b
55         );
56     }

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

  1 using System;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4
  5 namespace Fish.Study.Curve
  6 {
  7     /// <summary>
  8     /// 曲线测试
  9     /// </summary>
 10     public class CurveTest : MonoBehaviour
 11     {
 12         //路点
 13         public GameObject[] GameObjectList;
 14         //各路点的坐标
 15         public List<Vector3> TransDataList = new List<Vector3>();
 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 * b
100             );
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 }
时间: 2024-08-13 10:46:49

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

Unity3D游戏开发从零单排(五) - 导入CS模型到Unity3D

游戏动画基础 Animation组件 Animation组件是对于老的动画系统来说的. 老的动画形同对应的动画就是clip,每个运动都是一段单独的动画,使用Play()或CrossFade(),直接播放动画 或淡入淡出播放动画. animation.Play("name"); animation.CrossFade("name"); 下面的是它的几个属性 Animation:默认的动画片段: Aniamtions:包含的动画片段: Play Automaticall

Unity3D游戏开发之详解 Animation类和Animator类

Unity3D游戏开发之详解 Animation类和Animator类 Animation类 animation组件用于播放动画.可以指定动画剪辑到动画组件并从脚本控制动画播放.在Unity的动画系统基于权重并且支持动画融合,叠加动画,动画混合,标签和完全控制动画播放的各个方面. 如果想播放一个简单的动画,可以使用Animation.Play:如果想在动画之间交叉淡入,可以使用Animation.CrossFade:如果想改变动画模式(循环,一次,乒乓),可以改变动画导入设置里面的动画帧的Wra

Unity3D游戏开发之设置动画(Animations)属性

Unity3D游戏开发之设置动画(Animations)属性 通过创建角色动画Avatar,在新的动画系统Mecanim中,Unity就设置了角色动画的骨架和蒙皮信息,从而就可以在Unity中实现角色动画了. 切换到动画(Animations)选项卡.选中导入动画(Import Animation)的选项.如果该文件中有动画数据,可以看到动画剪辑的列表(Clips). Tips: Rig选项卡中动画类型(Animation Type)如果选则的是旧版(Legacy),Animations中的属性

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

一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被.机械等等,比如一个大楼的3D模型图.3D模型也包括玩具和电脑模型领域. 互联网的形态一直以来都是2D模式的,但是随着3D技术的不断进步,在未来的时间里,将会有越来越多的互联网应用以3D的方式呈现给用户,包括网络视讯.电子阅读.网络游戏.虚拟社区.电子商务.远程教育等等.甚至对于旅游业,3D互联网也能

[Unity3D]Unity3D游戏开发之异步记载场景并实现进度条读取效果

大家好,我是秦元培.欢迎大家关注我的博客,我的博客地址是:blog.csdn.net/qinyuanpei.终于在各种无语的论文作业中解脱了,所以立即抓紧时间来这里更新博客.博主本来计划在Unity3D游戏开发之从<魂斗罗>游戏说起(上)--目标追踪这篇文章后再写一篇<Unity3D游戏开发之从<魂斗罗>游戏说起(下)>,只是眼下博主的项目进度有些缓慢,所以想等项目稳定下来以后再和大家分享. 作为大家等待博主更新博客的回报,我们今天来说一说Unity3D中的游戏场景异步

unity3d游戏开发经验之对于关卡类游戏的技巧

过关类游戏在单机类游戏中出现会比较多,但多以休闲为主,比如<Candy Crush>.<Angry Birds>.<P V Z>.<小鳄鱼顽皮爱洗澡>.<Tiny Thief>等经典休闲游戏,鉴于很多圈内人士预测2014年是手游爆发年,且重点在ARPG类型,似乎会冒出很多横版过关或者全3D的过关动作类游戏,我们就针对此类型的游戏进行分析. 首先,此类型的游戏需要关注的是每关卡的独立玩家数量,即玩家ID数量,目的是为了监测玩家主要集中在哪个阶段.比

[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(下)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 喜欢我的博客请记住我的名字:秦元培,我的博客地址是blog.csdn.net/qinyuanpei. 转载请注明出处,本文作者:

Unity3D游戏开发从零单排(六) - 人物运动及攻击连击

提要 今天要实现的是一个简单人物控制器.包括用w,a,s,d来控制人物上下左右跑动,鼠标左击发出连招,都是基于老的lagacy的动画.虽然unity3d自带有charactorcontroller,但是并不是很好用,所以人物控制相关的全部自己来实现.先上效果图: 场景搭建 首先下载这个package,里面包含了人物的动作还有地面的模型.将人物和地面都拖进场景中.这里的模型默认的动画模式是lagacy,不用修改.模型有点偏小,改变模型的scale值为10.最好不要改源文件的scale的scale

unity3D游戏开发实战原创视频讲座系列10之《保卫战:异形入侵》游戏开发第一季

讲解目录 <保卫战:异形入侵>游戏开发    1 第一讲   游戏演示和资源的介绍    1 第二讲  "异形"怪物的实现    1 第三讲  "异形"怪物生命值的体现    9 第四讲  "异形"怪物死后处理    12 第五讲  玩家的制作    15 第六讲  玩家的行走控制(键盘)    16 第七讲  武器的切换(鼠标)     16 第八讲  摄像头的变化(鼠标)    19 第九讲  子弹预制体和特效的制作    20