Identifier isn't declared in the current scope in godot - godot

Code for the coin to make a score:
extends Area2D
onready var anim_player: AnimationPlayer = get_node("AnimationPlayer")
func _on_body_entered(body: PhysicsBody2D) -> void:
picked()
func picked() -> void:
PlayerData.Score += score
anim_player.play("Fade")
It isn't working in coin but works in enemy(code):
extends "res://Code/Both Script.gd"
onready var Stomp_Thingy: Area2D = $Stomp_Thingy
export var score: = 100
func _ready() -> void:
set_physics_process(false)
_Velocity.x = -Speed.x
func _on_Stomp_Thingy_body_entered(body: PhysicsBody2D) -> void:
if body.global_position.y > get_node("Stomp Thingy").global_position.y:
return
get_node("CollisionShape2D").disabled = true
queue_free()
func _physics_process(delta: float) -> void:
_Velocity.y += gravity * delta
if is_on_wall():
_Velocity.x *= -1.0
_Velocity.y = move_and_slide(_Velocity, FLOOR_NORMAL).y
func die() -> void:
queue_free()enter code here
PlayerData.Score += score

In script for coin, i think "score" isn't declared. So you can add "var score = 100" to that script. Or use autoload if you want score same on enemy and coin. Include more information.

Related

Player not looking in the right direction

I have a player that you can move by clicking in a location. They are guided by pathfinding to also move around any potential obstacles in their way. Here is my script:
extends KinematicBody2D
export var speed = 200
var velocity = Vector2.ZERO
onready var navigation_agent = $NavigationAgent2D
func _ready():
navigation_agent.connect("velocity_computed", self, "move")
func _input(event):
if event.is_action_pressed("mouse_right"):
navigation_agent.set_target_location(event.get_global_position())
func _process(_delta):
if $RayCast2D.is_colliding():
if $RayCast2D.get_collider().is_in_group("enemy_ground_troop"):
self.velocity = Vector2.ZERO
ranged_attack()
if navigation_agent.is_navigation_finished():
return
var overlapping_areas = $EnemyDetector.get_overlapping_areas()
for area in overlapping_areas:
if area.is_in_group("enemy_ground_troop"):
navigation_agent.set_target_location(area.get_global_position())
look_at(area.get_global_position())
velocity = global_position.direction_to(navigation_agent.get_next_location()) * speed
look_at(global_position.direction_to(navigation_agent.get_next_location()))
$RayCast2D.global_rotation = self.global_rotation
navigation_agent.set_velocity(velocity)
func move(velocity):
velocity = move_and_slide(velocity)
func ranged_attack():
print_debug("fired ranged attack")
When I run the scene, the player is not looking where I want them too based on the look at commands. How can I fix this?
The look_at method takes a target position, not a direction.
So, instead of this:
look_at(global_position.direction_to(navigation_agent.get_next_location()))
Try this:
look_at(navigation_agent.get_next_location())

Switch between 2D layers programmatically

NOTE this is about Godot 4.0
In a particular scene, I've a set of layers, of which only one is visible at a time. My code is able to decide how a switch from one layer to other occurs.
I've implemented a class for solutioning this: ViewSwitch. That class has a set of ViewSwitchItem. The layers have to be a subtype of ViewSwitchItem.
The problem I'm facing is that, only once, from a layer first_menu, after I click the "Start Game" button in my first layer and switch to another layer start_game_menu, the game switches back to first_menu even if the player didn't meant so. Like I said, it happens only once. After you click like, say, the second time, you'll be transitioned to start_game_menu without being redirected to first_menu again. All this is done using GDScript. Something is wrong in my logic.
gd_util/ViewSwitch.gd
class_name ViewSwitch
var current_item: ViewSwitchItem = null
var items: Array[ViewSwitchItem] = []
func initialize() -> void:
swap(null)
for sw in items:
sw.parent_switch = self
sw.initialize()
func swap(swap: ViewSwitchItem) -> void:
if current_item == swap:
return
if current_item != null:
current_item.end(swap)
else:
immediate_swap(swap)
func immediate_swap(swap: ViewSwitchItem) -> void:
for sw in items:
sw.node.visible = false
if swap == null:
return
current_item = swap
swap.node.visible = true
swap.start()
gd_util/ViewSwitchItem.gd
class_name ViewSwitchItem
var parent_switch: ViewSwitch = null
var node: Node = null
func initialize():
pass
func start():
pass
func end(swap: ViewSwitchItem):
if parent_switch.current_item == swap:
return
immediate_swap(swap)
func immediate_swap(swap: ViewSwitchItem):
if parent_switch.current_item == swap:
return
parent_switch.immediate_swap(swap)
scenes/mainMenuScene/MainMenuScene.gd
extends Node2D
var view_switch: ViewSwitch = ViewSwitch.new()
var first_menu := MainMenuScene_firstMenu.new()
var start_game_menu := MainMenuScene_startGameMenu.new()
# Called when the node enters the scene tree for the first time.
func _ready():
view_switch.items = [
first_menu,
start_game_menu,
]
first_menu.node = $root/animation/container1
start_game_menu.node = $root/animation/container2_startGame
view_switch.initialize()
view_switch.swap(first_menu)
# first_menu
$root/animation/container1/startGameBtn.pressed.connect(func():
view_switch.swap(start_game_menu))
$root/animation/container1/exitBtn.pressed.connect(func():
get_tree().quit())
# start_game_menu
$root/animation/container2_startGame/panel/PanelContainer/VBoxContainer/MarginContainer/VBoxContainer/returnBtn.pressed.connect(func():
view_switch.swap(first_menu))
$root/animation.animation_finished.connect(func(animation_name):
if animation_name == "Anim":
view_switch.swap(first_menu))
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
# first_menu
if view_switch.current_item == first_menu:
pass
# start_game_menu
elif view_switch.current_item == start_game_menu:
if Input.is_action_just_released("back"):
view_switch.swap(first_menu)
scenes/mainMenuScene/switches/MainMenuScene_firstMenu.gd
class_name MainMenuScene_firstMenu
extends ViewSwitchItem
var start_game_button = null
func initialize():
start_game_button = self.node.get_tree().root.get_child(0).get_node("root/animation/container1/startGameBtn")
func start():
start_game_button.grab_focus()
func end(swap: ViewSwitchItem):
immediate_swap(swap)
scenes/mainMenuScene/switches/MainMenuScene_startGameMenu.gd
class_name MainMenuScene_startGameMenu
extends ViewSwitchItem
var panel1 = null
func initialize():
panel1 = self.node.get_tree().root.get_child(0).get_node("root/animation/container2_startGame/panel")
panel1.after_popup.connect(func():
self.node.get_tree().root.get_child(0).get_node("root/animation/container2_startGame/panel/PanelContainer/VBoxContainer/MarginContainer/VBoxContainer/returnBtn").grab_focus())
panel1.after_collapse.connect(func():
# switch to first_menu
immediate_swap(parent_switch.items[0]))
func start():
panel1.popup()
func end(swap: ViewSwitchItem):
panel1.collapse()
Thanks!

Invalid set index 'value' (on base: 'null instance') with value type of float

I have a game I'm making in Godot, 2D
I have a progres sbar called "Healthbar"
I'm trying to set it's value to the players HP value
the full code is as follows
extends KinematicBody2D
var health: float = 100
func ready():
pass
export var movespeed : int
export var batteryspeed: int
var battery = preload("res://Bullet.tscn")
func _physics_process(delta):
get_tree().get_root().find_node("HealthBar").value = health
var motion = Vector2()
if (health <= 0):
gameover()
if(Input.is_action_pressed("MoveUp")):
motion.y -= 1
if(Input.is_action_pressed("MoveLeft")):
motion.x -= 1
if(Input.is_action_pressed("MoveDown")):
motion.y += 1
if(Input.is_action_pressed("MoveRight")):
motion.x += 1
motion = motion.normalized()
motion = move_and_slide(motion * movespeed)
if(Input.is_action_just_pressed("Fire")):
fire()
look_at(get_global_mouse_position())
func fire():
var batteryInstance = battery.instance()
batteryInstance.position = position
batteryInstance.rotation_degrees = rotation_degrees
batteryInstance.apply_impulse(Vector2(), Vector2(batteryspeed, 0).rotated(rotation))
get_tree().get_root().call_deferred("add_child", batteryInstance)
func gameover():
get_tree().reload_current_scene()
func _on_Area2D_body_entered(body):
if "Enemy" in body.name:
health -= 10
and the part I'm having issues with, I suspect is
get_tree().get_root().find_node("HealthBar").value = health
What do I do to set the progressbar value to the health variable?
It turns out you must use the function
{Progress Bar}.set_value({value})

Can jump a kinematic body from a rigidbody in godot?

I found this code to push a rigidbody with a kinematic body in godot:
for index in get_slide_count():
var collision = get_slide_collision(index)
if collision.collider.is_in_group("bodies"):
collision.collider.apply_central_impulse(-collision.normal * push)
This code works but when the player stand on rigidbody can't jump!!
P.S. I have set the infinite_inertia to false. All code is this:
extends KinematicBody2D
onready var animation = $AnimationPlayer
export (int, 0, 200) var push = 30
var velocity :=Vector2.ZERO
var gravity := 30
var speed := 50
var jumpforce = 300
func _physics_process(delta) -> void:
#Push()
if Input.is_action_pressed("right"):
$Sprite.flip_h=false
velocity.x += speed
animation.play("Walk")
elif Input.is_action_pressed("left"):
$Sprite.flip_h=true
velocity.x -= speed
animation.play("Walk")
else:
animation.play("Idle")
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y =- jumpforce
animation.play("Idle")
velocity.y += gravity
Push()
velocity=move_and_slide(velocity,Vector2.UP, false, 4, PI/4, false)
velocity.x= lerp(velocity.x,0,0.2)
func Push():
for index in get_slide_count():
var collision = get_slide_collision(index)
if collision.collider.is_in_group("bodies"):
collision.collider.apply_central_impulse(-collision.normal * push)
I found the solution to this problem!!! I set the rigitbody 's mass property from editor to 2 instead 1 . Is working now :)

unable to right to a variable from another script in Godot

Trying to access variable gravity in this script
extends KinematicBody2D
class_name Actor
export var speed: = Vector2(300.0, 1000.0)
export var gravity = 3000.0
var velocity: = Vector2.ZERO
func _physics_process(delta: float) -> void:
velocity.y += gravity*delta
#velocity.y = max(velocity.y, speed.y)
velocity = move_and_slide(velocity)
from this script
extends Actor
func _physics_process(delta: float) -> void:
var direction = Vector2(
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),0.0
)
velocity =
I get the error Unexpected token: Identifier:velocity
am I using class_name incorrectly?
You can access both velocity and gravity variables from base class, but you need to do it within a function, e.g.:
extends Actor
func _physics_process(delta: float) -> void:
velocity += Vector2.ZERO # just an example

Resources