Unity3d NGUI 搖桿實現
阿新 • • 發佈:2018-11-27
1.搖桿父物體設定Anchor,在左邊設定左左下邊,在右邊設定右下角:
2.建立搖桿,設定前置圖片和背景圖在同一物體下,給背景圖新增碰撞體和指令碼,並且設定前置圖片:
程式碼:
using UnityEngine;
using System;
public class GameRocker : MonoBehaviour {
private static GameRocker _instance;
public static GameRocker Instance
{
get { return _instance; }
}
private UIRoot UIRoot { get; set; }
/// <summary>
/// 開始使用搖桿
/// </summary>
public Action OnRockerStart;
/// <summary>
/// 停止使用搖桿
/// </summary>
public Action OnRockerEnd;
/// <summary>
/// 當搖桿使用中
/// </summary>
public Action<Vector2> OnRockeRun;
/// <summary>
/// 搖桿前置點
/// </summary>
public Transform RockerForward;
/// <summary>
/// 搖桿前置點範圍
/// </summary>
public float PointRange = 50;
/// <summary>
/// 是否為定點搖桿
/// </summary>
public bool IsFixedPoint = false;
/// <summary>
/// 預設搖桿座標
/// </summary>
private Vector3 defalutPos = Vector3.zero;
private bool IsPress = false;
/// <summary>
/// 是否在右側
/// </summary>
public bool IsRight = false;
private BoxCollider BoxCollider { get; set; }
/// <summary>
/// 手指ID
/// </summary>
private int fingerId = -1;
/// <summary>
/// 螢幕比例
/// </summary>
private float SceneRatio = 0;
/// <summary>
/// 世界座標
/// </summary>
private Vector2 worldPos = Vector2.zero;
private string State = "";
void Awake()
{
_instance = this;
BoxCollider = this.GetComponent<BoxCollider>();
UIRoot = GameObject.FindObjectOfType<UIRoot>();
}
void Start()
{
defalutPos = transform.localPosition;
SceneRatio = Screen.height / (float)Screen.width ;
worldPos.y = UIRoot.manualHeight;
worldPos.x = (int)(worldPos.y / SceneRatio);
RockerForward.localPosition = transform.localPosition;
}
void OnPress(bool isPress)
{
if (isPress)
OnStart();
else
OnEnd();
IsPress = isPress;
}
void Update()
{
if (IsPress)
OnRun();
}
private void OnStart()
{
///pc
if (Application.platform != RuntimePlatform.WindowsEditor && Application.platform != RuntimePlatform.WindowsPlayer)
{
if (fingerId == -1)
{
//int touchCount = Input.touchCount;
for (int i = 0; i < Input.touchCount; i++)
{
Touch touchInfo = Input.GetTouch(i);
//拍段touch點位置
if (IsTheRange(touchInfo.position))
{
if (!IsFixedPoint)
transform.localPosition = PosConversion(touchInfo.position);
fingerId = touchInfo.fingerId;
break;
}
}
State = "Start";
}
}
else
{
if (!IsFixedPoint)
transform.localPosition = PosConversion(UICamera.lastTouchPosition);
}
RockerForward.localPosition = transform.localPosition;
if (OnRockerStart != null)
OnRockerStart();
}
private void OnEnd()
{
fingerId = -1;
if (!IsFixedPoint)
{
transform.localPosition = defalutPos;
//RockerForward.localPosition = transform.localPosition;
}
RockerForward.localPosition = transform.localPosition;
if (OnRockerEnd != null)
OnRockerEnd();
State = "End";
}
private float time = 0;
private string error = "";
private void OnRun()
{
try
{
error = "";
time += Time.deltaTime;
//pc
Vector3 TargetPos = Vector3.zero;
if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer)
TargetPos = PosConversion(UICamera.lastTouchPosition);
else//手機
{
Touch touchInfo = GetTouch(fingerId);
TargetPos = PosConversion(touchInfo.position);
}
if (TargetPos == transform.localPosition) return;
State = "Run";
//if (IsIgnore(TargetPos)) return;
//計算方向
Vector3 rockerDir = TargetPos - transform.localPosition;
//執行事件
if (OnRockeRun != null)
OnRockeRun(rockerDir.normalized);
//如果開啟了範圍限定
if (PointRange != -1)
{
float dis = Vector3.Distance(TargetPos, transform.localPosition);
if (dis > PointRange)
{
Vector3 pointPos = rockerDir.normalized * PointRange;
RockerForward.localPosition = transform.localPosition + pointPos;
return;
}
RockerForward.transform.localPosition = TargetPos;
}
}
catch (Exception ce)
{
error = ce.Message;
fingerId = -1;
OnStart();
}
}
/// <summary>
/// 座標轉
/// </summary>
Vector3 PosConversion(Vector2 pos)
{
Vector2 newPos = Vector2.zero;
float heightRatio = pos.y / Screen.height;
newPos.y = heightRatio * worldPos.y;
float widthRatio = pos.x / Screen.width;
newPos.x = widthRatio * worldPos.x;
if (IsRight)
{
newPos.x = -(worldPos.x- newPos.x);
}
return newPos;
}
bool IsTheRange(Vector2 pos)
{
pos = PosConversion(pos);
Vector2 topPoint = new Vector2(transform.localPosition.x+BoxCollider.size.x/2,transform.localPosition.y+BoxCollider.size.y/2);
Vector2 downPoint = new Vector2(transform.localPosition.x - BoxCollider.size.x / 2, transform.localPosition.y - BoxCollider.size.y / 2);
if (pos.x < topPoint.x && pos.x > downPoint.x && pos.y < topPoint.y && pos.y > downPoint.y)
return true;
return false;
}
Touch GetTouch(int TouchID)
{
for (int i = 0; i < Input.touchCount; i++)
{
if (Input.touches[i].fingerId.Equals(TouchID))
return Input.touches[i];
}
return default(Touch);
}
string des = "";
void OnGUI()
{
GUI.color = Color.red;
des = "";
des += "Count:" + Input.touchCount + "\n";
for (int i = 0; i < Input.touchCount; i++)
{
des += "id:" + Input.touches[i].fingerId + " pos:" + Input.touches[i].position + " delayPos:" + Input.touches[i].deltaPosition + "\n";
}
des += "CurJoyPos:" + transform.localPosition+"\n";
des += "FingerId:" + fingerId+"\n";
des += "IsPress:" + IsPress+"\n";
des += "Time:" + time+"\n";
des += "State:" + State+"\n";
des += "Error:" + error;
GUILayout.Label(des);
}
}