Unity3D 游戏引擎之FBX模型载入与人物行走动画播放

移动开发 iOS 游戏开发
3D 世界中自定义模型的使用恐怕是重中之重,因为系统自身提供的模型肯定是无法满足GD对游戏的策划,所以为了让游戏更加绚丽,我们须要调用美术制作的精品模型与动画,本章将带领大家学习Unity3D中模型的载入与动画的播放。

由于作者手头上没有现成的模型,所以我将在Unity3D 官网中下载官方提供的游戏DEMO 中的模型来使用。另外官方提供了很多Unity3D 游戏DEMO,与详细的文档。可以帮助我们学习Unity.有兴趣的盆友可以去看看哈。

下载页面:http://unity3d.com/support/resources/  

本章博文的目的是利用上一章介绍的游戏摇杆来控制人物模型的移动,与行走动画的播放。

 

如上图所示Create中的文件夹male中存放着模型动画与贴图等,这个应该是美术提供给我们的。然后将整个male用鼠标拖动到左侧3D世界中,通过移动,旋转,缩放将人物模型放置在一个理想的位置。右侧红框内设置模型动画的属性。

Animation  

        idle1  该模型默认动画名称为idle1

Animations 

        size   该模型动画的数量

        Element 该模型的动画名称

Play Automatically 是否自动播放

Animation Physics 是否设置该模型物理碰撞

Animation Only if Visable 是否设置该模型仅自己显示

给该模型绑定一个脚本Controller.cs 用来接收摇杆返回的信息更新模型动画。

Controller.cs

[代码]c#/cpp/oc代码:

001 using UnityEngine; 
002 using System.Collections; 
003    
004    
005    
006 public class Controller : MonoBehaviour { 
007        
008     //人物的行走方向状态 
009     public const int HERO_UP= 0; 
010     public const int HERO_RIGHT= 1; 
011     public const int HERO_DOWN= 2; 
012     public const int HERO_LEFT= 3; 
013        
014     //人物当前行走方向状态 
015     public int state = 0; 
016        
017     //备份上一次人物当前行走方向状态 
018     //这里暂时没有用到 
019     public int backState = 0; 
020        
021     //游戏摇杆对象 
022     public MPJoystick moveJoystick;   
023        
024     //这个方法只调用一次,在Start方法之前调用 
025     public void Awake() { 
026            
027     } 
028        
029     //这个方法只调用一次,在Awake方法之后调用 
030     void Start () { 
031         state = HERO_DOWN; 
032     } 
033        
034        
035     void Update () { 
036        
037     //获取摇杆控制的方向数据 上一章有详细介绍   
038     float touchKey_x =  moveJoystick.position.x;   
039     float touchKey_y =  moveJoystick.position.y;   
040            
041          
042         
043     if(touchKey_x == -1){   
044        setHeroState(HERO_LEFT); 
045              
046     }else if(touchKey_x == 1){   
047        setHeroState(HERO_RIGHT); 
048              
049     }   
050         
051     if(touchKey_y == -1){   
052         setHeroState(HERO_DOWN); 
053     
054     }else if(touchKey_y == 1){   
055         setHeroState(HERO_UP);          
056     }   
057        
058     if(touchKey_x == 0 && touchKey_y ==0){ 
059         //松开摇杆后播放默认动画, 
060         //不穿参数为播放默认动画。 
061         animation.Play(); 
062     } 
063        
064            
065     } 
066        
067     public void setHeroState(int newState) 
068     { 
069            
070         //根据当前人物方向 与上一次备份方向计算出模型旋转的角度 
071         int rotateValue = (newState - state) * 90; 
072         Vector3 transformValue = new Vector3(); 
073            
074         //播放行走动画 
075         animation.Play("walk"); 
076            
077         //模型移动的位移的数值 
078         switch(newState){ 
079             case HERO_UP: 
080                 transformValue = Vector3.forward * Time.deltaTime; 
081             break;   
082             case HERO_DOWN: 
083                 transformValue = -Vector3.forward * Time.deltaTime; 
084             break;   
085             case HERO_LEFT: 
086                 transformValue = Vector3.left * Time.deltaTime; 
087                    
088             break;   
089             case HERO_RIGHT: 
090                 transformValue = -Vector3.left * Time.deltaTime; 
091             break;               
092         } 
093            
094            
095         //模型旋转 
096         transform.Rotate(Vector3.up, rotateValue); 
097            
098         //模型移动 
099         transform.Translate(transformValue, Space.World); 
100            
101         backState = state; 
102         state = newState; 
103            
104     } 
105        
106 }

上一章介绍了javaScript脚本使用游戏摇杆的方法,本章MOMO告诉大家使用C#脚本来使用游戏摇杆,上面我用 Controller.cs  C#脚本来接收系统提供的Joystick.js是肯定无法使用的,须要修改成.cs文件,我在国外的一个网站上看到了一个老外帮我们已经修改了,那么我将他修改后的代码贴出来方便大家学习,有兴趣的朋友可以研究研究。 

MPJoystick.cs

 [代码]c#/cpp/oc代码:

001 using UnityEngine;  
002    
003 /**
004   
005  * File: MPJoystick.cs
006   
007  * Author: Chris Danielson of (monkeyprism.com)
008   
009  * 
010   
011 // USED TO BE: Joystick.js taken from Penelope iPhone Tutorial
012   
013 //
014   
015 // Joystick creates a movable joystick (via GUITexture) that 
016   
017 // handles touch input, taps, and phases. Dead zones can control
018   
019 // where the joystick input gets picked up and can be normalized.
020   
021 //
022   
023 // Optionally, you can enable the touchPad property from the editor
024   
025 // to treat this Joystick as a TouchPad. A TouchPad allows the finger
026   
027 // to touch down at any point and it tracks the movement relatively 
028   
029 // without moving the graphic
030   
031 */ 
032 [RequireComponent(typeof(GUITexture))] 
033    
034 public class MPJoystick : MonoBehaviour 
035    
036
037    
038 class Boundary { 
039    
040 public Vector2 min = Vector2.zero; 
041    
042 public Vector2 max = Vector2.zero; 
043    
044
045 private static MPJoystick[] joysticks;   // A static collection of all joysticks 
046    
047 private static bool enumeratedJoysticks = false; 
048    
049 private static float tapTimeDelta = 0.3f;    // Time allowed between taps 
050 public bool touchPad; 
051    
052 public Vector2 position = Vector2.zero; 
053    
054 public Rect touchZone; 
055    
056 public Vector2 deadZone = Vector2.zero;  // Control when position is output 
057    
058 public bool normalize = false; // Normalize output after the dead-zone? 
059    
060 public int tapCount;      
061    
062 private int lastFingerId = -1;   // Finger last used for this joystick 
063    
064 private float tapTimeWindow;     // How much time there is left for a tap to occur 
065    
066 private Vector2 fingerDownPos; 
067    
068 //private float fingerDownTime; 
069    
070 //private float firstDeltaTime = 0.5f; 
071 private GUITexture gui; 
072    
073 private Rect defaultRect;    // Default position / extents of the joystick graphic 
074    
075 private Boundary guiBoundary = new Boundary();   // Boundary for joystick graphic 
076    
077 private Vector2 guiTouchOffset;  // Offset to apply to touch input 
078    
079 private Vector2 guiCenter;   // Center of joystick 
080 void Start() { 
081    
082 gui = (GUITexture)GetComponent(typeof(GUITexture)); 
083 defaultRect = gui.pixelInset; 
084    
085 defaultRect.x += transform.position.x * Screen.width;// + gui.pixelInset.x; // -  Screen.width * 0.5; 
086    
087         defaultRect.y += transform.position.y * Screen.height;// - Screen.height * 0.5; 
088 transform.position = Vector3.zero; 
089 if (touchPad) { 
090    
091 // If a texture has been assigned, then use the rect ferom the gui as our touchZone 
092    
093 if ( gui.texture ) 
094    
095 touchZone = defaultRect; 
096    
097 } else { 
098    
099 guiTouchOffset.x = defaultRect.width * 0.5f; 
100    
101 guiTouchOffset.y = defaultRect.height * 0.5f; 
102 // Cache the center of the GUI, since it doesn't change 
103    
104 guiCenter.x = defaultRect.x + guiTouchOffset.x; 
105    
106 guiCenter.y = defaultRect.y + guiTouchOffset.y; 
107 // Let's build the GUI boundary, so we can clamp joystick movement 
108    
109 guiBoundary.min.x = defaultRect.x - guiTouchOffset.x; 
110    
111 guiBoundary.max.x = defaultRect.x + guiTouchOffset.x; 
112    
113 guiBoundary.min.y = defaultRect.y - guiTouchOffset.y; 
114    
115 guiBoundary.max.y = defaultRect.y + guiTouchOffset.y; 
116    
117
118    
119
120 public Vector2 getGUICenter() { 
121    
122 return guiCenter; 
123    
124
125 void Disable() { 
126    
127 gameObject.active = false; 
128    
129 //enumeratedJoysticks = false; 
130    
131
132 private void ResetJoystick() { 
133    
134 gui.pixelInset = defaultRect; 
135    
136 lastFingerId = -1; 
137    
138 position = Vector2.zero; 
139    
140 fingerDownPos = Vector2.zero; 
141    
142
143 private bool IsFingerDown() { 
144    
145 return (lastFingerId != -1); 
146    
147
148 public void LatchedFinger(int fingerId) { 
149    
150 // If another joystick has latched this finger, then we must release it 
151    
152 if ( lastFingerId == fingerId ) 
153    
154 ResetJoystick(); 
155    
156
157 void Update() { 
158    
159 if (!enumeratedJoysticks) { 
160    
161 // Collect all joysticks in the game, so we can relay finger latching messages 
162    
163 joysticks = (MPJoystick[])FindObjectsOfType(typeof(MPJoystick)); 
164    
165 enumeratedJoysticks = true; 
166    
167
168 int count = Input.touchCount; 
169 if ( tapTimeWindow > 0 ) 
170    
171 tapTimeWindow -= Time.deltaTime; 
172    
173 else 
174    
175 tapCount = 0; 
176 if ( count == 0 ) 
177    
178 ResetJoystick(); 
179    
180 else 
181    
182
183    
184 for(int i = 0; i < count; i++) { 
185    
186 Touch touch = Input.GetTouch(i); 
187    
188 Vector2 guiTouchPos = touch.position - guiTouchOffset; 
189 bool shouldLatchFinger = false; 
190    
191 if (touchPad) { 
192    
193 if (touchZone.Contains(touch.position)) 
194    
195 shouldLatchFinger = true; 
196    
197
198    
199 else if (gui.HitTest(touch.position)) { 
200    
201 shouldLatchFinger = true; 
202    
203
204 // Latch the finger if this is a new touch 
205    
206 if (shouldLatchFinger && (lastFingerId == -1 || lastFingerId != touch.fingerId )) { 
207 if (touchPad) { 
208    
209 //gui.color.a = 0.15; 
210    
211 lastFingerId = touch.fingerId; 
212    
213 //fingerDownPos = touch.position; 
214    
215 //fingerDownTime = Time.time; 
216    
217
218 lastFingerId = touch.fingerId; 
219    
220     
221    
222 // Accumulate taps if it is within the time window 
223    
224 if ( tapTimeWindow > 0 ) 
225    
226 tapCount++; 
227    
228 else { 
229    
230 tapCount = 1; 
231    
232 tapTimeWindow = tapTimeDelta; 
233    
234
235 // Tell other joysticks we've latched this finger 
236    
237 //for (  j : Joystick in joysticks ) 
238    
239 foreach (MPJoystick j in joysticks) { 
240    
241 if (j != this)  
242    
243 j.LatchedFinger( touch.fingerId ); 
244    
245
246    
247 }    
248 if ( lastFingerId == touch.fingerId ) { 
249    
250 // Override the tap count with what the iPhone SDK reports if it is greater 
251    
252 // This is a workaround, since the iPhone SDK does not currently track taps 
253    
254 // for multiple touches 
255    
256 if ( touch.tapCount > tapCount ) 
257    
258 tapCount = touch.tapCount; 
259 if ( touchPad ) { 
260    
261 // For a touchpad, let's just set the position directly based on distance from initial touchdown 
262    
263 position.x = Mathf.Clamp( ( touch.position.x - fingerDownPos.x ) / ( touchZone.width / 2 ), -1, 1 ); 
264    
265 position.y = Mathf.Clamp( ( touch.position.y - fingerDownPos.y ) / ( touchZone.height / 2 ), -1, 1 ); 
266    
267 } else { 
268    
269 // Change the location of the joystick graphic to match where the touch is 
270    
271 Rect r = gui.pixelInset; 
272    
273 r.x =  Mathf.Clamp( guiTouchPos.x, guiBoundary.min.x, guiBoundary.max.x ); 
274    
275 r.y =  Mathf.Clamp( guiTouchPos.y, guiBoundary.min.y, guiBoundary.max.y ); 
276    
277 gui.pixelInset = r; 
278    
279
280 if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled) 
281    
282 ResetJoystick(); 
283    
284
285    
286
287    
288
289 if (!touchPad) { 
290    
291 // Get a value between -1 and 1 based on the joystick graphic location 
292    
293 position.x = ( gui.pixelInset.x + guiTouchOffset.x - guiCenter.x ) / guiTouchOffset.x; 
294    
295 position.y = ( gui.pixelInset.y + guiTouchOffset.y - guiCenter.y ) / guiTouchOffset.y; 
296    
297
298 // Adjust for dead zone 
299    
300 var absoluteX = Mathf.Abs( position.x ); 
301    
302 var absoluteY = Mathf.Abs( position.y ); 
303    
304     
305    
306 if (absoluteX < deadZone.x) { 
307    
308 // Report the joystick as being at the center if it is within the dead zone 
309    
310 position.x = 0; 
311    
312
313    
314 else if (normalize) { 
315    
316 // Rescale the output after taking the dead zone into account 
317    
318 position.x = Mathf.Sign( position.x ) * ( absoluteX - deadZone.x ) / ( 1 - deadZone.x ); 
319    
320
321 if (absoluteY < deadZone.y) { 
322    
323 // Report the joystick as being at the center if it is within the dead zone 
324    
325 position.y = 0; 
326    
327
328    
329 else if (normalize) { 
330    
331 // Rescale the output after taking the dead zone into account 
332    
333 position.y = Mathf.Sign( position.y ) * ( absoluteY - deadZone.y ) / ( 1 - deadZone.y ); 
334    
335
336
337 }

导出 build and run  看看在iPhone 上的效果,通过触摸游戏摇杆可以控制人物的上,下,左,右 ,左上,右上,左下,右下 8个方向的移动啦,不错吧,哇咔咔~~

 

责任编辑:冰凝儿
相关推荐

2012-12-24 09:04:04

iOSUnity3D

2012-12-24 08:52:44

iOSUnity3D

2012-12-24 08:46:50

iOSUnity3D

2012-12-24 08:51:23

iOSUnity3D

2012-12-24 09:01:41

iOSUnity3D

2012-12-24 08:57:35

iOSUnity3D

2012-12-24 08:48:25

iOSUnity3D

2012-12-24 09:17:12

iOSUnity3D

2012-12-24 08:40:12

2012-12-24 08:50:21

iOSUnity3D

2013-04-25 10:03:07

unity3D手机游戏引擎

2012-12-24 08:45:19

iOSUnity3D

2012-12-24 08:56:15

iOSUnity3D

2012-12-24 09:07:09

iOSUnity3D

2012-12-24 09:11:58

iOSUnity3D

2012-12-24 08:59:13

iOSUnity3D

2013-04-25 09:56:24

unity3D手机游戏引擎

2012-12-24 09:02:48

iOSUnity3D

2012-12-24 08:54:47

iOSUnity3D

2012-12-24 09:06:14

iOSUnity3D
点赞
收藏

51CTO技术栈公众号