【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类型的位置是从左上角顶点算起的,而且其旋转中心也位于左上角。

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

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

相关推荐
BW.SU8 天前
单片机 + 图像处理芯片 + TFT彩屏 指示灯控件
单片机·嵌入式硬件·人机交互·控件·触摸屏设计·指示灯·液晶屏
mozun202010 天前
QT:qt5调用打开exe程序并获取调用按钮控件实例2025.5.7
开发语言·数据库·qt·测试用例·控件·外部调用
Amctwd11 天前
【Godot】生命周期详解:从节点诞生到销毁的全流程解析
服务器·godot
冰茶_13 天前
WPF之Frame控件详解
学习·microsoft·微软·c#·wpf·控件
冰茶_13 天前
WPF之ScrollViewer控件详解
学习·microsoft·微软·c#·wpf·控件
冰茶_17 天前
WPF TextBlock控件性能优化指南
学习·性能优化·wpf·控件
Tandy12356_18 天前
Godot开发2D冒险游戏——第三节:游戏地图绘制
游戏引擎·godot
大佛拈花20 天前
Godot学习-3D基本环境设置以及3D角色移动
学习·3d·godot
胜天半子_王二_王半仙21 天前
godot源码编译
游戏引擎·godot
Tandy12356_21 天前
Godot开发2D冒险游戏——第二节:主角光环整起来!
游戏引擎·godot