码迷,mamicode.com
首页 > 编程语言 > 详细

unity编程——小玩具

时间:2015-05-30 07:03:26      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:

今天做了一个萤火虫飞舞效果,这个问题类似于一道算法题:一个点想移动到平面上任意一点,但是自身有一个旋转角度限制,每一次旋转时,最大旋转角度是 maxRotateAngle,思维延时(即两次连续执行自身指令的间隔)是 float gap。

大致思路是:

建立了四个指令,分别是:

Blink()—— 萤火虫屁股发光,是闪烁的......闪烁的...

Move()——(默认使用 Vector2 curSpeed 作为移动增量)

ComputeDir() —— 根据目标位置,计算当前运动方向,因为旋转角度限制无法一次直达。

Escape()—— 这个纯属自娱自乐了,哈哈,当鼠标接近萤火虫时,他就会“拼命地”逃离鼠标,我自己瞎搞的玩的。

 

技术分享

这里只加了一直萤火虫,可以加更多。

(美术实在太差,,,凑合看看热闹吧....)

*******************************************************

技术细节:

1.转向问题有点棘手,因为要考虑很多方面。其中之一就是坐标系问题我在这个脚本里面用了Graphics.DrawTexture()函数,这个底层函数的坐标原点和其他的不太一样,是左上角为原点的。

如果不熟悉,可以用 print() 多测试几次,我就是这么搞的。(>_<)。

(改了好几次,写了好多个版本。最终敲定了现在手上的版本。)

2.其二考虑的是效率问题了,转向,三角函数是少不了用的,其中我想到了的一种方法以萤火虫自身为原点,前进方向为Y轴建立坐标系,然后进行计算。这个法子很笨的,因为后期还要把目标点切出来转换到屏幕空间,反而繁琐了;也许是我能力不够,没找到优化方法吧。

我所采用的方法是,直接在屏幕空间来进行计算。因为有了统一他标准,少了很多转换,优化手段也多了起来。具体来说也很繁琐。

优化无止境啊... 大概思路还是那句老话:用更少的空间代价,换取更快的速度。

3.说一说Graphics绘图:用过了几次后,(发现这个有点类似于Java的绘图,JAVA绘图很简单,应该说实际上不止JAVA各个绘图API底层都是这样的语法。)

这个底层绘图不能随便用,因为深度测试绕过去了,绘制顺序必须再自己统一规定,不利于模块化;

它的使用有一些点必须注意:

 技术分享

必须是这样的格式,在发生repaint 时才能绘制。联系JAVA、win32的知识,就知道了repaint,这绝对是在最后一个绘制的,前面的深度测试,顶点变换什么的他都不干,直接插队到最后,就是这样一个霸道的站在世界的顶点的男银。

————————————————————————————————————————————————

最后一环,贴代码吧:

 自己写的也有很多不足,模块化不像模块化,函数之间的接替性不够,因为是我自己一个人玩玩,所以能用全局变量全部用的全局变量。还有很多,希望童鞋们不吝指教,多多与我交流,^_^

 

  1 using UnityEngine;
  2 using System.Collections;
  3 
  4 public class Star : MonoBehaviour {
  5 
  6     public Vector2 initPosPercent;
  7 
  8     public float maxComputeDestGap = 1.0f;
  9     public float curComputeDestGap = 0.0f;
 10     public float computeDirGap = 0.5f;
 11     public float curComputeDirTime = 0.0f;
 12     // 纹理
 13     public Texture2D starBgd;
 14     private Rect bgdRT = new Rect(0,0,0,0);
 15     float maxWidth, maxHeight, width, height;
 16 
 17     // 图片宽
 18     public float percentWidth = 0.1f;
 19 
 20     // 速度最大值
 21     public float maxSpeedAmount = 0.2f;
 22 
 23     // 当期速度值
 24     public float curSpeedAmount = 0.2f;
 25 
 26     // 放大种子
 27     public float scaleSeed = 0.0f;    // 初始扩大系数
 28     public float maxScale = 0.8f, minScale = 0.5f;
 29 
 30     // 最大旋转角度
 31     public float maxRotateAngle = 0.5f;    // 大约30度
 32     float curRotateAngle = 0.0f;
 33     // 当前速度
 34     private Vector2 curSpeed = new Vector2(0.0f,0.0f);
 35     // 当前缩放比
 36     private float curScale = 1.0f;
 37 
 38     private float destX = 0.0f, destY = 0.0f;
 39 
 40     // 常量
 41     private float halfPI;
 42     private float PI2;
 43 
 44     // 逃跑警戒距离
 45     public float escapeDist;
 46     public float escapeSpeedAmount;
 47 
 48     // Use this for initialization
 49     void Start () {
 50 
 51         Vector3 pos = new Vector3 (Screen.width * initPosPercent.x, Screen.height * initPosPercent.y, 0.0f);
 52         transform.position = pos;
 53 
 54         width = maxWidth = Screen.width * percentWidth;
 55         height = maxHeight = width;
 56 
 57         bgdRT = new Rect ( transform.position.x, transform.position.y, width*curScale, height*curScale );
 58 
 59 
 60         halfPI = Mathf.PI * 0.5f;
 61         PI2 = Mathf.PI * 2.0f;
 62     }
 63     
 64 
 65     // Update is called once per frame
 66     void Update () {
 67 
 68         if (curComputeDestGap < maxComputeDestGap )
 69             curComputeDestGap += Time.deltaTime;
 70         else
 71         {
 72             // 生成新目标
 73             destX = Random.Range (0, Screen.width);
 74             destY = Random.Range (0, Screen.height);
 75 
 76             curComputeDestGap = 0.0f;
 77         }
 78 
 79         if (curComputeDirTime < computeDirGap )
 80             curComputeDirTime += Time.deltaTime;
 81         else
 82         {
 83             // 生成新方向
 84             ComputeDir ( destX, destY);
 85             
 86             curComputeDirTime = 0.0f;
 87         }
 88 
 89 
 90         // 逃离
 91         Escape ();
 92 
 93         // 移动 star 
 94         Move ();
 95 
 96     }
 97 
 98 
 99     void OnGUI()
100     {
101         if( Event.current.type.Equals(EventType.Repaint) )
102         {
103             //    print ( x );
104             float x = transform.position.x - width * 0.5f;
105             float y = transform.position.y - height * 0.5f;
106             bgdRT = new Rect ( x, y, width, height );
107 
108 
109             GUI.DrawTexture ( bgdRT, starBgd );
110         }
111     }
112 
113     void Blink()
114     {
115         curScale = (maxScale - minScale)* 0.5f * Mathf.Sin (Time.time + scaleSeed) + maxScale;
116         
117         width = maxWidth * curScale;
118         height = width;
119     }
120 
121     void Escape()
122     {
123         Vector2 pos = new Vector2 ( transform.position.x, transform.position.y );
124         Vector2 mousePos = new Vector2 ( 0, 0 );
125         mousePos.x = Input.mousePosition.x;
126         mousePos.y = Screen.height - Input.mousePosition.y;
127 
128         float dist = Vector2.Distance ( mousePos, pos);
129 
130         if( dist <= escapeDist )
131         {
132             Vector2 dir = new Vector2( 0.0f, 0.0f );
133 
134             dir = pos - mousePos;
135 
136             dir.Normalize();
137             curSpeed = dir * escapeSpeedAmount;
138         }
139     }
140 
141 
142     void Move ()
143     {
144         float t = transform.position.x + curSpeed.x;
145 
146         // 防越界
147         if ( t < 0.0f || t > Screen.width )
148             curSpeed.x = -curSpeed.x;
149         t = transform.position.y + curSpeed.y;
150         if (t < 0.0f || t > Screen.height)
151             curSpeed.y = -curSpeed.y;
152         
153         
154         transform.Translate ( curSpeed.x * Time.deltaTime, curSpeed.y*Time.deltaTime, 0);
155     }
156 
157     void ComputeDir( float srcX, float srcY )
158     {
159         // 根据源位置计算目标位置,旋转角度有限所致
160         float m = srcX - transform.position.x;
161         float n = srcY - transform.position.y;
162 
163         // 在自身坐标系中的坐标
164         float angle = Mathf.Atan2 ( n, m );
165 
166         float dAngle = angle - curRotateAngle;
167 
168         // 转变成 pi < A - C < -PI
169         if (dAngle < -Mathf.PI) {
170             angle += PI2;
171         }
172         else if( dAngle > Mathf.PI )
173         {
174             angle -= PI2;
175         }
176 
177         dAngle = angle - curRotateAngle;
178 
179 
180         // 计算最终角度
181         if (dAngle > -maxRotateAngle && dAngle < maxRotateAngle)
182         {
183             // 一步即达的目标方向
184             curRotateAngle = angle;
185         }
186         else
187         {
188             if( dAngle < 0.0f )
189             {
190                 curRotateAngle -= maxRotateAngle;
191             }
192             else
193             {
194                 curRotateAngle += maxRotateAngle;
195             }
196 
197         }
198 
199         // 转换到 -PI 到 PI 空间
200         if (curRotateAngle < -Mathf.PI) {
201             curRotateAngle += PI2;
202         }
203         else if( curRotateAngle > Mathf.PI )
204         {
205             curRotateAngle -= PI2;
206         }
207 
208         // 计算最终速度
209         curSpeed.x = curSpeedAmount * Mathf.Cos ( curRotateAngle );
210         curSpeed.y = curSpeedAmount * Mathf.Sin ( curRotateAngle );
211 
212         return;
213     }
214     
215 }

 

 ***************

吐硼:

 C#真是够了,虐的我压灭压灭的,一说全是泪啊....

 

unity编程——小玩具

标签:

原文地址:http://www.cnblogs.com/SecretMan001/p/4539753.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!