Unity3D 虚拟摇杆 NGUI实现方法

来源:互联网 发布:银行数据录入员 提成 编辑:程序博客网 时间:2024/04/28 15:58

特此声明!对不起各位读者了,这是小生刚接触NGUI的做法,这些日子来才想起还写过了这篇博客,现在看来这篇博客的做法实在是SB,各位看到标题的读者也就不必看下去了,估计也没有时间去更新了,抱歉


首先呢,先声明一下哈,这个脚本从头到尾都是我自己设计和编写的哈,再加上今年就大四啦,所以要也开始镀一点金啦,所以呢,各位朋友也帮一下忙哈,能赞一个就赞一个哈,多多交流,共同进步哈,而且在您转载、修改、优化、使用的话,如果这几行字没碍着您的眼的话,留着也行哈。在代码中就是这几行哈。

/** * note 此代码原创为谭俊孟编写 note * note 如果对此代码有什么好的意见或者建议 note * note 请联系QQ:408333990 note * note 或者发邮箱:408333990@qq.com note * note 大家共同交流和进步 note * note 现由XXX转载修改,优化并使用 note */

因为我也刚接触Unity不久,自适应效果的框架还没来得急写,所以下面说一下这段代码需要的前期准备哈,不然数值不对就很容易出异常哈:

(1)NGUI的最基本操作要会哈,我也就刚刚学NGUI了几小时,也只是会创建一下控件而已哈,要用也得查查API哈。

(2)建一个摇杆移动范围的贴图(Texture),像这样那个半透明的圆形区域,,当然弄也行,这个就是好看一些哈,如果弄的话步骤是:准备一张你自己觉得好看的贴图,然后直接用NGUI建个Texture就行了,如果你的图片显示不是图片原有的效果,那可以尝试选择一下着色器(shader)的模式。

(3)准备你觉得合适的图片,然后用它创建一个图文集(Atlas);如果不会的话,那我就不教你啦,如果这个自己百度了还不会,那还是转行快点哈;话多了,不好意思。然后用这个图文集创建一个Button。

(4)这个需要修改的几个地方,1、这些Button自带代码的属性,JoyControl.cs就是我编写的代码,等会再细说哈。2、Button的碰撞器要改,把Box Collider修改成这个。3、Button的Background的Scale设置一下,

(5)代码的话应该有没有什么吧,我写了很多注释哈,如果实在看不懂,你们再留言,然后我再说哈。

 

 

using UnityEngine;using System.Collections;/** * note 此代码原创为谭俊孟编写 note * note 如果对此代码有什么好的意见或者建议 note * note 请联系QQ:408333990 note * note 或者发邮箱:408333990@qq.com note * note 大家共同交流和进步 note * note 现由XXX转载修改,优化并使用 note */public class JoyControl : MonoBehaviour{public GameObject playerTank;private float joyInitX;//note 摇杆的圆心初始坐标X noteprivate float joyInitY;//note 摇杆的圆心初始坐标Y noteprivate float joyMoveDistance;//note 摇杆最大可移动的距离 noteprivate float currentDistance;//note 单签摇杆圆心离初始圆心的距离 noteprivate float joyControlDistance;//note 摇杆开始控制坦克移动的最小距离 noteprivate float mousePositionX;//note 鼠标相对NGUI坐标系的坐标X noteprivate float mousePositionY;//note 鼠标相对NGUI坐标系的坐标X noteprivate float parallelMoveLeftX;//note 摇杆控制坦克平行移动左边界X noteprivate float parallelMoveRightX;//note 摇杆控制坦克平行移动右边界X noteprivate float parallelMoveLeftY;//note 摇杆控制坦克平行移动左边界Y noteprivate float parallelMoveRightY;//note 摇杆控制坦克平行移动右边界X noteprivate bool isTankMove;//note 摇杆是否能控制坦克移动 notevoid Start (){joyInitX = this.transform.localPosition.x;joyInitY = this.transform.localPosition.y;joyMoveDistance = 22.5f;joyControlDistance = 5.0f;mousePositionX = this.transform.localPosition.x;mousePositionY = this.transform.localPosition.y;parallelMoveLeftX = this.transform.localPosition.x - 5.0f;parallelMoveRightX = this.transform.localPosition.x + 5.0f;parallelMoveLeftY = this.transform.localPosition.y + 5.0f;parallelMoveRightY = this.transform.localPosition.y - 5.0f;}void Update(){if(isTankMove){//note 判断坦克是否在前后平行活动距离内 noteif(this.transform.localPosition.x > parallelMoveLeftX && this.transform.localPosition.x < parallelMoveRightX){// note 坦克移动 noteif(this.transform.localPosition.y > joyInitY){playerTank.transform.Translate(Vector3.forward * Time.deltaTime * getAbs(this.transform.localPosition.y, joyInitY) * playerTank.GetComponent<Tank>().tankMoveSpeed);}else{playerTank.transform.Translate(Vector3.back * Time.deltaTime * getAbs(this.transform.localPosition.y, joyInitY) * playerTank.GetComponent<Tank>().tankMoveSpeed);}}else if(this.transform.localPosition.y < parallelMoveLeftY && this.transform.localPosition.y > parallelMoveRightY){//note 横向拖动摇杆不做任何操作 note}else{//note 坦克移动和旋转 noteif(this.transform.localPosition.y > joyInitY){playerTank.transform.Translate(Vector3.forward * Time.deltaTime * getAbs(this.transform.localPosition.y, joyInitY) * playerTank.GetComponent<Tank>().tankMoveSpeed);if(this.transform.localPosition.x < joyInitX){playerTank.transform.Rotate(Vector3.down * Time.deltaTime * getAbs(this.transform.localPosition.x, joyInitX) * playerTank.GetComponent<Tank>().tankRotateSpeed);}else{playerTank.transform.Rotate(Vector3.up * Time.deltaTime * getAbs(this.transform.localPosition.x, joyInitX) * playerTank.GetComponent<Tank>().tankRotateSpeed);}}else{playerTank.transform.Translate(Vector3.back * Time.deltaTime * getAbs(this.transform.localPosition.y, joyInitY) * playerTank.GetComponent<Tank>().tankMoveSpeed);if(this.transform.localPosition.x < joyInitX){playerTank.transform.Rotate(Vector3.up * Time.deltaTime * getAbs(this.transform.localPosition.x, joyInitX) * playerTank.GetComponent<Tank>().tankRotateSpeed);}else{playerTank.transform.Rotate(Vector3.down * Time.deltaTime * getAbs(this.transform.localPosition.x, joyInitX) * playerTank.GetComponent<Tank>().tankRotateSpeed);}}}}}    void OnDrag (Vector2 delta) {if(GameObject.Find("Main Camera").GetComponent<MyCamera>().cameraState == 1){//note 摇杆随鼠标移动 notemousePositionX = Input.mousePosition.x - (float)Screen.width / 2;mousePositionY = Input.mousePosition.y - (float)Screen.height / 2;this.transform.localPosition = new Vector3(mousePositionX, mousePositionY, 0);// note 获得单签摇杆圆心离初始圆心的距离 notecurrentDistance = Mathf.Sqrt(getAbs(this.transform.localPosition.x, joyInitX) * getAbs(this.transform.localPosition.x, joyInitX) + getAbs(this.transform.localPosition.y, joyInitY) * getAbs(this.transform.localPosition.y, joyInitY));//note 判断摇杆移动距离是否超过最大距离,超过则设为最边沿的点 noteif(currentDistance < joyControlDistance){isTankMove = false;}else if(currentDistance > joyMoveDistance){setJoyMoveMaxPosition();isTankMove = true;}else{isTankMove = true;}}else if(GameObject.Find("Main Camera").GetComponent<MyCamera>().cameraState == 2){}    }/** * note 计算两个值的绝对值之差的绝对值 note */ float getAbs(float a, float b){return Mathf.Abs(Mathf.Abs(a)-Mathf.Abs(b));}/** * note 求摇杆可移动最大边界点的坐标 note */void setJoyMoveMaxPosition(){/*  * note 移动鼠标控制摇杆超过规定距离,则摇杆保持以摇杆为圆心的当前两点的原斜率,长度为最大长度 note * note 其中x,y为(joyInitX, joyInitY),而(x1,y1)为当前摇杆坐标,R为和joyMoveDistance note * note (x2, y2)为最后要求的结果坐标,并且赋给当前的摇杆 note * ntoe 算法: note * note 由直线公式:y = kx + b; 推出k 和 b note * note k = (y1 - y) / (x1 - x);   b = y - k * x; note * note 再由园的公式(x2 - x)^2 + (y2 - y)^2 = R^2; note * note 进行带入运算得出关于x2的一元二次方程: (x2 - x)^2 + (k * x2 + b - y)^2 = R^2; note * note 整理后得出:(1 + k^2) * x2^2 + 2 * (k*b - k*y - x)x2 + x^2 + b^2 + y^2 - 2*b*y - R^2 = 0; note * note 再根据求根公式:x=[-b±√(b^2-4ac)]/2a 和 当前摇杆坐标X与初始坐标X的比较可得出x2的值,继而得出相应的y2 note */float k, b;//note 直线的参数 notefloat a1, b1, c1;//note 一元二次方程的参数 notefloat tempX1,tempX2;//note 最后得出的两个X坐标 notek = (this.transform.localPosition.y - joyInitY) / (this.transform.localPosition.x - joyInitX);b = joyInitY - k * joyInitX;a1 = 1 + k*k;b1 = 2 * (k*b -k*joyInitY - joyInitX);c1 = joyInitX*joyInitX + b*b + joyInitY*joyInitY - 2*b*joyInitY - joyMoveDistance*joyMoveDistance;tempX1 = (-b1 + Mathf.Sqrt(b1*b1 - 4*a1*c1)) / (2 * a1);tempX2 = (-b1 - Mathf.Sqrt(b1*b1 - 4*a1*c1)) / (2 * a1);if(this.transform.localPosition.x > joyInitX){if(tempX1 > joyInitX){this.transform.localPosition = new Vector3 (tempX1, k*tempX1 + b, 0);}else{this.transform.localPosition = new Vector3 (tempX2, k*tempX2 + b, 0);}}else{if(tempX1 < joyInitX){this.transform.localPosition = new Vector3 (tempX1, k*tempX1 + b, 0);}else{this.transform.localPosition = new Vector3 (tempX2, k*tempX2 + b, 0);}}}}


最后呢,总结一下吧,因为接触Unity时间不长,更加不说NGUI了,所以自适应效果没有做,还有一些异常处理液没有做,如果代码里面的某些东西给大家带来误导,那我先抱歉一下哈,哦,对了,最重要的,因为爪机太过落后,没能上真机调试,真能用电脑来调,所以就不是Touch时间了,而是mouse事件,不过应该改一下就行了,思想都是一样的哈,有什么好的意见或者建议请留言或者QQ或者邮箱联系哈。