我有一个多人项目设置,目的是创建一款生存游戏。在这个生存游戏中,我有玩家库存、外部库存(例如箱子),并且玩家能够丢弃物品,并将物品从库存中取消实例化,将数据传输到服务器,然后使用其实例在服务器上实例化该对象。已保存特定属性。
我遇到的问题是服务器主机,掉落物品机制按预期工作。然而,当客户端加入服务器时(它们可以移动、与对象交互、拾取在运行时实例化的任何对象,并使用传输到服务器的数据“射击”其他玩家,然后“击中”客户端),并且客户端尝试放下一个项目,它会发出信号,但服务器不会接受它收到的数据,并且不会为任何人实例化该节点。
向服务器发出信号并发送数据的播放器代码:
> func _on_inventory_drop_slot_data(grabbed_slot_data) -> void:
>
> print_debug("Sending object to server.")
> drop_item.emit(grabbed_slot_data)
接收数据并将数据实例化为服务器上的节点的服务器代码:
> func _on_inventory_drop_slot_data(grabbed_slot_data) -> void:
> print_debug("Server is receiving object.")
> if grabbed_slot_data:
> print_debug(grabbed_slot_data)
> else:
> print_debug("no slot data")
> var pick_up = PickUp.instantiate()
> pick_up.slot_data = grabbed_slot_data
> pick_up.position = Vector3(0,10,0)
> add_child(pick_up)
根据我的理解,一旦一个项目在服务器端为每个人实例化,每个人都应该能够看到该对象,对吗?如果情况并非如此,我是否需要使用 MultiplayerSpawner 节点来实例化所有客户端上掉落的物品,就像处理玩家实例一样?
如果您想查看的话,这是完整的播放器代码。
> extends CharacterBody3D
>
> signal health_changed(health_value)
> signal drop_item(grabbed_slot_data)
>
> @onready var PickUp = preload("res://item/pickup/pickup.tscn")
>
> @onready var inventoryHUD = $PlayerInventory/InventoryHUD
> @onready var player_inventory = $PlayerInventory/InventoryHUD/Inventory
> @onready var inventorySubviewport = $PlayerInventory/InventoryHUD/Background/SubViewportContainer
> @onready var hot_bar_inventory = $PlayerInventory/InventoryHUD/Inventory/HotBarInventory
>
> @onready var interact_ray = $Rig/Skeleton3D/Waist/Spine/Torso/Head/InteractRay
> @onready var fpshealthbar = $Rig/Skeleton3D/Waist/Spine/Torso/FirstPersonHUD/Health
> @onready var tpshealthbar = $Rig/Skeleton3D/Waist/Spine/Torso/FirstPersonHUD/HealthBack
>
> @onready var camera = null
> @onready var fpscamera = $FPSCamera
> @onready var tpscamera = $TPSCamera
>
> @onready var anim_rig = $AnimationRig
> @onready var anim_arms = $AnimationArms
> @onready var anim_tpsc = $AnimationTPSC
> @onready var anim_weapon = $Weapon/AnimationWeapon
>
> @onready var head = $Rig/Skeleton3D/Waist/Spine/Torso/Head
> @onready var tpshead = $Rig/Skeleton3D/Waist/Spine/Torso/ThirdArmSpine/SpineToArm/ThirdArmUpper/ThirdArmMidsection/ThirdArmLower/ThirdCamera
> @onready var righthand = $Rig/Skeleton3D/Waist/Spine/Torso/RightShoulder/RightArmUpper/RightArmLower/RightHand
> @onready var rightpalm = $Rig/Skeleton3D/Waist/Spine/Torso/RightShoulder/RightArmUpper/RightArmLower/RightHand/RightPalm
> @onready var leftshoulder = $Rig/Skeleton3D/Waist/Spine/Torso/LeftShoulder
> @onready var rightshoulder = $Rig/Skeleton3D/Waist/Spine/Torso/RightShoulder
>
> @onready var weapon = $Weapon
> @onready var raycast = $Weapon/Yeetcast
> @onready var aimposition = $Weapon/aimposition
> @onready var muzzle_flash = $Weapon/MuzzleFlash
>
> @export var inventory_data: InventoryData
> @export var weapon_slot_1_data: InventoryDataEquip
> @export var weapon_slot_2_data: InventoryDataEquip
> @export var weapon_slot_3_data: InventoryDataEquipHeavy
> @export var mod_slot_1_data: InventoryDataEquipMod
> @export var mod_slot_2_data: InventoryDataEquipMod
> @export var mod_slot_3_data: InventoryDataEquipMod
>
> @onready var weapon_model_1 = null
> @onready var weapon_model_2 = null
> @onready var weapon_model_3 = null
>
> var weapon_1_id = null
> var weapon_2_id = null
> var weapon_3_id = null
>
> var SPEED = Globals.PlayerSpeed
> var CROUCHSPEED = Globals.PlayerCrouchSpeed
> var CRAWLSPEED = Globals.PlayerCrawlSpeed
> var SPRINTSPEED = Globals.PlayerSprintSpeed
> var JUMPSPEED = Globals.PlayerJumpSpeed
>
> var gravity = Globals.PlayerGravity
> var health: int = Globals.PlayerHealth
> var PlayerInQuestion = Globals.PlayerInQuestion
> #var damage: int = slot_data.item_data_equip.attack_value
>
> var equipped_weapon_1 = false
> var equipped_weapon_2 = false
> var equipped_weapon_3 = false
>
> var freelook = false
> var crouching = false
> var sprinting = false
> var crawling = false
> var walking = false
> var shooting = false
> var aiming = false
> var inspecting = false
> var pausing = false
> var inventory = false
> var collections = false
>
> func _enter_tree():
>
> set_multiplayer_authority(str(name).to_int())
>
> func _ready():
>
> if not is_multiplayer_authority(): return
> Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
> camera = fpscamera
>
> player_inventory.set_player_inventory_data(self.inventory_data)
> player_inventory.set_weapon_slot_1_inventory_data(self.weapon_slot_1_data)
> player_inventory.set_weapon_slot_2_inventory_data(self.weapon_slot_2_data)
> player_inventory.set_weapon_slot_3_inventory_data(self.weapon_slot_3_data)
> player_inventory.set_mod_slot_1_inventory_data(self.mod_slot_1_data)
> player_inventory.set_mod_slot_2_inventory_data(self.mod_slot_2_data)
> player_inventory.set_mod_slot_3_inventory_data(self.mod_slot_3_data)
>
> for node in get_tree().get_nodes_in_group("external_inventory"):
> node.toggle_inventory.connect(toggle_inventory_interface)
> hot_bar_inventory.set_inventory_data(self.inventory_data)
> #get_parent().instantiate_pickup.connect(on_instantiate_pickup)
>
> func _unhandled_input(event):
>
> if not is_multiplayer_authority(): return
>
> if Input.is_action_just_pressed("quit"):
> if pausing:
> pausing = false
> else:
> pausing = true
> inventory = false
> inventoryHUD.visible = false
> player_inventory.visible = false
> Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
>
> if Input.is_action_just_pressed("inventory"):
> toggle_inventory_interface()
>
> if Input.is_action_just_pressed("collections"):
>
> if collections:
> collections = false
> else:
> collections = true
>
> if Input.is_action_just_pressed("interact"):
> if inventory:
> toggle_inventory_interface()
> if interact_ray.is_colliding():
> interact_ray.get_collider().player_interact()
>
> if not pausing and not inventory and not collections:
> if event is InputEventMouseMotion:
> if freelook:
> camera.rotate_y(-event.relative.x * .005)
> else:
> rotate_y(-event.relative.x * .005)
> camera.rotate_x(-event.relative.y * .005)
> camera.rotation.x = clamp(camera.rotation.x, -PI/2, PI/2)
>
> if Input.is_action_just_pressed("inspect equipped"):
> inspecting = true
> print_debug("Inspecting")
> if Input.is_action_just_released("inspect equipped"):
> inspecting = false
> print_debug("No longer Inspecting")
>
> if Input.is_action_pressed("sprint"):
> if Input.is_action_pressed("crouch"):
> crawling = true
> print_debug("Crawling.")
> else:
> sprinting = true
> elif Input.is_action_just_released("sprint"):
> sprinting = false
> crawling = false
>
> if Input.is_action_just_pressed("jump") and is_on_floor():
> velocity.y = JUMPSPEED
>
> if Input.is_action_pressed("crouch"):
> crouching = true
> print_debug("Crouching.")
> elif Input.is_action_just_released("crouch"):
> crouching = false
> crawling = false
> anim_rig.play("rig stand")
>
> if Input.is_action_pressed("freelook"):
> freelook = true
> print_debug("Freelook.")
> elif Input.is_action_just_released("freelook"):
> freelook = false
> camera.rotation = Vector3(0,0,0)
>
> if Input.is_action_just_pressed("swap cameras") and camera == tpscamera:
> print_debug("FPS Camera")
> fpscamera.current = true
> camera = fpscamera
> elif Input.is_action_just_pressed("swap cameras") and camera == fpscamera:
> print_debug("TPS Camera")
> fpscamera.current = false
> tpscamera.current = true
> camera = tpscamera
>
> if Input.is_action_just_pressed("lean left"):
> tpscamera.position.x = tpscamera.position.x - 1
> tpscamera.position.y = tpscamera.position.y - .4
> if tpscamera.position.x < -1:
> tpscamera.position.x = -1
> if tpscamera.position.y < 2.9:
> tpscamera.position.y = 2.9
> if Input.is_action_just_pressed("lean right"):
> tpscamera.position.x = tpscamera.position.x + 1
> tpscamera.position.y = tpscamera.position.y - .4
> if tpscamera.position.x > 1:
> tpscamera.position.x = 1
> if tpscamera.position.y < 2.9:
> tpscamera.position.y = 2.9
> if Input.is_action_pressed("lean left") and Input.is_action_pressed("lean right"):
> tpscamera.position.x = 0
>
> if equipped_weapon_1 or equipped_weapon_2 or equipped_weapon_3:
> if Input.is_action_just_pressed("action 1") and anim_rig.current_animation != "shoot":
> play_shoot_effects.rpc()
> shooting = true
> if raycast.is_colliding():
> if raycast.get_collider() is CharacterBody3D:
> var hit_player = raycast.get_collider()
> print(raycast.get_collider().name)
> hit_player.attack.rpc_id(hit_player.get_multiplayer_authority())
> elif Input.is_action_just_released("action 1"):
> shooting = false
> stop_shoot_effects.rpc()
>
> if Input.is_action_just_pressed("action 2") and not sprinting:
> aiming = true
> elif Input.is_action_just_released("action 2"):
> aiming = false
> fpscamera.position.x = 0
> fpscamera.position.z = -0.35
>
> if Input.is_action_just_pressed("equipped 1") and weapon_1_id:
> equipped_weapon_2 = false
> equipped_weapon_3 = false
> weapon_model_2.visible = false
> weapon_model_3.visible = false
> if equipped_weapon_1:
> weapon.visible = false
> equipped_weapon_1 = false
> leftshoulder.rotation.x = 0
> rightshoulder.rotation.x = 0
> else:
> weapon.visible = true
> equipped_weapon_1 = true
> weapon_model_1.visible = true
>
> if Input.is_action_just_pressed("equipped 2") and weapon_2_id:
> equipped_weapon_1 = false
> equipped_weapon_3 = false
> weapon_model_1.visible = false
> weapon_model_3.visible = false
> if equipped_weapon_2:
> weapon.visible = false
> equipped_weapon_2 = false
> leftshoulder.rotation.x = 0
> rightshoulder.rotation.x = 0
> else:
> weapon.visible = true
> equipped_weapon_2 = true
> weapon_model_2.visible = true
>
> if Input.is_action_just_pressed("equipped 3") and weapon_3_id:
> equipped_weapon_1 = false
> equipped_weapon_2 = false
> weapon_model_1.visible = false
> weapon_model_2.visible = false
> if equipped_weapon_3:
> weapon.visible = false
> equipped_weapon_3 = false
> leftshoulder.rotation.x = 0
> rightshoulder.rotation.x = 0
> else:
> weapon.visible = true
> equipped_weapon_3 = true
> weapon_model_3.visible = true
>
> func _physics_process(delta):
>
> if not is_multiplayer_authority(): return
> camera.current = true
> var input_dir = Input.get_vector("left", "right", "forward", "backward")
> var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
>
> head.rotation = camera.rotation
> tpshead.rotation.z = camera.rotation.y
> tpshead.rotation.x = camera.rotation.x * -1
> fpshealthbar.size.x = health
> tpshealthbar.size.x = health
>
> get_slot_data()
>
> if inventory:
> interact_ray.enabled = false
> velocity.x = 0
> velocity.z = 0
> if not inventory:
> interact_ray.enabled = true
>
> if not freelook:
> weapon.global_position = rightpalm.global_position
> weapon.rotation.x = camera.rotation.x
>
> if not pausing and not inventory:
> if direction:
> if crawling:
> velocity.x = direction.x * CRAWLSPEED
> velocity.z = direction.z * CRAWLSPEED
> elif crouching:
> velocity.x = direction.x * CROUCHSPEED
> velocity.z = direction.z * CROUCHSPEED
> elif sprinting:
> velocity.x = direction.x * SPRINTSPEED
> velocity.z = direction.z * SPRINTSPEED
> else:
> walking = true
> velocity.x = direction.x * SPEED
> velocity.z = direction.z * SPEED
> else:
> velocity.x = move_toward(velocity.x, 0, SPEED)
> velocity.z = move_toward(velocity.z, 0, SPEED)
>
> if not is_on_floor():
> velocity.y -= gravity * delta
>
> if inspecting:
> weapon.rotation.y = righthand.rotation.y * -1
> weapon.rotation.x = righthand.rotation.x * -1
> anim_arms.play("arms inspect")
>
> if equipped_weapon_1 or equipped_weapon_2 or equipped_weapon_3:
> if not inspecting:
> weapon.rotation.y = 0
> anim_arms.play("arms weapon equipped")
> if not freelook and not sprinting and not crawling:
> leftshoulder.rotation.x = camera.rotation.x
> rightshoulder.rotation.x = camera.rotation.x * -1
> if not equipped_weapon_1 and not equipped_weapon_2 and not equipped_weapon_3:
> anim_arms.play("arms idle")
>
> if crouching:
> anim_rig.play("rig crouch")
> fpscamera.position.y = fpscamera.position.y - .01
> if fpscamera.position.y < 1.8:
> fpscamera.position.y = 1.8
> else:
> if camera == fpscamera:
> fpscamera.position.x = 0
> fpscamera.position.z = -0.35
> fpscamera.position.y = fpscamera.position.y + .1
> if fpscamera.position.y > 2.4:
> fpscamera.position.y = 2.4
> if crouching:
> fpscamera.position.y = 1.8
>
> if camera == tpscamera:
> tpscamera.fov = 100
>
> if aiming:
> if camera == fpscamera:
> fpscamera.global_position = aimposition.global_position
> if camera == tpscamera:
> tpscamera.fov = 50
>
> if sprinting:
> aiming = false
> leftshoulder.rotation.x = 0
> rightshoulder.rotation.x = 0
> anim_arms.play("arms weapon sprinting")
>
> if crawling:
> aiming = false
> leftshoulder.rotation.x = 0
> rightshoulder.rotation.x = 0
> anim_arms.play("arms weapon crawling")
>
> if velocity.z == 0 and not crouching:
> anim_rig.play("rig idle")
> if camera.position.x == -1:
> anim_tpsc.play("tpsc left")
> if camera.position.x == 1:
> anim_tpsc.play("tpsc right")
> if camera.position.x == 0:
> anim_tpsc.play("tpsc centered")
> if camera == fpscamera:
> anim_tpsc.play("tpsc retracted")
> if tpscamera.position.x == 0:
> tpscamera.position.y = 3.3
>
> move_and_slide()
>
>
>
> @rpc("any_peer")
> func heal(heal_value: int):
>
> health += heal_value
> if health > Globals.PlayerHealth:
> health = Globals.PlayerHealth
>
> @rpc("any_peer")
> func attack():
> var attack_value = 10
> health -= attack_value
> if health <= 0:
> health = Globals.PlayerHealth
> position = Vector3.ZERO
> health_changed.emit(health)
>
> @rpc("call_local")
> func play_shoot_effects():
>
> muzzle_flash.restart()
> muzzle_flash.emitting = true
>
> @rpc("call_local")
> func stop_shoot_effects():
>
> anim_weapon.stop()
> muzzle_flash.emitting = false
>
>
> func toggle_inventory_interface(external_inventory_owner = null) -> void:
>
> if inventoryHUD.visible:
> inventory = false
> inventoryHUD.visible = false
> player_inventory.visible = false
> Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
>
> else:
> inventory = true
> inventoryHUD.visible = true
> player_inventory.visible = true
> Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
>
> if external_inventory_owner and player_inventory.visible:
> player_inventory.set_external_inventory(external_inventory_owner)
> else:
> player_inventory.clear_external_inventory()
>
> func get_drop_position() -> Vector3:
>
> var PlayerFacing = -self.global_transform.basis.z
> return fpscamera.global_position + PlayerFacing
>
> func _on_inventory_drop_slot_data(grabbed_slot_data) -> void:
>
> print_debug("Sending object to server.")
> drop_item.emit(grabbed_slot_data)
>
> #func on_instantiate_pickup(grabbed_slot_data):
> var pick_up = PickUp.instantiate()
> pick_up.slot_data = grabbed_slot_data
> pick_up.position = Vector3(0,10,0)
> add_child(pick_up)
>
> func get_slot_data() -> void:
>
> weapon_1_id = weapon_slot_1_data.slot_datas[0]
> weapon_2_id = weapon_slot_2_data.slot_datas[0]
> weapon_3_id = weapon_slot_3_data.slot_datas[0]
>
> if weapon_1_id == null:
> equipped_weapon_1 = false
> if weapon_model_1:
> weapon_model_1.visible = false
>
> elif weapon_1_id.item_data.name == "A55 Clipper":
> weapon_model_1 = $"Weapon/models/A55 Clipper"
> elif weapon_1_id.item_data.name == "A22 Thumper":
> weapon_model_1 = $"Weapon/models/A22 Thumper"
> elif weapon_1_id.item_data.name == "A33 Jackhammer":
> weapon_model_1 = $"Weapon/models/A33 Jackhammer"
>
> if weapon_2_id == null:
> equipped_weapon_2 = false
> if weapon_model_2:
> weapon_model_2.visible = false
>
> elif weapon_2_id.item_data.name == "A55 Clipper":
> weapon_model_2 = $"Weapon/models/A55 Clipper"
> elif weapon_2_id.item_data.name == "A22 Thumper":
> weapon_model_2 = $"Weapon/models/A22 Thumper"
> elif weapon_2_id.item_data.name == "A33 Jackhammer":
> weapon_model_2 = $"Weapon/models/A33 Jackhammer"
>
> if weapon_3_id == null:
> equipped_weapon_3 = false
> if weapon_model_3:
> weapon_model_3.visible = false
>
> elif weapon_3_id.item_data.name == "Rosen's Shadow":
> weapon_model_3 = $"Weapon/models/Exotic Rosen's Shadow"
>
如果您想查看,这里是完整的服务器代码。
> extends Node
>
> var pos_dict = {}
> var players = {}
>
> #signal instantiate_pickup(grabbed_slot_data)
>
> enum lobby_status {Private, Friends, Public, Invisible}
> enum search_distance {Close, Default, Far, Worldwide}
>
> @onready var main_menu = $CanvasLayer
> @onready var address_entry = $CanvasLayer/AddressEntry
> @onready var hud = $CanvasLayer/HUD
> @onready var health_bar = $CanvasLayer/HUD/HealthBar
>
> @onready var connection_timer = $ConnectionTimer
>
> @onready var steam_name = $CanvasLayer/SteamName
> @onready var lobby_name = steam_name
> @onready var lobby_output = $CanvasLayer/Chat/RichTextLabel
> @onready var player_count = $CanvasLayer/Players/Playercount
> @onready var player_list = $CanvasLayer/Players/RichTextLabel
> @onready var chat_input = $CanvasLayer/Chat/SendMessage/TextEdit
>
> @onready var keybinds_panel = $CanvasLayer/SettingsPanel/KeybindsButton/KeybindsPanel
> @onready var video_panel = $CanvasLayer/SettingsPanel/VideoButton/VideoPanel
> @onready var audio_panel = $CanvasLayer/SettingsPanel/AudioButton/AudioPanel
> @onready var chat_panel = $CanvasLayer/SettingsPanel/ChatButton/ChatPanel
> @onready var accessibility_panel = $CanvasLayer/SettingsPanel/AccessibilityButton/AccessibilityPanel
>
> @onready var PickUp = preload("res://item/pickup/pickup.tscn")
>
> const Player = preload("res://player/player.tscn")
> const PORT = 9999
>
> var enet_peer = ENetMultiplayerPeer.new()
>
>
>
>
>
> func _process(_delta):
>
> $CanvasLayer/DisconnectTimer/Timer.text = str(ceil($ConnectionTimer.time_left))
> if address_entry.text == "":
> $CanvasLayer/JoinButton.disabled = true
> else:
> $CanvasLayer/JoinButton.disabled = false
>
>
>
> func _unhandled_input(_event):
>
> if Input.is_action_just_pressed("quit"):
> if main_menu.visible:
> main_menu.visible = false
> Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
> else:
> main_menu.visible = true
> Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
>
>
>
> func _on_connection_timer_timeout():
>
> get_tree().change_scene_to_file("res://world.tscn")
> $CanvasLayer/DisconnectTimer.visible = false
> Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
> print_debug("Connection to the server timed out.")
>
> func add_player(peer_id):
>
> var player = Player.instantiate()
> player.name = str(peer_id)
> add_child(player)
> players[peer_id] = player
> player.drop_item.connect(_on_inventory_drop_slot_data)
> if player.drop_item.is_connected(_on_inventory_drop_slot_data):
> print_debug("This is connecting to",player)
> if player.is_multiplayer_authority():
> player.health_changed.connect(update_health_bar)
>
> func remove_player(peer_id):
>
> var player = get_node_or_null(str(peer_id))
> if player:
> player.queue_free()
>
> func update_health_bar(health_value):
>
> health_bar.value = health_value
>
> func _on_multiplayer_spawner_spawned(node):
>
> if node.is_multiplayer_authority():
> node.health_changed.connect(update_health_bar)
>
>
> func upnp_setup():
>
> var upnp = UPNP.new()
> var discover_result = upnp.discover()
> assert(discover_result == UPNP.UPNP_RESULT_SUCCESS, \
> "UPNP Discover Failed! Error %s" % discover_result)
> assert(upnp.get_gateway() and upnp.get_gateway().is_valid_gateway(), \
> "UPNP Invalid Gateway!")
>
> var map_result = upnp.add_port_mapping(PORT)
> assert(map_result == UPNP.UPNP_RESULT_SUCCESS, \
> "UPNP Port Mapping Failed! Error %s" % map_result)
> print("Success! Join Address: %s" % upnp.query_external_address())
>
> func _on_inventory_drop_slot_data(grabbed_slot_data) -> void:
> print_debug("Server is receiving object.")
> if grabbed_slot_data:
> print_debug(grabbed_slot_data)
> else:
> print_debug("no slot data")
> var pick_up = PickUp.instantiate()
> pick_up.slot_data = grabbed_slot_data
> pick_up.position = Vector3(0,10,0)
> add_child(pick_up)
>
> func _on_host_button_pressed():
>
> main_menu.hide()
> hud.show()
> $CanvasLayer/HostButton.disabled = true
> $CanvasLayer/JoinButton.disabled = true
> $CanvasLayer/JoinLocal.disabled = true
> $CanvasLayer/AddressEntry.editable = false
> $CanvasLayer/LeaveButton.disabled = false
> $CanvasLayer/Background.visible = false
> enet_peer.create_server(PORT)
> multiplayer.multiplayer_peer = enet_peer
> multiplayer.peer_connected.connect(add_player)
> multiplayer.peer_disconnected.connect(remove_player)
> add_player(multiplayer.get_unique_id())
> upnp_setup()
>
> func _on_join_button_pressed():
>
> enet_peer.create_client(address_entry.text, PORT)
> multiplayer.multiplayer_peer = enet_peer
> connection_timer.start()
> $CanvasLayer/LeaveButton.disabled = false
> $CanvasLayer/DisconnectTimer.visible = true
> enet_peer.get_connection_status()
> if enet_peer.get_connection_status() == 1:
> main_menu.hide()
> $CanvasLayer/HostButton.disabled = true
> $CanvasLayer/JoinButton.disabled = true
> $CanvasLayer/JoinLocal.disabled = true
> $CanvasLayer/AddressEntry.editable = false
> $CanvasLayer/Background.visible = false
> connection_timer.stop()
> $CanvasLayer/DisconnectTimer.visible = false
> print_debug("Connected to the server!")
>
> func _on_join_local_pressed():
>
> enet_peer.create_client("localhost", PORT)
> multiplayer.multiplayer_peer = enet_peer
> connection_timer.start()
> $CanvasLayer/LeaveButton.disabled = false
> $CanvasLayer/DisconnectTimer.visible = true
> enet_peer.get_connection_status()
> if enet_peer.get_connection_status() == 1:
> main_menu.hide()
> $CanvasLayer/HostButton.disabled = true
> $CanvasLayer/JoinButton.disabled = true
> $CanvasLayer/JoinLocal.disabled = true
> $CanvasLayer/AddressEntry.editable = false
> $CanvasLayer/Background.visible = false
> connection_timer.stop()
> $CanvasLayer/DisconnectTimer.visible = false
> print_debug("Connected to the server!")
>
> func _on_leave_button_pressed():
>
> enet_peer.close()
> get_tree().reload_current_scene()
> $CanvasLayer/JoinButton.disabled = true
> $CanvasLayer/JoinLocal.disabled = true
> $CanvasLayer/AddressEntry.editable = true
> $CanvasLayer/HostButton.disabled = false
> $CanvasLayer/LeaveButton.disabled = false
> $CanvasLayer/Background.visible = true
> print_debug("Returning to the Menu.")
>
> func _on_exit_button_pressed():
>
> get_tree().quit()
>
> func _on_settings_button_pressed():
> if $CanvasLayer/SettingsPanel.visible == true:
> $CanvasLayer/SettingsPanel.visible = false
> else:
> $CanvasLayer/SettingsPanel.visible = true
>
> func _on_keybinds_button_pressed():
> if keybinds_panel.visible == true:
> keybinds_panel.visible = false
> else:
> keybinds_panel.visible = true
> video_panel.visible = false
> audio_panel.visible = false
> chat_panel.visible = false
> accessibility_panel.visible = false
>
> func _on_video_button_pressed():
> if video_panel.visible == true:
> video_panel.visible = false
> else:
> video_panel.visible = true
> keybinds_panel.visible = false
> audio_panel.visible = false
> chat_panel.visible = false
> accessibility_panel.visible = false
>
> func _on_audio_button_pressed():
> if audio_panel.visible == true:
> audio_panel.visible = false
> else:
> audio_panel.visible = true
> video_panel.visible = false
> keybinds_panel.visible = false
> chat_panel.visible = false
> accessibility_panel.visible = false
>
> func _on_chat_button_pressed():
> if chat_panel.visible == true:
> chat_panel.visible = false
> else:
> chat_panel.visible = true
> video_panel.visible = false
> audio_panel.visible = false
> keybinds_panel.visible = false
> accessibility_panel.visible = false
>
> func _on_accessibility_button_pressed():
> if accessibility_panel.visible == true:
> accessibility_panel.visible = false
> else:
> accessibility_panel.visible = true
> video_panel.visible = false
> audio_panel.visible = false
> chat_panel.visible = false
> keybinds_panel.visible = false
>
我尝试从连接到服务器的客户端发出信号,并且在测试“is_connected”时确认信号正在连接,但客户端没有从发射中获取数据并执行函数。
这就是问题所在,我需要连接信号两次。这是我必须第二次连接的地方:
func _on_multiplayer_spawner_spawned(节点):
if node.is_multiplayer_authority():
node.health_changed.connect(update_health_bar)
node.drop_item.connect(_on_inventory_drop_slot_data)