如何通过屏幕任意位置手指划圆实现角色绕垂直轴旋转?
任意位置划圆控制角色绕垂直轴旋转实现方案
现有方案问题说明
- 第一种射线检测方案:要求拖动位置必须围绕角色在屏幕上的投影,无法支持任意屏幕位置操作,不符合需求
- 第二种ScreenDrag方案:直接累加x/y轴偏移值,无法识别划圆的方向,只能单一方向旋转
核心实现思路
通过记录拖动手势的连续坐标点,计算相邻两次拖动偏移向量的叉积,判断划圆的方向(顺时针/逆时针),结合划动的速度计算角色Y轴旋转量,实现任意位置划圆控制角色旋转的效果。
完整实现代码
成员变量定义
# 旋转速度系数,可根据实际需求调整快慢 var rot_speed: float = 0.02 # 存储上一帧触摸坐标 var last_touch_pos: Vector2 = Vector2.ZERO # 拖动状态标记 var is_dragging: bool = false
输入事件处理逻辑
func _input(event): # 处理触摸按下事件,记录初始状态 if event is InputEventScreenTouch and event.pressed: is_dragging = true last_touch_pos = event.position return # 处理触摸抬起事件,重置状态 if event is InputEventScreenTouch and not event.pressed: is_dragging = false return # 处理拖动事件,计算旋转参数 if event is InputEventScreenDrag and is_dragging: var current_pos = event.position # 计算当前帧相对于上一帧的划动偏移 var delta_vec = current_pos - last_touch_pos # 计算以屏幕中心为原点的两个相邻坐标向量,消除位置影响,支持任意区域划圆 var screen_center = get_viewport().get_visible_rect().size / 2 var last_vec = last_touch_pos - screen_center var current_vec = current_pos - screen_center # 2D向量叉积判断旋转方向:结果为正代表逆时针划动,为负代表顺时针划动 var cross_value = last_vec.cross(current_vec) var rot_dir = sign(cross_value) # 结合划动距离计算旋转幅度 var rot_delta = delta_vec.length() * rot_speed * rot_dir # 执行绕自身垂直轴旋转逻辑 rotate_y(rot_delta) # 更新上一帧触摸坐标 last_touch_pos = current_pos
优化建议
- 可增加划动距离阈值,仅当
delta_vec.length()大于设定值时执行旋转逻辑,避免小幅度误触 - 如需支持多指操作,可增加触摸点index判断,避免多手指同时操作冲突
- 可根据划圆的线速度动态调整旋转速度,提升操作跟随感
内容的提问来源于stack exchange,提问作者Limbard
相关产品推荐
相关产品推荐

