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

概述

在一些情况下我们可能需要使用鼠标控制对一个图形或对象(如控件)进行旋转。
通过如下图的分析:
image.png
我们可以知道:

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

测试

原理清楚,实践开始。我们创建一个如下的UI场景:
image.png
为Control节点添加如下代码:

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)

它主要是绘制出控件的矩形边界,并绘制出对角线:
image.png
为根节点添加如下代码:

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类型的位置是从左上角顶点算起的,而且其旋转中心也位于左上角。
image.png
所以我们需要手动或代码形式将其旋转中心设定为其矩形范围的中心。
image.png
运行后就可以使用鼠标控制控件进行旋转。
鼠标控制矩形旋转.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巽星石

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值