unity中实现Edge浏览器鼠标手势的功能
2023-12-18 05:12:32
概要
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;
}
小结
直线手势比较简单,后续会继续研究进阶手势,如曲线,异性等手势,欢迎交流!
文章来源:https://blog.csdn.net/weixin_43559607/article/details/132753279
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!