G4.3
What I have, Scene Powerbox, Wire and Player.
Node2D - Powerbox
-AnimatedSprite
-Area2D
–Collision
StaticBody2D - Wire
- Animatedsprite
- CollisionStatic
- Area2D
- –CollisionArea
What I want to do is when the wire breaks the player can walk over to the broken wire and press an input and activate a fixing function. The wire will then be fixed.
Conditions - The wire can only be fixed while the player holds down the input and can only work if the player is on the wire collision box. This will then trigger animation and when animation is finished the wire is fixed. If the player lets go of input or moves outside the wire collsion it will stop fixing which will then have the player start again.
Powerbox has an export which the wire scene is attached to within the inspector.
When the player moves over the wire the script on powerbox knows its the player. After this point I get logic lost.
Any ideas please???
This is a pretty complicated task but the system you want to use is pretty well developed. Ill try and write some stuff based on my code.
extends StaticBody2D
signal wire_fixed
enum WireState {FIXED, BROKEN, BEING_FIXED}
# you can use a global Enums for this if you want to as well
# But I just used enums here cause its only for wires.
export var fix_time = 3.0
var current_state = WireState.FIXED
var player_in_area = false
var fix_progress = 0.0
var animation_player = null
func _ready():
if has_node("AnimationPlayer"):
animation_player = $AnimationPlayer
$Area2D.connect("body_entered", self, "_on_Area2D_body_entered")
$Area2D.connect("body_exited", self, "_on_Area2D_body_exited")
func _process(delta):
if current_state == WireState.BROKEN and player_in_area:
if Input.is_action_pressed("fix_wire"):
fix_progress += delta
if animation_player:
animation_player.play("fixing")
if fix_progress >= fix_time:
complete_fix()
else:
reset_fix_progress()
func break_wire():
current_state = WireState.BROKEN
if animation_player:
animation_player.play("broken")
func complete_fix():
current_state = WireState.FIXED
fix_progress = 0.0
if animation_player:
animation_player.play("fixed")
emit_signal("wire_fixed")
func reset_fix_progress():
fix_progress = 0.0
if current_state == WireState.BEING_FIXED:
current_state = WireState.BROKEN
if animation_player:
animation_player.stop()
func _on_Area2D_body_entered(body):
if body.is_in_group("player"):
player_in_area = true
func _on_Area2D_body_exited(body):
if body.is_in_group("player"):
player_in_area = false
reset_fix_progress()
Then use something like this script for your Powerbox that references the wire:
extends Node2D
export(NodePath) var wire_path
var wire = null
func _ready():
if wire_path:
wire = get_node(wire_path)
wire.connect("wire_fixed", self, "_on_Wire_fixed")
# Called when the wire is fixed
func _on_Wire_fixed():
$AnimatedSprite.play("powered")
Couple of things I want to add on to this, Because I’m writing all of this in code. I’m ref’ing nodes by hard coding them. DONT DO THIS IN YOU CODE. Do something that more versatile like an @export with the correct node reference as a var for Wire or the Powerbox.
Also make sure to create a group for the player and add it to that group that I made in the code. Name it whatever you wanna.
Also you can use more complicated signals or custom signals. I can suggest a vid for that if you want to. Those can be hard to get down.
1 Like
@noaht5.1999 Thanks for this! Just had a wee hour looking over this and applying it to my situation. Obviously not intended to be plug and play but this did get me out of a jam!
Made me rethink a number of things and I seem to be back on track! Aprreciate your time.
1 Like