unity中实现Edge浏览器鼠标手势的功能思路详解

 更新时间:2023年12月18日 11:13:58   作者:安东尼王  
这篇文章主要介绍了unity中实现Edge浏览器鼠标手势的功能思路详解,实现起来其实并不复杂,涉及的技术点有pc端和移动端屏幕拖动事件,二维向量的相关运算,手势匹配算法,事件系统设计模式,需要的朋友可以参考下

概要

Edge浏览器中,只需要使用鼠标按住右键在屏幕上不同方向拖动,就可以触发很多快捷操作,效果很丝滑。那如果想使用unity开发这么一个功能,支持PC端和移动端,要怎么做呢?

实现思路

实现起来其实并不复杂,涉及的技术点有pc端和移动端屏幕拖动事件,二维向量的相关运算,手势匹配算法,事件系统设计模式。
大概思路是:定义鼠标路径为不同的事件类型,例如:“Up”,“Down”,“Left”,“Right”,将相邻不重复的路径类型添加到一个列表中, 通过鼠标事件,获取当前帧和上一帧的滑动方向,如果方向偏移当前方向范围,则判断为鼠标在滑动过程中发生了转折,将每次转折的方向记录到一个列表中,转折次数根据定义的事件鼠标路径数量而定,超出这个数量则判定为无效手势,最后当手势抬起时,匹配定义的事件手势路径列表和滑动过程中记录的手势列表,如果匹配成功则判定触发事件。

1.鼠标拖动事件

提示:移动端和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.鼠标拖动的二维方向计算

获取鼠标拖动的方向向量

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

计算方向,目前只识别上下左右四个方向,次方法可扩展为八个方向

 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.匹配鼠标手势路径

记录路径方向

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

定义事件路径,此处只示例最多两段路径,事件路径可以扩展多段

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

小结

直线手势比较简单,后续会继续研究进阶手势,如曲线,异性等手势,欢迎交流!

到此这篇关于unity中实现Edge浏览器鼠标手势的功能的文章就介绍到这了,更多相关unity Edge浏览器鼠标手势内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#用Activex实现Web客户端读取RFID功能的代码

    C#用Activex实现Web客户端读取RFID功能的代码

    由于要在Web项目中采用RFID读取功能,所以有必要开发Activex,一般情况下开发Activex都采用VC,VB等,但对这两块不是很熟悉,所以采用C#编写Activex的方式实现
    2011-05-05
  • C# MemoryStream类案例详解

    C# MemoryStream类案例详解

    这篇文章主要介绍了C# MemoryStream类案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • c# 获取照片的经纬度和时间的示例代码

    c# 获取照片的经纬度和时间的示例代码

    这篇文章主要介绍了c# 获取照片的经纬度和时间的示例代码,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下
    2020-11-11
  • C#引用类型作为方法的参数分析

    C#引用类型作为方法的参数分析

    这篇文章主要介绍了C#引用类型作为方法的参数分析,以实例的形式较为详细的分析了参数的传值问题,需要的朋友可以参考下
    2014-11-11
  • C#连接Oracle数据库字符串(引入DLL)的方式

    C#连接Oracle数据库字符串(引入DLL)的方式

    这篇文章主要给大家介绍了关于C#连接Oracle数据库字符串(引入DLL)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • C#中多线程调用方式的几种实现

    C#中多线程调用方式的几种实现

    本文主要介绍了C#中几种多线程调用方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09
  • 详解C# parallel中并行计算的四种写法总结

    详解C# parallel中并行计算的四种写法总结

    在C#中,parallel关键字可以用于并行计算。本文为大家总结了四种C# parallel并行计算的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-11-11
  • C#简单爬虫案例分享

    C#简单爬虫案例分享

    这篇文章主要为大家分享了C#简单爬虫案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • 基于WPF实现面包屑效果的示例代码

    基于WPF实现面包屑效果的示例代码

    这篇文章主要为大家详细介绍了如何基于WPF实现面包屑效果,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下
    2023-04-04
  • C# 脚本引擎RulesEngine的使用详解

    C# 脚本引擎RulesEngine的使用详解

    这篇文章主要介绍了C# 脚本引擎RulesEngine的使用方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下
    2021-02-02

最新评论