Implement the function of Edge browser mouse gestures in unity

overview

In the Edge browser, you only need to hold down the right button of the mouse and drag it in different directions on the screen to trigger many shortcut operations, and the effect is very smooth. So if you want to use unity to develop such a function to support PC and mobile terminals, what should you do?

Implementation ideas

is actually not complicated to implement. The technical points involved include PC and mobile screen drag events, related operations of two-dimensional vectors, gesture matching algorithms, and event system design patterns.
The general idea is: define the mouse path as different event types, such as: "Up", "Down", "Left", "Right", and add adjacent non-duplicate path types to In a list, the sliding direction of the current frame and the previous frame is obtained through mouse events. If the direction deviates from the current direction range, it is judged that the mouse has turned during the sliding process, and the direction of each turning is recorded in a list. , the number of turns is determined according to the number of defined event mouse paths. If it exceeds this number, it will be judged as an invalid gesture. Finally, when the gesture is raised, it will match the defined event gesture path list and the gesture list recorded during the sliding process. If the match is successful, it will be judged. trigger event.

1. Mouse drag event

提示:移动端和pc端事件有所区别

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. Calculation of two-dimensional direction of mouse dragging

Get the direction vector of mouse drag

  	private Vector2 GetDragDirection()
    {
    
    
        var v = (Vector2)Input.mousePosition - _preMousePoint;
        return v.normalized;
    }

Calculating direction, currently only four directions are recognized: up, down, left, right, this method can be expanded to eight directions.

 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为上一帧的鼠标位置,此字段采集的频率建议不要太过频繁,不建议每帧采集,因为可能导致滑动速度过慢时存在噪点手势,影响事件结果

3. Match mouse gesture path

Record path direction

	private void UpdateGestures()
    {
    
    
        var dir = GetDirection();
        if (_preDirection != dir)
        {
    
    
            _preDirection = dir;
            _curDirections.Add(dir);
        }
    }

Define the event path. Here we only illustrate a maximum of two segments. The event path can be extended to multiple segments.

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

match path

private GestureState MatchGesture()
    {
    
    
        var state = GestureState.Invalid;
        foreach (var gesture in Gestures)
        {
    
    
            if (gesture.Value.SequenceEqual(_curDirections))
            {
    
    
                state = gesture.Key;
                break;
            }
        }

        return state;
    }

summary

Straight-line gestures are relatively simple. We will continue to study advanced gestures in the future, such as curves, opposite-sex gestures, etc. Welcome to communicate!

Guess you like

Origin blog.csdn.net/weixin_43559607/article/details/132753279