Godot的RichTextLabel富文本标签,鼠标拖拽滚动,方向键滚动,底部吸附,自动滚动

零、godot介绍

Godot 是一款游戏引擎软件,可以用来写游戏

中文界面,中文文档,MIT开源,免费使用全部功能,无分成,跨平台,轻量,不会下架(因为没上架)

官网链接:https://godotengine.org/zh-cn/

文档链接:https://docs.godotengine.org/zh-cn/

一、下载godot

二、软件安装

在电脑硬盘空间里找个地方创建GodotSoftware文件夹用来放置godot本体,例如参考以下目录结构

bash 复制代码
Godot/
├── _rcedit/
│   └── rcedit-x64.exe
├── _导出模板/
│   └── Godot_v4.4.1-stable_export_templates.tpz
├── _导出位置/
│   ├── Windows/
│   └── Android/
├── _静态Web服务器软件/
│   └── ran_windows_amd64.exe
├── _素材/
│   ├── images/
│   ├── audio/
│   ├── shader/
│   └── fonts/
├── _文档/
│   └── XX文档.pdf
├── GodotSoftware/
│   └── Godot_v4.4.1-stable_win64.exe
└── GodotProjects/
    ├── Project_Game1/
    │   ├── .godot/
    │   ├── scenes/
    │   ├── scripts/
    │   └── res/
    └── Project_Game2/
        ├── .godot/
        ├── scenes/
        ├── scripts/
        └── res/

三、创建项目

  • 1 运行Godot_v4.4.1-stable_win64.exe

  • 2 点击创建或者新建项目

  • 3 项目名称

    输入框项目名称:可拖拽的富文本标签

  • 4 设置项目路径

    (GodotProjects文件夹要点进去,如果不点进去godot的最近使用就会记录成父文件夹)

  • 5 设置版本控制

    选择

  • 6 创建完成

    点击创建按钮,创建完成

四、创建RichTextLabel

  • 1 创建:

    使用场景面板,点击其他节点,输入rich找到并选中RichTextLabel,点击创建按钮

  • 2 保存
    *符号表示这个场景没有保存

    点击场景 - 保存场景,在弹出场景另存为...窗口中直接点击保存按钮即可

  • 3 确认保存

    左下角文件系统多了一个rich_text_label.tscn,这就是已保存的场景文件

五、切换编辑器界面

在godot窗口正上方,有五个选项,分别是 2D 3D 脚本代码 游戏结果预览 资源库

点击并切换到2D,这样才能查看创建的RichTextLabel长什么样子

六、缩放2D预览窗口

在"红框圈住的区域"滚动鼠标滚轮直到绿框内的数值比较低,比如(18.0%)

粉色#cb3950横线,绿色#78b315竖线,紫色#565694方框,这些线组成的方框就是最终玩家看到的区域

七、设置RichTextLabel的锚点预设

  • 1 在左侧场景树中点击选中RichTextLabel后,在2D预览界面会看到一堆控制手柄
  • 2 设置锚点(这个按钮在视图按钮附近)

点击锚点预设设置按钮将 RichTextLabel 的锚点设置为整个矩形

按快捷键Ctrl+S保存

  • 3 效果截图:

八、设置 RichTextLabel 中的文本内容

  • 1 勾选启用BBCode

  • 2 点击展开按钮显示一个更大的输入框更容易编辑
    (注意:如果整个Godot窗口怎么点都没反应,说明你把这个输入框弹窗最小化到左下角了)

    输入以下内容

    [b]加粗[/b][i]斜体[/i][u]下划线文本[/u][s]删除线文本[/s][color=aqua]青色文本[/color][color=maroon]深红色文本[/color][color=teal]蓝绿色文本[/color]
    [color=6cf]自定义颜色(十六进制)[/color][color=6cf8]半透明颜色(带alpha通道的十六进制)[/color]
    [code][color=e3e3e3][color=bf67ff]function[/color] [color=7cacf8]show_alert/color { alert([color=fe8d59]"代码字体"[/color]); }[/color][/code]
    [url=https://godotengine.org/zh-cn/]Godot官网[/url] [url={"action": "open_url", "url": "https://godotengine.org/zh-cn/"}] JSON式链接[/url]url需要配合 meta_clicked 信号点击才有用
    [font_size=24]大号字体文本[/font_size]
    [left]左对齐文本[/left]
    [center]居中对齐文本[/center]
    [right]右对齐文本[/right]

    [wave amp=30 freq=1][b][color=ff0000]波浪效果文本,上下波动显示。[/color][/b][/wave]
    [tornado radius=20 freq=1][i][color=0000ff]旋风效果文本,在圆圈内旋转显示。[/color][/i][/tornado]
    [shake rate=3 level=15][u][color=008000]抖动效果文本,摇晃显示。[/color][/u][/shake]
    [rainbow freq=0.5 sat=15 val=20][b]彩虹效果文本,随时间变化颜色。[/b][/rainbow]
    [fade start=2 length=10][i][color=800080]渐隐效果文本,部分字符逐渐消失。[/color][/i][/fade]
    [pulse color=#00FFAA height=5.0 freq=1.5][b]这是脉冲效果文本,文字上下脉动并改变颜色。[/b][/pulse]

    [img]res://icon.svg[/img][img color=333]res://icon.svg[/img][img=100]res://icon.svg[/img][img tooltip="嘿嘿嘿"]res://icon.svg[/img]
    [img=100x1000]res://icon.svg[/img]

按快捷键Ctrl+S保存

  • 3 最终效果:

九、设置项目窗口大小(窗口太大截图就大,文章里的图就会缩小变糊)

点击项目-项目设置

在项目设置中,将显示 - 窗口 - 视口宽度设置为700,将显示 - 窗口 - 视口高度设置为400

(一般情况下,高级设置是要打开的,但是这次无所谓)

十、运行当前场景

(运行场景时,场景和脚本会自动保存)

右上角,按F6或者按按钮运行当前场景

运行结果:

关闭展示的DEBUG窗口

十一、添加脚本

  • 1 添加脚本
    1.1 右键RichTextLabel,点击添加脚本选项

    1.2 或者选中RichTextLabel,直接点击添加脚本图标
  • 2 创建脚本
    在"设置节点的脚本"窗口中直接点击创建即可
  • 3 效果截图
    文件系统新出现了一个rich_text_label.gd脚本文件
  • 4 折叠输出面板
    在窗口底部,将输出点成白色(按快捷键Alt+O)
  • 5 折叠脚本文件名面板
    在窗口底部,点击左箭头开关脚本面板(快捷键Ctrl+)
  • 6 按快捷键Ctrl+S保存

十二、编写脚本(RichTextLabel的链接点击功能)

  • 1 连接信号
    选中RichTextLabel,右侧属性面板找到节点 - 信号
    点击连接...按钮(或者双击meta_clicked(meta: Variant))

    在"连接信号到方法"窗口直接点击连接按钮即可
  • 2 连接效果:
    红框处的图标表明:这个方法和信号连接了,不能随便删除(可以信号断开之后再删除)
  • 3 修改res://rich_text_label.gd
python 复制代码
extends RichTextLabel

func _ready() -> void:
	add_godot_doc_link()
	pass

func _on_meta_clicked(meta: Variant) -> void:
	# BBCode 不支持字典类型,会以字符串形式存储,需要手动解析。
	# 想要字典类型可以使用 push_meta 方法
	if meta is Dictionary:
		print("meta is Dictionary")
		var meta_recv_dict = meta as Dictionary
		if meta_recv_dict.has_all(["action", "url"]) and meta_recv_dict.action == "open_url":
			OS.shell_open(str(meta_recv_dict.url))
		else:
			print("字典中缺键")
	else:
		var json = JSON.new()
		var error = json.parse(meta)
		if error == OK:
			# 解析json
			var meta_recv = json.data
			if typeof(meta_recv) == TYPE_DICTIONARY:
				var meta_recv_dict = json.data as Dictionary
				if meta_recv_dict.has_all(["action", "url"]) and meta_recv_dict.action == "open_url":
					OS.shell_open(str(meta_recv_dict.url))
				else:
					print("字典中缺键")
			else:
				print("不是字典类型")
		else:
			# 直接当作网址字符串
			OS.shell_open(str(meta))

func add_godot_doc_link():
	add_text("\n")
	var doc_url_metadata = { "action": "open_url", "url": "https://docs.godotengine.org/zh-cn/" }
	push_meta(doc_url_metadata, RichTextLabel.META_UNDERLINE_ON_HOVER, "tooltip_random_VbJbHn")
	push_color("#59a1e0")
	add_text("点击访问godot文档")
	pop()
	pop()

按快捷键Ctrl+S保存

  • 4 查看效果:按F6运行当前场景,点击这三个url就会调用系统浏览器访问godot链接

  • 5 关闭展示的DEBUG窗口

  • 6 点击func左侧的折叠按钮折叠方法,折叠_on_meta_clickedadd_godot_doc_link

十三、编写脚本(RichTextLabel的鼠标拖拽滚动功能)

  • 1 写一个转换方法,将布尔值转换为正1或者-1方便后续计算
python 复制代码
# 根据方向标志返回乘数(-1 或 1)
func get_direction_multiplier(value: bool) -> int:
	return -1 if value else 1
  • 2 写一个控制滚动位置的方法
python 复制代码
func set_scroll_value(value: float, block_duration: float = 0.0) -> void:
	# 例:block_time可以使用0.01
	if block_duration > 0:
		# 阻塞这个函数一小段时间, 不然获取到的max_value是旧的
		await get_tree().create_timer(block_duration).timeout
	v_scroll_bar.value = clamp(value, v_scroll_bar.min_value, v_scroll_bar.max_value)
  • 3 鼠标拖拽用到的变量(一般写在_ready方法之前)

    鼠标拖拽

    @export var invert_drag_direction: bool = true
    @onready var v_scroll_bar = get_v_scroll_bar()
    var is_dragging: bool = false
    var drag_start_pos: Vector2 = Vector2.ZERO
    var scroll_value: float = 0.0

  • 4 连接信号
    选中RichTextLabel,连接gui_input(event: InputEvent)信号,方法_on_gui_input(event: InputEvent)

  • 5 写_on_gui_input方法

python 复制代码
func _on_gui_input(event: InputEvent) -> void:
	if event is InputEventMouseButton:
		if event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
			# 开始拖拽
			is_dragging = true
			drag_start_pos = event.position
			scroll_value = v_scroll_bar.value
		elif not event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
			# 结束拖拽
			is_dragging = false
	elif event is InputEventMouseMotion and is_dragging:
		# 拖拽中
		var deltay = event.position.y - drag_start_pos.y
		var new_value = scroll_value + deltay * get_direction_multiplier(invert_drag_direction)
		set_scroll_value(new_value)
  • 6 运行
    按F6运行当前场景
    RichTextLabel区域按下鼠标左键不松手,上下移动光标,然后松开鼠标左键
    效果展示(动图已压缩,能看出来鼠标拖拽好使就行):

十四、编写脚本(RichTextLabel的方向键滚动功能)

  • 1 创建方向键滚动用到的变量(一般写在_ready方法之前)
python 复制代码
# 方向键控制
@export var invert_key_direction: bool = false
var key_scroll_step: int = 10
var is_mouse_inside: bool = false
  • 2 复制粘贴这两个方法,下一步再连接信号(用来控制is_mouse_inside的真假)
python 复制代码
func _on_mouse_entered() -> void:
	is_mouse_inside = true

func _on_mouse_exited() -> void:
	is_mouse_inside = false

效果截图(func左侧没有连接图标,因为还没连接):

  • 3 连接信号
    选中RichTextLabel,找到并双击mouse_entered()信号,接收方法名正好是_on_mouse_entered,点击连接
    选中RichTextLabel,找到并双击mouse_exited()信号,接收方法名正好是_on_mouse_exited,点击连接
    已连接效果截图:
  • 4 在_input方法判断按键
python 复制代码
func _input(event: InputEvent) -> void:
	if event is InputEventKey and event.pressed and is_mouse_inside:
		var step = key_scroll_step
		if event.ctrl_pressed:
			step *= 50
		elif event.shift_pressed:
			step *= 10
		elif event.alt_pressed:
			step = 1
		if event.keycode == KEY_UP:
			var new_value = v_scroll_bar.value + (step * -1 * get_direction_multiplier(invert_key_direction))
			set_scroll_value(new_value)
		elif event.keycode == KEY_DOWN:
			var new_value = v_scroll_bar.value + (step * get_direction_multiplier(invert_key_direction))
			set_scroll_value(new_value)

十四、查看效果

  • 1 为了查看效果,新建一个场景并把RichTextLabel当作子场景
    场景 - 新建场景 - 其他节点
  • 2 选择VBoxContainer
  • 3 选中刚创建好的VBoxContainer节点,按F2重命名为Test_rtextP(有测试前缀,是RichTextLabel的父节点)
    右键Test_rtextP实例化子节点

    点击选择rich_text_label.tscn作为实例化的子节点
  • 4 再实例化一个子节点,选择rich_text_label.tscn,让Test_rtextP中包含两个RichTextLabel
    节点结构如图:
  • 5 切换到2D预览显示模式
    选中Test_rtextP,设置锚点预设为整个矩形

    同时选中Test_rtextP的两个子节点,在右侧的检查器中找到Control - layout - Custom Minimum Size
    y设置为180
    (检查器向下滚动大概2/3处)

  • 6 切换到2D预览显示模式查看效果
  • 7 按Ctrl+S将这个场景保存为test_rtext_p.tscn
  • 8 按F6运行当前场景
    随机按上方向键和下方向键,鼠标所在位置的富文本就会滚动
  • 9 关闭DEBUG窗口
    选中Test_rtextP的子节点RichTextLabel,点击在编辑器中打开

    选中RichTextLabel,点击打开脚本

十五、编写脚本(RichTextLabel的底部吸附功能)

  • 1 创建变量
python 复制代码
# 底部吸附滚动条
var random_append_text_timer = Timer.new()
var lock_bottom = true
var lock_bottom_threshold = 100
signal text_updated

Ctrl+S保存,右侧节点 - 信号就会多出来一个text_updated()信号(不保存其实也会显示)

  • 2 创建三个方法
python 复制代码
func add_rand_append_text_timer():
	add_child(random_append_text_timer)
	random_append_text_timer.timeout.connect(_on_random_append_text_Timer_timeout)
	random_append_text_timer.one_shot = true
	random_append_text_timer.start(randf_range(1.0, 2.0))

func _on_random_append_text_Timer_timeout():
	append_text("\n文本" + str(randf()))
	text_updated.emit()
	
	random_append_text_timer.wait_time = randf_range(1.0, 2.0)
	random_append_text_timer.start()

func _on_text_updated() -> void:
	if v_scroll_bar.max_value - v_scroll_bar.value < lock_bottom_threshold + size.y:
		set_scroll_value(v_scroll_bar.max_value, 0.01)
	# 文本量过大直接清空(超宽显示器?)
	if get_line_count() > 1000:
		text = ""
  • 3 连接信号
    在信号界面双击text_updated()信号,连接到_on_text_updated方法上
  • 4 修改_ready方法,把add_rand_append_text_timer填进去
python 复制代码
func _ready() -> void:
	add_godot_doc_link()
	add_rand_append_text_timer()
	pass
  • 5 按F6运行当前场景查看效果
    将文本手动滚动到底部,新加了文本之后就会自动滚动
    如果滚动位置离底部较远,则不会滚动
  • 6 注意:lock_bottom_threshold变量最好和新添加文本的高度有关,新添加文本高度过大,底部吸附就失效了

十六、编写脚本(RichTextLabel的自动滚动功能)

  • 1 创建变量
python 复制代码
# 自动滚动
@export var auto_scroll_speed_normal = 50
var auto_scroll_speed_fast = auto_scroll_speed_normal * 20
var auto_scroll_speed = auto_scroll_speed_normal
  • 2 创建方法(将auto_scroll方法写到_process中)
python 复制代码
func _process(delta: float) -> void:
	auto_scroll(delta)

func auto_scroll(delta) -> void:
	v_scroll_bar.value += auto_scroll_speed * delta
	if Input.is_action_just_pressed("ui_accept"):
		auto_scroll_speed = auto_scroll_speed_fast
	if Input.is_action_just_released("ui_accept"):
		auto_scroll_speed = auto_scroll_speed_normal
  • 3 按F6运行当前场景
    运行之后自动滚动
    如果按住空格,会用另一个更快的速度滚动("ui_accept"是godot内置的按键映射,其中一个触发按键就是空格)

十七、退出

🥳进行一个出的退操作

<>
<>
<>
<>
<>
<>

相关推荐
90后小陈老师1 天前
Unity教学 项目2 2D闯关游戏
游戏·unity·游戏引擎
噗噗夹的TA之旅1 天前
Unity Shader 学习20:URP LitForwardPass PBR 解析
学习·unity·游戏引擎·图形渲染·技术美术
nnsix1 天前
Unity ReferenceFinder插件 多选资源查找bug解决
unity·游戏引擎·bug
gzroy1 天前
Unity Shader Graph实现全息瞄准器
unity·游戏引擎
90后小陈老师1 天前
Unity教学 基础介绍
unity·游戏引擎
90后小陈老师1 天前
Unity教学 项目3 3D坦克大战
3d·unity·游戏引擎
秦奈1 天前
Unity复习学习随笔(五):Unity基础
学习·unity·游戏引擎
nnsix1 天前
Unity ReferenceFinder插件 窗口中选择资源时 同步选择Assets下的资源
java·unity·游戏引擎
ۓ明哲ڪ1 天前
Unity功能——关闭脚本自动编译(Unity2021.3)
unity·游戏引擎
90后小陈老师1 天前
Unity教学 项目4 3D求生枪手
3d·unity·游戏引擎