Godot中双击单个物品实例却触发全部实例信号的问题及解决
问题原因与解决方案
为什么双击单个实例会触发所有实例?
你给每个物品实例都绑定了_input函数,这个函数是全局输入监听——只要游戏里发生左键双击事件,所有物品实例都会执行这段代码,不管点击的是不是自己,所以才会出现所有实例都输出信息、发送信号的情况。
解决方法:只响应自身被点击的事件
推荐用Godot内置的节点输入回调来实现,有两种常用方式:
方法1:使用_input_event(推荐)
这个函数只会在点击到当前节点时触发,需要你的物品节点带有碰撞体(比如Area2D、StaticBody2D),并且开启Pickable选项:
- 确保物品节点结构包含碰撞体(比如
Area2D下挂CollisionShape2D,并设置好匹配物品大小的碰撞形状) - 在检查器里找到碰撞体节点的
Input选项,勾选Pickable - 把原代码的
_input替换成_input_event:
func _input_event(viewport, event, shape_idx): if event is InputEventMouseButton: # 只在双击按下时触发,避免重复响应松开事件 if event.button_index == MOUSE_BUTTON_LEFT and event.double_click and event.pressed: print(self.type, " (", self.position.x, ", ", self.position.y, ")") move_to_pickup.emit(self)
方法2:在_input里手动判断点击位置
如果不想用_input_event,可以在全局输入监听里手动检查鼠标是否点击在当前物品的范围内:
func _input(event): if event is InputEventMouseButton: if event.button_index == MOUSE_BUTTON_LEFT and event.double_click and event.pressed: # 将全局鼠标位置转换为当前节点的本地坐标 var local_mouse_pos = to_local(get_global_mouse_position()) # 验证鼠标位置是否在碰撞形状覆盖范围内 if $CollisionShape2D.shape.has_point(local_mouse_pos): print(self.type, " (", self.position.x, ", ", self.position.y, ")") move_to_pickup.emit(self)
内容的提问来源于stack exchange,提问作者Michael Teasdale
相关产品推荐
相关产品推荐

