Unity 使用有限狀態機 完美還原 王者榮耀 虛擬搖桿

效果如圖所示
搖桿的UI組成

如圖所示 簡單的可以認為搖桿由1、2、3貼圖組成
- 為搖桿的底座
- 為搖桿的桿
- 為搖桿的指向
可以理解這就是街機上的搖桿
詳解---搖桿顯示規則

如圖所示
- 最外面綠色的矩形為可點擊區域
- 黑色矩形為搖桿的顯示區域
-
搖桿在操作結束后會回到抬起位置(如圖狀態)
-
搖桿的可點擊區域有限制(如圖綠色框)
-
搖桿的顯示區域有限制(如圖黑色框 作用:防止搖桿一半在屏幕外 )
-
搖桿的中心位置隨點擊位置改變(如果在顯示區域外則取臨界值)
更據上面的規則定義public變量可以方便策划大佬運行狀態隨時修改
詳解---操作搖桿的幾種動作、狀態
首先我們把搖桿系統分解成狀態、動作
- 閑置(狀態)
- 按下(動作)
- 抬起(動作)
- 准備(狀態)
- 拖動(狀態)
動作、狀態區別(重點)
- 動作:一旦執行完畢就結束了(調用一次)
- 狀態:如果沒有外部條件的觸發,一個狀態會一直持續下去(不停的調用)

- 閑置---狀態
- 不需要做任何處理


- 按下---動作(手指按下屏幕 觸發)
- 獲取手指按下坐標
- 設置搖桿的位置(如左圖)
- 如果坐標在顯示區域外,則取臨界值(如右圖)
- UI、特效的顯示或隱藏

- 抬起---動作(手指離開屏幕 觸發)
- 搖桿回到抬起位置
- UI、特效的顯示或隱藏

- 准備---狀態(手指按下屏幕動作完成 觸發)
- 獲取手指的實時坐標
- 如果實時坐標與按下坐標的距離大於設定值則切換到拖動狀態
- UI、特效的顯示或隱藏

- 拖動---狀態(手指滑動 觸發)
- 獲取手指的實時坐標
- 獲取實時坐標與搖桿的坐標的距離P
- 設置桿的位置
- 如果桿的位置超過可拖動的最大值則取最大值
- 設置指向的位置
- 如果距離P大於顯示指向最小值則顯示指向同時
- 否則隱藏指向
這些動作、狀態是我邊測試邊寫代碼總結出來的
使用枚舉定義搖桿的幾種狀態、動作
可源代碼中找到對應的方法
詳解---幾種狀態、動作之間切換

-
手指按下切換到---按下動作
-
手指抬起切換到---抬起動作
-
按下動作執行完成切換到---准備狀態
-
准備狀態達成條件切換到---拖動狀態
使用到的API和方法
如果你理解了搖桿系統,但遇到了一些技術上的問題,下面的方法可能幫助你
- 計算兩個坐標的距離
float distance = Vector3.Distance(Vec0, Vec1);
- 獲取手指按下位置
Vector3 mousePosition = UICamera.currentTouch.pos;
- 計算手指按下相對於搖桿的位置
//轉換為世界坐標
mousePosition = UICamera.currentCamera.ScreenToWorldPoint(mousePosition);
//轉換為本地坐標
mousePosition = transform.InverseTransformPoint(mousePosition);
- 設置搖桿指向的角度
//mouseLocalPosition手指按下相對於搖桿的坐標
//background搖桿
//direction指向
Double angle = Math.Atan2((mouseLocalPosition.y - background.localPosition.y), (mouseLocalPosition.x - background.localPosition.x)) * 180 / Math.PI;
//設置搖桿指向的角度
direction.eulerAngles = new Vector3(0, 0, (float)angle);
如果有更好的辦法 求大佬賜教
老規矩工程鏈接:https://github.com/QiangZou/Joystick
UI、適配由NGUI實現,需要導入NGUI到工程中(NGUI有點大,沒上傳)
