Godot - dibujar sin reglas

A veces sucede que el motor simplemente limita el flujo interminable de ideas. Entonces, una vez quise dibujar desde cualquier lugar, cualquier cosa y en cualquier lugar. Esto es lo que se discutirá.





Para empezar, imaginemos una tarea tan trivial: al hacer clic con el mouse, debe dibujar alguna primitiva que el usuario especifique, por ejemplo, presionando teclas. Suena simple, pero con Godot puede ser un dolor de cabeza.





, : Godot _draw



CanvasItem



, .. , , , _process



. , , _draw



, . . , ? ? ? .





– «» . Godot – , - , . godot API , – VisualServer



. ( ) Godot. , , VisualServer



.





CanvasItem



- , , ? , . RID



(Resource ID), World2D



. CanvasItem



get_canvas_item()



, , _draw



. , , :





: Controller



Drawer



.





"" , . Controller



:





extends Node2D

onready var drawer = $"../Drawer"

var counter = 0

func custom_draw_line(start, goal, color, width=1.0, antialising=false):
	VisualServer.canvas_item_add_line(drawer.get_canvas_item(), start, goal, color, width, antialising)

func _process(delta):
	if Input.is_action_just_pressed("mouse_left"):
		counter += 2
		custom_draw_line(Vector2(100, 100)+Vector2(counter, counter), Vector2(300, 150)+Vector2(counter, counter), Color.green)
      
      



custom_draw_line(...)



, VisualServer



canvas_item_add_line(...)



, Drawer



. , Controller



, , , .





, . , , . ? Godot, . , :





void CanvasItem::_update_callback() {
	if (!is_inside_tree()) {
		pending_update = false;
		return;
	}

	RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item());
	//todo updating = true - only allow drawing here
	if (is_visible_in_tree()) { //todo optimize this!!
		if (first_draw) {
			notification(NOTIFICATION_VISIBILITY_CHANGED);
			first_draw = false;
		}
		drawing = true;
		current_item_drawn = this;
		notification(NOTIFICATION_DRAW);
		emit_signal(SceneStringNames::get_singleton()->draw);
		if (get_script_instance()) {
			get_script_instance()->call(SceneStringNames::get_singleton()->_draw);
		}
		current_item_drawn = nullptr;
		drawing = false;
	}
	//todo updating = false
	pending_update = false; // don't change to false until finished drawing (avoid recursive update)
}
      
      



7:





RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item())
      
      



, . , .. , . , Drawer



. VisualServer.canvas_item_create()



, , , , World2D.canvas



( "" ) .. Drawer



, . VisualServer



VisualServer.canvas_item_set_parent(item, parent)



. : , . , , . :VisualServer.canvas_item_clear(surface)



. :





extends Node2D

onready var drawer = $"../Drawer"

var counter = 0

var surface

func _ready():
	surface = VisualServer.canvas_item_create()
	VisualServer.canvas_item_set_parent(surface, drawer.get_canvas_item())

func custom_draw_line(start, goal, color, width=1.0, antialising=false):
	VisualServer.canvas_item_add_line(surface, start, goal, color, width, antialising)

func _process(delta):
	if Input.is_action_just_pressed("mouse_left"):
		counter += 2
		custom_draw_line(Vector2(100, 100)+Vector2(counter, counter), Vector2(300, 150)+Vector2(counter, counter), Color.green)
	elif Input.is_action_just_pressed("mouse_right"):
		VisualServer.canvas_item_clear(surface)
		counter = 0
      
      



, . , Drawer



, .





, , . , CanvasItem



, CanvasItem



( ):





void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width) {
	ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");

	RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
}
      
      



4, VisualServer



, , .





? , .. - , . , Resource



, . , , .





, , . , " ". , , ( ), , " ", .





- , . , .





, .. .





, , . , , _draw



CanvasItem



. , 3D , , , .





. : , Godot . , !








All Articles