为什么在Godot中信号对我不起作用?

huangapple go评论59阅读模式
英文:

Why are signals not working for me in Godot?

问题

I understand that you'd like a translation of the code you provided. Here's the translated code:

我试图创建一个带有棋子的棋盘。显然,棋子需要移动,这就涉及到信号。我有一个名为drag_piece的脚本,它看起来像这样。

extends Area2D

var selected = false

func _ready():
	input_event.connect(when_held)

func _process(delta):
	if selected:
		followMouse()

func followMouse():
	position = get_global_mouse_position()

func when_held(viewport, event, shape_idx):
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
		if event.pressed:
			selected = true
		else:
			selected = false

这个脚本单独运行正常,但当我需要通过脚本创建Area2D节点时,出现问题,代码如下:

var piece_area2D = Area2D.new();
piece_area2D.name = piece_name + str(rank) + str(file)
var drag_script = load("res://scripts/drag_piece.gd")
piece_area2D.set_script(drag_script)
var piece_sprite = Sprite2D.new()
var piece_collision = CollisionShape2D.new()
var collision_shape = RectangleShape2D.new()
collision_shape.size = Vector2(64, 64)

piece_collision.set_shape(collision_shape)

var spritelocation = "res://images/pieces/" + piece_color + piece_name + ".png"
piece_sprite.texture = load(spritelocation)
piece_area2D.position = Vector2((rank * 64) - (64 / 2),(file * 64) - (64 / 2))
piece_sprite.scale = Vector2(1, 1)
piece_sprite.z_index = 1

这不是完整的脚本。除了当我按住左键时棋子不会被拖动之外,一切都正常运行。

我尝试在_ready函数中添加一个打印语句,打印"works",以确保脚本运行正常,它确实打印了出来,所以我真的不知道问题在哪里。我阅读了Godot关于信号的文档并在Google上搜索了一个小时多,但没有找到解决办法。

英文:

I'm trying to create a chess board with pieces. Obviously the pieces will need to move and that's where signals come in. I have a drag_piece script that looks like this.

extends Area2D

var selected = false

func _ready():
	input_event.connect(when_held)

func _process(delta):
	if selected:
		followMouse()

func followMouse():
	position = get_global_mouse_position()

func when_held(viewport, event, shape_idx):
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
		if event.pressed:
			selected = true
		else:
			selected = false

The script works fine by itself but the problem comes when I need to create area2D nodes through script like this:

var piece_area2D = Area2D.new();
	piece_area2D.name = piece_name + str(rank) + str(file)
	var drag_script = load("res://scripts/drag_piece.gd")
	piece_area2D.set_script(drag_script)
	var piece_sprite = Sprite2D.new()
	var piece_collision = CollisionShape2D.new()
	var collision_shape = RectangleShape2D.new()
	collision_shape.size = Vector2(64, 64)
	
	piece_collision.set_shape(collision_shape)
	
	var spritelocation = "res://images/pieces/" + piece_color + piece_name + ".png"
	piece_sprite.texture = load(spritelocation)
	piece_area2D.position = Vector2((rank * 64) - (64 / 2),(file * 64) - (64 / 2))
	piece_sprite.scale = Vector2(1, 1)
	piece_sprite.z_index = 1

This is not the entire script. Everything works fine besides the pieces dragging when i hold down left click.

I tried adding a print statement in the ready function that prints "works" so I know that the script is working fine, and it did print it so I really don't know what the problem is. I read the Godot documentation on signals and searched google for a good hour and something and haven't found anything.

答案1

得分: 1

  1. 你不需要连接 input_event 到相同的对象,你可以代替重写 _input_event

    例如:

    func _input_event(viewport, event, shape_idx):
        if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
            if event.pressed:
                selected = true
            else:
                selected = false
    
  2. get_global_mouse_position 是一个全局位置,将其设置为 global_position 而不是 position

    像这样:

    global_position = get_global_mouse_position()
    

    本地坐标可能已经与全局坐标对齐,但这不是保证的。

  3. 你可以通过创建一个场景并实例化它来简化 Area2D 的创建。

    你可以像这样从代码中实例化一个场景:

    Godot 4

    var instance = load("res://path/to/the/scene.tscn").instantiate()
    

    Godot 3

    var instance = load("res://path/to/the/scene.tscn").instance()
    

    你的场景可以设置脚本、碰撞器、纹理等等。

  4. 你是否将 Area2D 添加到了场景中?你所展示的代码只是创建它们。

    可能你会使用 add_child

    add_child(instance)
    
英文:
  1. You don't need to connect input_event to the same object, you can instead override _input_event.

    For example:

    func _input_event(viewport, event, shape_idx):
        if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
            if event.pressed:
                selected = true
            else:
                selected = false
    
  2. get_global_mouse_position is a global position, set it to global_position not position.

    Like this:

    global_position = get_global_mouse_position()
    

    The local coordinates might have been aligned with the global coordinates for you, but that is not guaranteed.

  3. You could simplify the Area2D creation by making an scene and instantiating it.

    You can instantiate an scene from code like this:

    Godot 4

    var instance = load("res://path/to/the/scene.tscn").instantiate()
    

    Godot 3

    var instance = load("res://path/to/the/scene.tscn").instance()
    

    Your scene can have the script set, the collider, the texture, etc.

  4. Did you add the Area2D to the scene? The code you showed only creates them.

    Presumably you would use add_child:

    add_child(instance)
    

huangapple
  • 本文由 发表于 2023年6月13日 01:15:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76458925.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定