特此声明!对不起各位读者了,这是小生刚接触NGUI的做法,这些日子来才想起还写过了这篇博客,现在看来这篇博客的做法实在是SB,各位看到标题的读者也就不必看下去了,估计也没有时间去更新了,抱歉
首先呢,先声明一下哈,这个脚本从头到尾都是我自己设计和编写的哈,再加上今年就大四啦,所以要也开始镀一点金啦,所以呢,各位朋友也帮一下忙哈,能赞一个就赞一个哈,多多交流,共同进步哈,而且在您转载、修改、优化、使用的话,如果这几行字没碍着您的眼的话,留着也行哈。在代码中就是这几行哈。
/**
* note 此代码原创为谭俊孟编写 note
* note 如果对此代码有什么好的意见或者建议 note
* note 请联系QQ:408333990 note
* note 或者发邮箱:[email protected] 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 或者发邮箱:[email protected] note
* note 大家共同交流和进步 note
* note 现由XXX转载修改,优化并使用 note
*/
public class JoyControl : MonoBehaviour
{
public GameObject playerTank;
private float joyInitX; //note 摇杆的圆心初始坐标X note
private float joyInitY; //note 摇杆的圆心初始坐标Y note
private float joyMoveDistance; //note 摇杆最大可移动的距离 note
private float currentDistance; //note 单签摇杆圆心离初始圆心的距离 note
private float joyControlDistance; //note 摇杆开始控制坦克移动的最小距离 note
private float mousePositionX; //note 鼠标相对NGUI坐标系的坐标X note
private float mousePositionY; //note 鼠标相对NGUI坐标系的坐标X note
private float parallelMoveLeftX; //note 摇杆控制坦克平行移动左边界X note
private float parallelMoveRightX; //note 摇杆控制坦克平行移动右边界X note
private float parallelMoveLeftY; //note 摇杆控制坦克平行移动左边界Y note
private float parallelMoveRightY; //note 摇杆控制坦克平行移动右边界X note
private bool isTankMove; //note 摇杆是否能控制坦克移动 note
void 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 判断坦克是否在前后平行活动距离内 note
if(this.transform.localPosition.x > parallelMoveLeftX && this.transform.localPosition.x < parallelMoveRightX)
{
// note 坦克移动 note
if(this.transform.localPosition.y > joyInitY)
{
playerTank.transform.Translate(Vector3.forward * Time.deltaTime * getAbs(this.transform.localPosition.y, joyInitY) * playerTank.GetComponent().tankMoveSpeed);
}
else
{
playerTank.transform.Translate(Vector3.back * Time.deltaTime * getAbs(this.transform.localPosition.y, joyInitY) * playerTank.GetComponent().tankMoveSpeed);
}
}
else if(this.transform.localPosition.y < parallelMoveLeftY && this.transform.localPosition.y > parallelMoveRightY)
{
//note 横向拖动摇杆不做任何操作 note
}
else
{
//note 坦克移动和旋转 note
if(this.transform.localPosition.y > joyInitY)
{
playerTank.transform.Translate(Vector3.forward * Time.deltaTime * getAbs(this.transform.localPosition.y, joyInitY) * playerTank.GetComponent().tankMoveSpeed);
if(this.transform.localPosition.x < joyInitX)
{
playerTank.transform.Rotate(Vector3.down * Time.deltaTime * getAbs(this.transform.localPosition.x, joyInitX) * playerTank.GetComponent().tankRotateSpeed);
}
else
{
playerTank.transform.Rotate(Vector3.up * Time.deltaTime * getAbs(this.transform.localPosition.x, joyInitX) * playerTank.GetComponent().tankRotateSpeed);
}
}
else
{
playerTank.transform.Translate(Vector3.back * Time.deltaTime * getAbs(this.transform.localPosition.y, joyInitY) * playerTank.GetComponent().tankMoveSpeed);
if(this.transform.localPosition.x < joyInitX)
{
playerTank.transform.Rotate(Vector3.up * Time.deltaTime * getAbs(this.transform.localPosition.x, joyInitX) * playerTank.GetComponent().tankRotateSpeed);
}
else
{
playerTank.transform.Rotate(Vector3.down * Time.deltaTime * getAbs(this.transform.localPosition.x, joyInitX) * playerTank.GetComponent().tankRotateSpeed);
}
}
}
}
}
void OnDrag (Vector2 delta)
{
if(GameObject.Find("Main Camera").GetComponent().cameraState == 1)
{
//note 摇杆随鼠标移动 note
mousePositionX = Input.mousePosition.x - (float)Screen.width / 2;
mousePositionY = Input.mousePosition.y - (float)Screen.height / 2;
this.transform.localPosition = new Vector3(mousePositionX, mousePositionY, 0);
// note 获得单签摇杆圆心离初始圆心的距离 note
currentDistance = 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 判断摇杆移动距离是否超过最大距离,超过则设为最边沿的点 note
if(currentDistance < joyControlDistance)
{
isTankMove = false;
}
else if(currentDistance > joyMoveDistance)
{
setJoyMoveMaxPosition();
isTankMove = true;
}
else
{
isTankMove = true;
}
}
else if(GameObject.Find("Main Camera").GetComponent().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 直线的参数 note
float a1, b1, c1; //note 一元二次方程的参数 note
float tempX1,tempX2; //note 最后得出的两个X坐标 note
k = (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或者邮箱联系哈。