1. 程式人生 > >Unity3d NGUI 搖桿實現

Unity3d NGUI 搖桿實現

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); } }