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

雨松MOMO原创文章如转载,请注明:转载至我的独立域名博客雨松MOMO程序研究院,原文地址:http://www.xuanyusong.com/archives/526

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


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

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

//
// Joystick.js
// Penelope iPhone Tutorial
//
// Joystick creates a movable joystick (via GUITexture) that
// handles touch input, taps, and phases. Dead zones can control
// where the joystick input gets picked up and can be normalized.
//
// Optionally, you can enable the touchPad property from the editor
// to treat this Joystick as a TouchPad. A TouchPad allows the finger
// to touch down at any point and it tracks the movement relatively
// without moving the graphic
//@script RequireComponent( GUITexture )// A simple class for bounding how far the GUITexture will move
class Boundary
{var min : Vector2 = Vector2.zero;var max : Vector2 = Vector2.zero;
}static private var joysticks : Joystick[];                 // A static collection of all joysticks
static private var enumeratedJoysticks : boolean = false;
static private var tapTimeDelta : float = 0.3;             // Time allowed between tapsvar touchPad : boolean;                                     // Is this a TouchPad?
var touchZone : Rect;
var deadZone : Vector2 = Vector2.zero;                     // Control when position is output
var normalize : boolean = false;                           // Normalize output after the dead-zone?
var position : Vector2;                                     // [-1, 1] in x,y
var tapCount : int;                                         // Current tap countprivate var lastFingerId = -1;                             // Finger last used for this joystick
private var tapTimeWindow : float;                          // How much time there is left for a tap to occur
private var fingerDownPos : Vector2;
private var fingerDownTime : float;
private var firstDeltaTime : float = 0.5;private var gui : GUITexture;                             // Joystick graphic
private var defaultRect : Rect;                             // Default position / extents of the joystick graphic
private var guiBoundary : Boundary = Boundary();           // Boundary for joystick graphic
private var guiTouchOffset : Vector2;                       // Offset to apply to touch input
private var guiCenter : Vector2;                            // Center of joystickfunction Start()
{// Cache this component at startup instead of looking up every frame   gui = GetComponent( GUITexture );// Store the default rect for the gui, so we can snap back to itdefaultRect = gui.pixelInset;    defaultRect.x += transform.position.x * Screen.width;// + gui.pixelInset.x; // -  Screen.width * 0.5;defaultRect.y += transform.position.y * Screen.height;// - Screen.height * 0.5;transform.position.x = 0.0;transform.position.y = 0.0;if ( touchPad ){// If a texture has been assigned, then use the rect ferom the gui as our touchZoneif ( gui.texture )touchZone = defaultRect;}else{               // This is an offset for touch input to match with the top left// corner of the GUIguiTouchOffset.x = defaultRect.width * 0.5;guiTouchOffset.y = defaultRect.height * 0.5;// Cache the center of the GUI, since it doesn't changeguiCenter.x = defaultRect.x + guiTouchOffset.x;guiCenter.y = defaultRect.y + guiTouchOffset.y;// Let's build the GUI boundary, so we can clamp joystick movementguiBoundary.min.x = defaultRect.x - guiTouchOffset.x;guiBoundary.max.x = defaultRect.x + guiTouchOffset.x;guiBoundary.min.y = defaultRect.y - guiTouchOffset.y;guiBoundary.max.y = defaultRect.y + guiTouchOffset.y;}
}function Disable()
{gameObject.active = false;enumeratedJoysticks = false;
}function ResetJoystick()
{// Release the finger control and set the joystick back to the default positiongui.pixelInset = defaultRect;lastFingerId = -1;position = Vector2.zero;fingerDownPosition = Vector2.zero;if ( touchPad )gui.color.a = 0.025;
}function IsFingerDown() : boolean
{return (lastFingerId != -1);
}function LatchedFinger( fingerId : int )
{// If another joystick has latched this finger, then we must release itif ( lastFingerId == fingerId )ResetJoystick();
}function Update()
{   if ( !enumeratedJoysticks ){// Collect all joysticks in the game, so we can relay finger latching messagesjoysticks = FindObjectsOfType( Joystick );enumeratedJoysticks = true;}  var count = Input.touchCount;// Adjust the tap time window while it still availableif ( tapTimeWindow > 0 )tapTimeWindow -= Time.deltaTime;elsetapCount = 0;if ( count == 0 )ResetJoystick();else{for(var i : int = 0;i < count; i++){var touch : Touch = Input.GetTouch(i);         var guiTouchPos : Vector2 = touch.position - guiTouchOffset;var shouldLatchFinger = false;if ( touchPad ){                if ( touchZone.Contains( touch.position ) )shouldLatchFinger = true;}else if ( gui.HitTest( touch.position ) ){shouldLatchFinger = true;}     // Latch the finger if this is a new touchif ( shouldLatchFinger && ( lastFingerId == -1 || lastFingerId != touch.fingerId ) ){if ( touchPad ){gui.color.a = 0.15;lastFingerId = touch.fingerId;fingerDownPos = touch.position;fingerDownTime = Time.time;}lastFingerId = touch.fingerId;// Accumulate taps if it is within the time windowif ( tapTimeWindow > 0 )tapCount++;else{tapCount = 1;tapTimeWindow = tapTimeDelta;}// Tell other joysticks we've latched this fingerfor ( var j : Joystick in joysticks ){if ( j != this )j.LatchedFinger( touch.fingerId );}                       }               if ( lastFingerId == touch.fingerId ){    // Override the tap count with what the iPhone SDK reports if it is greater// This is a workaround, since the iPhone SDK does not currently track taps// for multiple touchesif ( touch.tapCount > tapCount )tapCount = touch.tapCount;if ( touchPad ){ // For a touchpad, let's just set the position directly based on distance from initial touchdownposition.x = Mathf.Clamp( ( touch.position.x - fingerDownPos.x ) / ( touchZone.width / 2 ), -1, 1 );position.y = Mathf.Clamp( ( touch.position.y - fingerDownPos.y ) / ( touchZone.height / 2 ), -1, 1 );}else{                  // Change the location of the joystick graphic to match where the touch isgui.pixelInset.x =  Mathf.Clamp( guiTouchPos.x, guiBoundary.min.x, guiBoundary.max.x );gui.pixelInset.y =  Mathf.Clamp( guiTouchPos.y, guiBoundary.min.y, guiBoundary.max.y );      }if ( touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled )ResetJoystick();                   }           }}if ( !touchPad ){// Get a value between -1 and 1 based on the joystick graphic locationposition.x = ( gui.pixelInset.x + guiTouchOffset.x - guiCenter.x ) / guiTouchOffset.x;position.y = ( gui.pixelInset.y + guiTouchOffset.y - guiCenter.y ) / guiTouchOffset.y;}// Adjust for dead zone   var absoluteX = Mathf.Abs( position.x );var absoluteY = Mathf.Abs( position.y );if ( absoluteX < deadZone.x ){// Report the joystick as being at the center if it is within the dead zoneposition.x = 0;}else if ( normalize ){// Rescale the output after taking the dead zone into accountposition.x = Mathf.Sign( position.x ) * ( absoluteX - deadZone.x ) / ( 1 - deadZone.x );}if ( absoluteY < deadZone.y ){// Report the joystick as being at the center if it is within the dead zoneposition.y = 0;}else if ( normalize ){// Rescale the output after taking the dead zone into accountposition.y = Mathf.Sign( position.y ) * ( absoluteY - deadZone.y ) / ( 1 - deadZone.y );}
}

单击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 ,表示 用户触摸摇杆的位置, 上 下 左 右 的信息。


//游戏摇杆对象
var moveJoystick : Joystick;//飞机的贴图
var plan : Texture;//飞机在屏幕中的坐标
var x = 0;
var y = 0;//避免飞机飞出屏幕,分别是X、Y最大坐标,最小坐标是0、0
var cross_x = 0;
var cross_y = 0;//飞机移动的速度
var planSpeed = 20;function Start() {//初始化赋值x = 100;y = 100;cross_x = Screen.width -  plan.width;cross_y = Screen.height -  plan.height;}function Update () {//得到游戏摇杆的反馈信息,得到的值是 -1 到 +1 之间var touchKey_x =  moveJoystick.position.x;var touchKey_y =  moveJoystick.position.y;//摇杆向左if(touchKey_x == -1){x -= planSpeed;}//摇杆向右else if(touchKey_x == 1){x += planSpeed;}//摇杆向上if(touchKey_y == -1){y += planSpeed;}//摇杆向下else if(touchKey_y == 1){y -= planSpeed;}//防止飞机飞出屏幕,出界检测if(x < 0){x = 0;}else if(x > cross_x){x = cross_x;}if(y < 0){y = 0;}else if(y > cross_y){y = cross_y;}
}function OnGUI () {//将飞机绘制在屏幕中GUI.DrawTexture(Rect(x,y,128,128),plan);  }

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

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

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

Unity3D 游戏引擎之IOS自定义游戏摇杆与飞机平滑的移动(十一)相关推荐

  1. Unity3D 游戏引擎之IOS高级界面发送消息与Unity3D消息的接收(九)

    Unity3D 游戏引擎之IOS高级界面发送消息与Unity3D消息的接收 雨松MOMO原创文章如转载,请注明:转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xys289 ...

  2. 我们月光工作室和我们的3款游戏被国内Unity3D游戏引擎第一技术论坛--“游戏蛮牛” 报道啦!...

    注明:目前月光工作室已经停止更新,因为创业伙伴回国,小编自己忙于<程序员联盟>社区的各样事务.以后也许会重拾App开发吧.谨以此文纪念那段美好的时光!以下的某些链接也已失效. 我们月光工作 ...

  3. webGL、webGPU、封装、渲染引擎 three.js、游戏引擎,定位是游戏开发,在前面的渲染引擎基础上,还提供了骨骼动画、物理引擎、AI、GUI 等功能,以及可视化编辑器来设计关卡,支撑大型游戏

    https://zhuanlan.zhihu.com/p/162878354 如何选择 WebGL 框架和引擎? ​ 知道得越多,不知道的就更多了 数据可视化Sugar-百度智能云 ​cloud.ba ...

  4. Love2D游戏引擎制作贪吃蛇游戏

    预览游戏 love2d游戏引擎重要函数 详情: love.load:当游戏开始时被调用且仅调用一次 love.draw:回调函数,每帧更新一次游戏画面 love.update:回调函数,每帧更新一次游 ...

  5. 手把手教你架构3d游戏引擎pdf_一个在游戏行业摸爬滚打了十几年的人,为何我对这本书情有独钟...

    Big News!<游戏开发:世嘉新人培训教材>今日开始预售啦!经过漫长的等待,这次终于可以买到了.现在下单,你将在图书出印厂的第一时间收到书哦- 这本书由世嘉一线开发者执笔,并被选为世嘉 ...

  6. 开源游戏引擎_Hatchit:开源游戏引擎

    开源游戏引擎 通过视频游戏,越来越多的学生正在学习开源世界. 像FreeCiv和Minetest这样的开源游戏邀请年轻的玩家来研究源代码,而像SpigotMC这样的项目则使他们能够编写插件来扩展自己喜 ...

  7. python 游戏引擎 cocos2d_【Cocos2dx游戏开发】Cocos2d-x简介

    一.简介 最近在做一个Android下的卡牌游戏--<九州幻想>开发项目,而我们使用的引擎是Cocos2dx,所以想要写写笔记来记录一下项目中的收获.当然首先稍微介绍一下Cocos2d-x ...

  8. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程03:碰撞检测》

    2019独角兽企业重金招聘Python工程师标准>>> 3.碰撞检测 碰撞检测的概述: 碰撞在物理学中表现为两粒子或物体间极端的相互作用.而在游戏世界中,游戏对象在游戏世界自身并不受 ...

  9. 最大的幻术-游戏开发-到底是先学游戏引擎还是先学游戏编程

        学习游戏的目的     我们学习游戏制作,游戏开发,游戏编程,游戏XX,我们的目的只有一个,打造一个非常牛逼,非常屌,非常让人开心的虚拟体验.我们用自己的学识让玩家在虚拟世界征战,生活,一步一 ...

最新文章

  1. 分布式RPC实践--Dubbo基础篇
  2. Java 内存泄漏监控检测与分析
  3. 智源博士后合作导师专访 | 曾毅:面向可持续发展的人工智能
  4. centos7 各版本区别 DVD Netinstall Everything Minimal GnomeLive KdeLive
  5. java-String StringBuffer
  6. 【bzoj2006】【NOI2015】超级钢琴
  7. linux下面安装maven
  8. mysql中的视图_分布式 | DBLE 是如何实现视图的?
  9. PHP向右侧拉菜单,测试使用中
  10. Emacs + gdb单步调试汇编代码
  11. 分享最新36款高质量免费英文字体
  12. mysql systemctl开机启动_Linux 开机启动项命令:chkconfig 和 systemctl
  13. 书籍-从Paxos到Zookeeper分布式一致性原理与实践
  14. 使用 background:url(#) 解决 IE67 bug
  15. 鲁瑜计算机,程序员计算器.pptx
  16. 干货!大话EXT4文件系统完整版
  17. 尽在双11:阿里巴巴技术演进与超越
  18. 深入理解设计模式-设计模式七大原则
  19. c语言父进程创建孙进程,进程的创建与并发的执行-带答案版.doc
  20. OPENCV入门教程十一:dilate图像膨胀

热门文章

  1. oracle表启用online,Oracle数据库启动与关闭
  2. PyTorch深度学习入门笔记(五)torchvision中DataLoader的使用
  3. 瑞幸咖啡“起死回生”,商业与资本的“猫鼠游戏”?
  4. 接入腾讯云短信(免费+个人开发者)
  5. [数据结构] 无头结点的头插法建立单链表(c语言)
  6. angular4 入门
  7. 基于“数字孪生”和YoLoV5的AI药物开发(技术理论实践部分)
  8. Jacobian矩阵和Hessian矩阵,LM最优化方法
  9. C语言中putchar与getchar的易错之处
  10. esp32/arduino使用snap7与SIMENS plc通信