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

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

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

相关推荐
代码盗圣15 天前
GODOT 4 不用scons编译cpp扩展的方法
游戏引擎·godot
知兀1 个月前
单例模式(自动加载)
笔记·游戏引擎·godot
知兀1 个月前
Godot中的信号
笔记·游戏引擎·godot
知兀1 个月前
【godot游戏引擎学习笔记】初识界面
笔记·游戏引擎·godot
知兀1 个月前
Godot中类和静态类型
笔记·游戏引擎·godot
知兀1 个月前
编辑器、节点树、基础设置
笔记·游戏引擎·godot
foxgod1 个月前
QT + opengl 让2d贴图动起来
qt·opengl·旋转
巽星石2 个月前
【Godot4.3】匀速和匀变速直线运动粒子
godot·物理·加速度·速度曲线
巽星石2 个月前
【Godot4.3】基于中心点连线的矩形重叠检测
godot·gdscript·碰撞·图形
巽星石2 个月前
【Godot4.3】自定义数列类NumList
godot·gdscript·斐波那契·数列