• Unity3D 游戏引擎之IOS自定义游戏摇杆与飞机平滑的移动


    http://blog.csdn.net/xys289187120/article/details/6941061

         移动开发游戏中使用到的触摸游戏摇杆在iPhone上是非常普遍的,毕竟是全触摸屏手机,今天MOMO 通过一个小例子和大家讨论Unity3D 中如何自定义一个漂亮的全触摸游戏摇杆。

     

           值得高兴的是,Unity3D 游戏引擎的标准资源中已经帮助我们封装了一个游戏摇杆脚本,所以实现部分的代码可以完全借助它的,具体调用需要我们自己来。

     

     Joystick.js是官方提供的脚本,具体代码如下,有兴趣的朋友可以仔细研究研究,MOMO就不多说啦。哇咔咔~

     

     

    [javascript] view plaincopy
    1. //////////////////////////////////////////////////////////////  
    2. // Joystick.js  
    3. // Penelope iPhone Tutorial  
    4. //  
    5. // Joystick creates a movable joystick (via GUITexture) that   
    6. // handles touch input, taps, and phases. Dead zones can control  
    7. // where the joystick input gets picked up and can be normalized.  
    8. //  
    9. // Optionally, you can enable the touchPad property from the editor  
    10. // to treat this Joystick as a TouchPad. A TouchPad allows the finger  
    11. // to touch down at any point and it tracks the movement relatively   
    12. // without moving the graphic  
    13. //////////////////////////////////////////////////////////////  
    14.   
    15. @script RequireComponent( GUITexture )  
    16.   
    17. // A simple class for bounding how far the GUITexture will move  
    18. class Boundary   
    19. {  
    20.     var min : Vector2 = Vector2.zero;  
    21.     var max : Vector2 = Vector2.zero;  
    22. }  
    23.   
    24. static private var joysticks : Joystick[];                  // A static collection of all joysticks  
    25. static private var enumeratedJoysticks : boolean = false;  
    26. static private var tapTimeDelta : float = 0.3;              // Time allowed between taps  
    27.   
    28. var touchPad : boolean;                                     // Is this a TouchPad?  
    29. var touchZone : Rect;  
    30. var deadZone : Vector2 = Vector2.zero;                      // Control when position is output  
    31. var normalize : boolean = false;                            // Normalize output after the dead-zone?  
    32. var position : Vector2;                                     // [-1, 1] in x,y  
    33. var tapCount : int;                                         // Current tap count  
    34.   
    35. private var lastFingerId = -1;                              // Finger last used for this joystick  
    36. private var tapTimeWindow : float;                          // How much time there is left for a tap to occur  
    37. private var fingerDownPos : Vector2;  
    38. private var fingerDownTime : float;  
    39. private var firstDeltaTime : float = 0.5;  
    40.   
    41. private var gui : GUITexture;                               // Joystick graphic  
    42. private var defaultRect : Rect;                             // Default position / extents of the joystick graphic  
    43. private var guiBoundary : Boundary = Boundary();            // Boundary for joystick graphic  
    44. private var guiTouchOffset : Vector2;                       // Offset to apply to touch input  
    45. private var guiCenter : Vector2;                            // Center of joystick  
    46.   
    47. function Start()  
    48. {  
    49.     // Cache this component at startup instead of looking up every frame      
    50.     gui = GetComponent( GUITexture );  
    51.       
    52.     // Store the default rect for the gui, so we can snap back to it  
    53.     defaultRect = gui.pixelInset;     
    54.       
    55.     defaultRect.x += transform.position.x * Screen.width;// + gui.pixelInset.x; // -  Screen.width * 0.5;  
    56.     defaultRect.y += transform.position.y * Screen.height;// - Screen.height * 0.5;  
    57.       
    58.     transform.position.x = 0.0;  
    59.     transform.position.y = 0.0;  
    60.           
    61.     if ( touchPad )  
    62.     {  
    63.         // If a texture has been assigned, then use the rect ferom the gui as our touchZone  
    64.         if ( gui.texture )  
    65.             touchZone = defaultRect;  
    66.     }  
    67.     else  
    68.     {                 
    69.         // This is an offset for touch input to match with the top left  
    70.         // corner of the GUI  
    71.         guiTouchOffset.x = defaultRect.width * 0.5;  
    72.         guiTouchOffset.y = defaultRect.height * 0.5;  
    73.           
    74.         // Cache the center of the GUI, since it doesn't change  
    75.         guiCenter.x = defaultRect.x + guiTouchOffset.x;  
    76.         guiCenter.y = defaultRect.y + guiTouchOffset.y;  
    77.           
    78.         // Let's build the GUI boundary, so we can clamp joystick movement  
    79.         guiBoundary.min.x = defaultRect.x - guiTouchOffset.x;  
    80.         guiBoundary.max.x = defaultRect.x + guiTouchOffset.x;  
    81.         guiBoundary.min.y = defaultRect.y - guiTouchOffset.y;  
    82.         guiBoundary.max.y = defaultRect.y + guiTouchOffset.y;  
    83.     }  
    84. }  
    85.   
    86. function Disable()  
    87. {  
    88.     gameObject.active = false;  
    89.     enumeratedJoysticks = false;  
    90. }  
    91.   
    92. function ResetJoystick()  
    93. {  
    94.     // Release the finger control and set the joystick back to the default position  
    95.     gui.pixelInset = defaultRect;  
    96.     lastFingerId = -1;  
    97.     position = Vector2.zero;  
    98.     fingerDownPosition = Vector2.zero;  
    99.       
    100.     if ( touchPad )  
    101.         gui.color.a = 0.025;      
    102. }  
    103.   
    104. function IsFingerDown() : boolean  
    105. {  
    106.     return (lastFingerId != -1);  
    107. }  
    108.       
    109. function LatchedFinger( fingerId : int )  
    110. {  
    111.     // If another joystick has latched this finger, then we must release it  
    112.     if ( lastFingerId == fingerId )  
    113.         ResetJoystick();  
    114. }  
    115.   
    116. function Update()  
    117. {     
    118.     if ( !enumeratedJoysticks )  
    119.     {  
    120.         // Collect all joysticks in the game, so we can relay finger latching messages  
    121.         joysticks = FindObjectsOfType( Joystick );  
    122.         enumeratedJoysticks = true;  
    123.     }     
    124.           
    125.     var count = Input.touchCount;  
    126.       
    127.     // Adjust the tap time window while it still available  
    128.     if ( tapTimeWindow > 0 )  
    129.         tapTimeWindow -= Time.deltaTime;  
    130.     else  
    131.         tapCount = 0;  
    132.       
    133.     if ( count == 0 )  
    134.         ResetJoystick();  
    135.     else  
    136.     {  
    137.         for(var i : int = 0;i < count; i++)  
    138.         {  
    139.             var touch : Touch = Input.GetTouch(i);            
    140.             var guiTouchPos : Vector2 = touch.position - guiTouchOffset;  
    141.       
    142.             var shouldLatchFinger = false;  
    143.             if ( touchPad )  
    144.             {                 
    145.                 if ( touchZone.Contains( touch.position ) )  
    146.                     shouldLatchFinger = true;  
    147.             }  
    148.             else if ( gui.HitTest( touch.position ) )  
    149.             {  
    150.                 shouldLatchFinger = true;  
    151.             }         
    152.       
    153.             // Latch the finger if this is a new touch  
    154.             if ( shouldLatchFinger && ( lastFingerId == -1 || lastFingerId != touch.fingerId ) )  
    155.             {  
    156.                   
    157.                 if ( touchPad )  
    158.                 {  
    159.                     gui.color.a = 0.15;  
    160.                       
    161.                     lastFingerId = touch.fingerId;  
    162.                     fingerDownPos = touch.position;  
    163.                     fingerDownTime = Time.time;  
    164.                 }  
    165.                   
    166.                 lastFingerId = touch.fingerId;  
    167.                   
    168.                 // Accumulate taps if it is within the time window  
    169.                 if ( tapTimeWindow > 0 )  
    170.                     tapCount++;  
    171.                 else  
    172.                 {  
    173.                     tapCount = 1;  
    174.                     tapTimeWindow = tapTimeDelta;  
    175.                 }  
    176.                                               
    177.                 // Tell other joysticks we've latched this finger  
    178.                 for ( var j : Joystick in joysticks )  
    179.                 {  
    180.                     if ( j != this )  
    181.                         j.LatchedFinger( touch.fingerId );  
    182.                 }                         
    183.             }                 
    184.       
    185.             if ( lastFingerId == touch.fingerId )  
    186.             {     
    187.                 // Override the tap count with what the iPhone SDK reports if it is greater  
    188.                 // This is a workaround, since the iPhone SDK does not currently track taps  
    189.                 // for multiple touches  
    190.                 if ( touch.tapCount > tapCount )  
    191.                     tapCount = touch.tapCount;  
    192.                   
    193.                 if ( touchPad )  
    194.                 {     
    195.                     // For a touchpad, let's just set the position directly based on distance from initial touchdown  
    196.                     position.x = Mathf.Clamp( ( touch.position.x - fingerDownPos.x ) / ( touchZone.width / 2 ), -1, 1 );  
    197.                     position.y = Mathf.Clamp( ( touch.position.y - fingerDownPos.y ) / ( touchZone.height / 2 ), -1, 1 );  
    198.                 }  
    199.                 else  
    200.                 {                     
    201.                     // Change the location of the joystick graphic to match where the touch is  
    202.                     gui.pixelInset.x =  Mathf.Clamp( guiTouchPos.x, guiBoundary.min.x, guiBoundary.max.x );  
    203.                     gui.pixelInset.y =  Mathf.Clamp( guiTouchPos.y, guiBoundary.min.y, guiBoundary.max.y );       
    204.                 }  
    205.                   
    206.                 if ( touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled )  
    207.                     ResetJoystick();                      
    208.             }             
    209.         }  
    210.     }  
    211.       
    212.     if ( !touchPad )  
    213.     {  
    214.         // Get a value between -1 and 1 based on the joystick graphic location  
    215.         position.x = ( gui.pixelInset.x + guiTouchOffset.x - guiCenter.x ) / guiTouchOffset.x;  
    216.         position.y = ( gui.pixelInset.y + guiTouchOffset.y - guiCenter.y ) / guiTouchOffset.y;  
    217.     }  
    218.       
    219.     // Adjust for dead zone   
    220.     var absoluteX = Mathf.Abs( position.x );  
    221.     var absoluteY = Mathf.Abs( position.y );  
    222.       
    223.     if ( absoluteX < deadZone.x )  
    224.     {  
    225.         // Report the joystick as being at the center if it is within the dead zone  
    226.         position.x = 0;  
    227.     }  
    228.     else if ( normalize )  
    229.     {  
    230.         // Rescale the output after taking the dead zone into account  
    231.         position.x = Mathf.Sign( position.x ) * ( absoluteX - deadZone.x ) / ( 1 - deadZone.x );  
    232.     }  
    233.           
    234.     if ( absoluteY < deadZone.y )  
    235.     {  
    236.         // Report the joystick as being at the center if it is within the dead zone  
    237.         position.y = 0;  
    238.     }  
    239.     else if ( normalize )  
    240.     {  
    241.         // Rescale the output after taking the dead zone into account  
    242.         position.y = Mathf.Sign( position.y ) * ( absoluteY - deadZone.y ) / ( 1 - deadZone.y );  
    243.     }  
    244. }  

     

     

     

     

    单击Create 创建一个GUI Texture,命名为Joy ,它用来显示游戏摇杆,如下图所示将摇杆的图片资源,与摇杆的脚本连线赋值给Joy.  Pixel Inset 中可以设置摇杆的显示位置与显示宽高。

     

     

     

     

     

    到这一步 build and run 就可以在iPhone上看到这个游戏摇杆,并且可以通过触摸它,360度平滑过度。

     

     

    在屏幕中绘制一个飞机,通过游戏摇杆去控制飞机的移动。

     

    创建一个脚本,命名为Main.js 如下图所示  将 Main.js 、joy、plan 分别 绑定在Main Camera 上。

     

     


     

     

    moveJoystick.position.x;

    moveJoystick.position.y;

     

    这两个值是非常重要的两个信息,它们的取值范围是 -1 到 +1 ,表示 用户触摸摇杆的位置, 上 下 左 右 的信息。

     

     

    [javascript] view plaincopy
    1. //游戏摇杆对象  
    2. var moveJoystick : Joystick;  
    3.   
    4. //飞机的贴图  
    5. var plan : Texture;  
    6.   
    7. //飞机在屏幕中的坐标  
    8. var x = 0;  
    9. var y = 0;  
    10.   
    11. //避免飞机飞出屏幕,分别是X、Y最大坐标,最小坐标是0、0  
    12. var cross_x = 0;  
    13. var cross_y = 0;  
    14.   
    15. //飞机移动的速度  
    16. var planSpeed = 20;  
    17.   
    18. function Start() {  
    19.     //初始化赋值  
    20.     x = 100;  
    21.     y = 100;  
    22.     cross_x = Screen.width -  plan.width;  
    23.     cross_y = Screen.height -  plan.height;  
    24.       
    25. }  
    26.   
    27. function Update () {  
    28.     //得到游戏摇杆的反馈信息,得到的值是 -1 到 +1 之间  
    29.       
    30.     var touchKey_x =  moveJoystick.position.x;  
    31.     var touchKey_y =  moveJoystick.position.y;  
    32.       
    33.     //摇杆向左  
    34.     if(touchKey_x == -1){  
    35.         x -= planSpeed;  
    36.           
    37.     }  
    38.     //摇杆向右  
    39.     else if(touchKey_x == 1){  
    40.         x += planSpeed;  
    41.           
    42.     }  
    43.     //摇杆向上  
    44.     if(touchKey_y == -1){  
    45.         y += planSpeed;  
    46.           
    47.     }  
    48.     //摇杆向下  
    49.     else if(touchKey_y == 1){  
    50.         y -= planSpeed;  
    51.           
    52.     }  
    53.       
    54.     //防止飞机飞出屏幕,出界检测  
    55.     if(x < 0){  
    56.         x = 0;  
    57.     }else if(x > cross_x){  
    58.         x = cross_x;  
    59.     }  
    60.       
    61.     if(y < 0){  
    62.         y = 0;  
    63.     }else if(y > cross_y){  
    64.         y = cross_y;  
    65.     }  
    66. }  
    67.   
    68.   
    69.   
    70.   
    71. function OnGUI () {  
    72.   
    73.   
    74.   //将飞机绘制在屏幕中  
    75.   GUI.DrawTexture(Rect(x,y,128,128),plan);    
    76.   
    77. }  



    导出 build and run  看看在iPhone 上的效果,通过触摸游戏摇杆可以控制飞机的移动啦,不错吧,哇咔咔~~

     

     

     

     

     

     

     

    最后欢迎各位盆友可以和MOMO一起讨论Unity3D游戏开发,最近感冒的盆友越来越多,大家要多多注意身体健康噢。哇咔咔~~~ 附上Unity3D工程的下载地址,Xcode项目我就不上传了,须要的自己导出。

     

    下载地址:http://www.xuanyusong.com/archives/526

  • 相关阅读:
    [Istio]流量管理API v1alpha3路由规则
    [Istioc]Istio部署sock-shop时rabbitmq出现CrashLoopBackOff
    [Go]指针操作
    [Go]接口的运用
    [Go]结构体及其方法
    [Kubernetes]Volume
    [Kubernetes]kubectl命令补全出错
    [Docker]容器镜像
    [Docker]容器的隔离与限制
    [Go]通道(channel)的基本操作
  • 原文地址:https://www.cnblogs.com/songtzu/p/3009557.html
Copyright © 2020-2023  润新知