如何在工具模式下绘制 Shape2D?
How to draw a Shape2D in toolmode?
我正在使用 Physics2DServer
添加碰撞形状,如下所示:
Physics2DServer.body_add_shape(_body, _shape, Transform2D.IDENTITY, collision_disabled)
基于此
但我看不出是什么形状,
那么有没有办法在工具模式下绘制(并根据body移动它)?
这花了一点时间才弄清楚,但它实际上比我预期的要简单。第一个见解是 Shape2D
已经有一个 draw
方法,所以我们可以这样做:
shape.draw(get_canvas_item(), Color.darkblue)
或使用您喜欢的任何颜色。
这意味着我们可以制定一个通用的解决方案,而不是处理每一种形状。
我们可以利用 _draw
。为了使它无效,我们可以在每次更改时调用 update
。
顺便说一句,Resource
有一个“已更改”信号,所有 build-in 资源(对于自定义资源,您必须手动执行)在它们的状态发生变化时(如果您发现一个不这样做的,请举报)。
所以我们有这个:
tool
extends Node2D
export var shape:Shape2D setget set_shape
func _draw() -> void:
if not Engine.editor_hint:
return
if shape == null:
return
shape.draw(get_canvas_item(), Color.darkblue)
func set_shape(new_value:Shape2D) -> void:
if shape == new_value:
return
if shape != null and shape.is_connected("changed", self, "update"):
shape.disconnect("changed", self, "update")
shape = new_value
if shape != null and not shape.is_connected("changed", self, "update"):
shape.connect("changed", self, "update")
update()
缺点是我们无法配置它在自定义位置绘制Shape2D
(它将在Node2D
的局部坐标原点绘制)。 而且,不,我们不能作弊。
但是,我们可以通过 VisualServer
创建一个 canvas 项目来定位它。此设置可能看起来很熟悉:
var canvas_item:RID
var invalid_rid:RID
func _enter_tree() -> void:
canvas_item = VisualServer.canvas_item_create()
VisualServer.canvas_item_set_parent(canvas_item, get_canvas_item())
func _exit_tree() -> void:
VisualServer.canvas_item_clear(canvas_item)
canvas_item = invalid_rid
func _draw() -> void:
if not Engine.editor_hint:
return
if shape == null:
return
shape.draw(canvas_item, Color.darkblue)
要移动它,我们可以设置它的变换,如下所示:
export var offset:Vector2 setget set_offset
func set_offset(new_value:Vector2) -> void:
if offset == new_value:
return
offset = new_value
VisualServer.canvas_item_set_transform(
canvas_item,
Transform2D.IDENTITY.translated(offset)
)
我正在使用 Physics2DServer
添加碰撞形状,如下所示:
Physics2DServer.body_add_shape(_body, _shape, Transform2D.IDENTITY, collision_disabled)
基于此
但我看不出是什么形状,
那么有没有办法在工具模式下绘制(并根据body移动它)?
这花了一点时间才弄清楚,但它实际上比我预期的要简单。第一个见解是 Shape2D
已经有一个 draw
方法,所以我们可以这样做:
shape.draw(get_canvas_item(), Color.darkblue)
或使用您喜欢的任何颜色。
这意味着我们可以制定一个通用的解决方案,而不是处理每一种形状。
我们可以利用 _draw
。为了使它无效,我们可以在每次更改时调用 update
。
顺便说一句,Resource
有一个“已更改”信号,所有 build-in 资源(对于自定义资源,您必须手动执行)在它们的状态发生变化时(如果您发现一个不这样做的,请举报)。
所以我们有这个:
tool
extends Node2D
export var shape:Shape2D setget set_shape
func _draw() -> void:
if not Engine.editor_hint:
return
if shape == null:
return
shape.draw(get_canvas_item(), Color.darkblue)
func set_shape(new_value:Shape2D) -> void:
if shape == new_value:
return
if shape != null and shape.is_connected("changed", self, "update"):
shape.disconnect("changed", self, "update")
shape = new_value
if shape != null and not shape.is_connected("changed", self, "update"):
shape.connect("changed", self, "update")
update()
缺点是我们无法配置它在自定义位置绘制Shape2D
(它将在Node2D
的局部坐标原点绘制)。 而且,不,我们不能作弊。
但是,我们可以通过 VisualServer
创建一个 canvas 项目来定位它。此设置可能看起来很熟悉:
var canvas_item:RID
var invalid_rid:RID
func _enter_tree() -> void:
canvas_item = VisualServer.canvas_item_create()
VisualServer.canvas_item_set_parent(canvas_item, get_canvas_item())
func _exit_tree() -> void:
VisualServer.canvas_item_clear(canvas_item)
canvas_item = invalid_rid
func _draw() -> void:
if not Engine.editor_hint:
return
if shape == null:
return
shape.draw(canvas_item, Color.darkblue)
要移动它,我们可以设置它的变换,如下所示:
export var offset:Vector2 setget set_offset
func set_offset(new_value:Vector2) -> void:
if offset == new_value:
return
offset = new_value
VisualServer.canvas_item_set_transform(
canvas_item,
Transform2D.IDENTITY.translated(offset)
)