【Godot4.2】实现鼠标控制对象(控件)旋转

概述

在一些情况下我们可能需要使用鼠标控制对一个图形或对象(如控件)进行旋转。

通过如下图的分析:

我们可以知道:

  • 我们只需要求出对象(如控件)中心点C到鼠标点击的位置start的向量与中心点C到鼠标移动后的位置start的向量之间的夹角θ
  • 然后将这个角度加到对象(如控件)的rotation属性上就可以了。

测试

原理清楚,实践开始。我们创建一个如下的UI场景:

为Control节点添加如下代码:

swift 复制代码
extends Control

@export var border_color = Color.YELLOW_GREEN
@export var border_width = 2

var rect = get_draw_safety_rect()


func _draw():
	# 绘制边框和对角线
	draw_rect(rect,border_color,false,border_width)
	draw_line(rect.position,rect.position+rect.size,border_color,border_width)
	draw_line(rect.position+Vector2(rect.size.x,0),rect.position++Vector2(0,rect.size.y),border_color,border_width)


# 获取绘制函数能正确使用的控件Rect2
func get_draw_safety_rect() -> Rect2:
	var rect = get_rect()
	return Rect2(rect.position - position,rect.size/scale)

它主要是绘制出控件的矩形边界,并绘制出对角线:

为根节点添加如下代码:

swift 复制代码
extends Control

@onready var control = $Control
@export var line_color = Color.YELLOW  # 辅助线颜色

var can_rotate:bool        # 是否处于旋转状态
var start_vector:Vector2   # 起始向量
var line:Array[Vector2] = []   # 记录辅助线


func _input(event):
	# 鼠标左键
	if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_LEFT:
			if event.is_pressed(): # 按下
				# 开启旋转状态
				can_rotate = true
				
				# 计算和记录初始控件中心到鼠标位置的向量
				var pos = event.position
				var c = control.position + control.pivot_offset
				start_vector = pos - c
				# 构造控件中心到鼠标位置的线段
				line.clear()
				line.append(c)
				line.append(pos)
				# 申请重绘
				queue_redraw()
			else: # 松开
				# 关闭旋转状态
				can_rotate = false
				# 申请重绘
				queue_redraw()
	# 鼠标移动
	if event is InputEventMouseMotion:
		# 如果是可旋转状态
		if can_rotate:
			# 计算和新的控件中心到鼠标位置的向量
			var pos = event.position
			var c = control.position + control.pivot_offset
			var end_vector:Vector2 = pos - c
			# control跟随鼠标旋转
			control.rotation += start_vector.angle_to(end_vector)
			# 将新的向量记录到start_vector
			start_vector = end_vector
			# 构造新的控件中心到鼠标位置的线段
			line.clear()
			line.append(c)
			line.append(pos)
			# 申请重绘
			queue_redraw()

func _draw():
	# 绘制控件中心到鼠标位置的线段
	if line.size()>0 and can_rotate:
		draw_line(line[0],line[1],line_color,1)

注意:默认情况下Control类型的位置是从左上角顶点算起的,而且其旋转中心也位于左上角。

所以我们需要手动或代码形式将其旋转中心设定为其矩形范围的中心。

运行后就可以使用鼠标控制控件进行旋转。

相关推荐
梦起丶8 天前
Qml 中实现时间轴组件
qt·ui·时间轴·控件·qml
梦起丶9 天前
Qml 中实现任意角为圆角的矩形
qt·ui·控件·qml
ChoSeitaku11 天前
No.1|Godot|俄罗斯方块复刻|棋盘和初始方块的设置
java·前端·godot
Moweiii14 天前
Godot Tween 补间动画探索
游戏引擎·godot·技术美术
Moweiii15 天前
Godot最佳实践个人转述
c#·游戏引擎·godot
利白1 个月前
我的Qt作品(20)使用Qt+OpenCV写一个旋转/抠图/mask生成工具
qt·opencv·旋转·抠图·mask
老大白菜1 个月前
Godot RPG 游戏开发指南
游戏引擎·godot
ChoSeitaku2 个月前
No.1 杀戮尖塔Godot复刻|项目概述|场景设置
游戏引擎·godot
Cici_ovo2 个月前
godot游戏引擎_瓦片集和瓦片地图介绍
游戏引擎·godot
峰度偏偏2 个月前
【适配】屏幕拖拽-滑动手感在不同分辨率下的机型适配
算法·游戏·unity·ue5·ue4·godot