unity中實(shí)現(xiàn)Edge瀏覽器鼠標(biāo)手勢的功能思路詳解
概要
Edge瀏覽器中,只需要使用鼠標(biāo)按住右鍵在屏幕上不同方向拖動,就可以觸發(fā)很多快捷操作,效果很絲滑。那如果想使用unity開發(fā)這么一個功能,支持PC端和移動端,要怎么做呢?
實(shí)現(xiàn)思路
實(shí)現(xiàn)起來其實(shí)并不復(fù)雜,涉及的技術(shù)點(diǎn)有pc端和移動端屏幕拖動事件,二維向量的相關(guān)運(yùn)算,手勢匹配算法,事件系統(tǒng)設(shè)計模式。
大概思路是:定義鼠標(biāo)路徑為不同的事件類型,例如:“Up”,“Down”,“Left”,“Right”,將相鄰不重復(fù)的路徑類型添加到一個列表中, 通過鼠標(biāo)事件,獲取當(dāng)前幀和上一幀的滑動方向,如果方向偏移當(dāng)前方向范圍,則判斷為鼠標(biāo)在滑動過程中發(fā)生了轉(zhuǎn)折,將每次轉(zhuǎn)折的方向記錄到一個列表中,轉(zhuǎn)折次數(shù)根據(jù)定義的事件鼠標(biāo)路徑數(shù)量而定,超出這個數(shù)量則判定為無效手勢,最后當(dāng)手勢抬起時,匹配定義的事件手勢路徑列表和滑動過程中記錄的手勢列表,如果匹配成功則判定觸發(fā)事件。
1.鼠標(biāo)拖動事件
提示:移動端和pc端事件有所區(qū)別
MouseDown
private static bool MouseDown() { if (Application.isMobilePlatform) { if (Input.touchCount == 1 && Input.touches[0].phase == TouchPhase.Began) { MouseId = 0; return true; } return false; } if (Input.GetMouseButtonDown(1)) { return true; } return false; }
MousePress
private static bool MousePress() { if (Application.isMobilePlatform) { return Input.touches[0].phase == TouchPhase.Moved || Input.touches[0].phase == TouchPhase.Stationary; } if (Input.GetMouseButton(1)) { return true; } return false; }
MouseUp
private static bool MouseUp() { if (Application.isMobilePlatform) { return Input.touches[0].phase == TouchPhase.Ended || Input.touches[0].phase == TouchPhase.Canceled; } if (Input.GetMouseButtonUp(1)) { return true; } return false; }
2.鼠標(biāo)拖動的二維方向計算
獲取鼠標(biāo)拖動的方向向量
private Vector2 GetDragDirection() { var v = (Vector2)Input.mousePosition - _preMousePoint; return v.normalized; }
計算方向,目前只識別上下左右四個方向,次方法可擴(kuò)展為八個方向
private Direction GetDirection() { var dir = GetDragDirection(); var dotH = Vector2.Dot(Vector2.right, dir); var dorV = Vector2.Dot(Vector2.up, dir); //更趨向于橫向滑動 if (Mathf.Abs(dotH) > Mathf.Abs(dorV)) { return dotH > 0 ? Direction.Right : Direction.Left; } //更趨向于縱向滑動 if (Mathf.Abs(dotH) < Mathf.Abs(dorV)) { return dorV > 0 ? Direction.Up : Direction.Down; } return _preDirection; }
提示:_preMousePoint為上一幀的鼠標(biāo)位置,此字段采集的頻率建議不要太過頻繁,不建議每幀采集,因?yàn)榭赡軐?dǎo)致滑動速度過慢時存在噪點(diǎn)手勢,影響事件結(jié)果
3.匹配鼠標(biāo)手勢路徑
記錄路徑方向
private void UpdateGestures() { var dir = GetDirection(); if (_preDirection != dir) { _preDirection = dir; _curDirections.Add(dir); } }
定義事件路徑,此處只示例最多兩段路徑,事件路徑可以擴(kuò)展多段
public static Dictionary<GestureState, List<Direction>> Gestures = new() { { GestureState.Down , new() { Direction.Down }}, { GestureState.Up , new(){ Direction.Up }}, { GestureState.Left , new() { Direction.Left }}, { GestureState.Right , new() { Direction.Right }}, { GestureState.DownLeft , new() { Direction.Down, Direction.Left}}, { GestureState.DownRight , new() { Direction.Down,Direction.Right }}, { GestureState.UpLeft , new() { Direction.Up,Direction.Left }}, { GestureState.UpRight , new() { Direction.Up,Direction.Right }}, { GestureState.LeftDown , new() { Direction.Left, Direction.Down }}, { GestureState.LeftUp , new() { Direction.Left, Direction.Up }}, { GestureState.RightDown , new() {Direction.Right, Direction.Down }}, { GestureState.RightUp , new(){Direction.Right, Direction.Up }}, };
匹配路徑
private GestureState MatchGesture() { var state = GestureState.Invalid; foreach (var gesture in Gestures) { if (gesture.Value.SequenceEqual(_curDirections)) { state = gesture.Key; break; } } return state; }
小結(jié)
直線手勢比較簡單,后續(xù)會繼續(xù)研究進(jìn)階手勢,如曲線,異性等手勢,歡迎交流!
到此這篇關(guān)于unity中實(shí)現(xiàn)Edge瀏覽器鼠標(biāo)手勢的功能的文章就介紹到這了,更多相關(guān)unity Edge瀏覽器鼠標(biāo)手勢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
剖析設(shè)計模式編程中C#對于組合模式的運(yùn)用
這篇文章主要介紹了設(shè)計模式編程中C#對于組合模式的運(yùn)用,理論上來說組合模式包含抽象構(gòu)件、樹葉構(gòu)件和樹枝構(gòu)件三個角色,需要的朋友可以參考下2016-02-02