Godot Version 4.2
Question
my player.gd
extends CharacterBody3D
const SPEED = 7.0
const MAX_SPEED = 14.0 # Maximum speed when sprinting
const ACCELERATION = 0.5 # How quickly the player reaches max speed
const JUMP_VELOCITY = 6
var score = 0 # Score variable
var jumps = 0 # Number of jumps since touching the ground
var sprinting = false # Whether the player is sprinting
Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting(“physics/3d/default_gravity”)
var mouse_sensitivity = 0.3 # Add this line
Create a reference to the FPS label.
@onready var fps_label = $Camera3D/FPSLabel
@onready var score_label = $Camera3D/ScoreLabel
var bullet_scene = preload(“res://scenes/bullet.tscn”) # Preload the bullet scene
func _ready():
for coin in get_tree().get_nodes_in_group(“coins”):
coin.connect(“COIN_PICKUP”, Callable(self, “_on_coin_pickup”))
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) # Add this line
func _physics_process(delta):
# Add the gravity.
if not is_on_floor():
velocity.y -= gravity * delta # velocity pushing it downard
else:
jumps = 0 # Reset the jump counter when the player touches the ground
# Handle jump.
if Input.is_action_just_pressed("jump") and jumps < 2:
velocity.y = JUMP_VELOCITY # jump y axis = th variable
jumps += 1
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
var input_dir = Input.get_vector("left", "right", "up", "down")
var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
var speed = SPEED
if Input.is_action_pressed("sprint"):
speed = lerp(speed, MAX_SPEED, ACCELERATION)
if direction:
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)
move_and_slide()
# Update the FPS label.
fps_label.text = "FPS = " + str(Engine.get_frames_per_second())
func _input(event):
if event is InputEventMouseMotion:
rotate_y(deg_to_rad(-event.relative.x * mouse_sensitivity)) # Add this line
if Input.is_action_just_pressed("ui_cancel"):
get_tree().quit() # Quits the game
if Input.is_action_just_pressed("restart"):
get_tree().reload_current_scene() # Restarts the current scene
if Input.is_action_just_pressed("fire"): # Replace "fire" with the actual input action for firing
var bullet = bullet_scene.instantiate() # Instance the bullet scene
var spawn_position = self.global_transform.origin + self.transform.basis.z * -1.5 # Adjust the spawn position
bullet.global_transform = Transform3D(self.global_transform.basis, spawn_position) # Set the bullet's global transform
bullet.set_direction(-self.transform.basis.z) # Set the bullet's direction to the player's forward vector
get_parent().add_child(bullet) # Add the bullet to the current scene
if Input.is_action_just_pressed("secondary_fire"): # Replace "secondary_fire" with the actual input action for secondary fire
for i in range(4): # Instance three bullets
var spawn_position = self.global_transform.origin + self.transform.basis.z * -1.6 # Adjust the spawn position to be a bit more forward
var bullet = bullet_scene.instantiate() # Instance the bullet scene
bullet.global_transform = Transform3D(self.global_transform.basis, spawn_position) # Set the bullet's global transform
bullet.set_direction(-self.transform.basis.z) # Set the bullet's direction to the player's forward vector
bullet.set_spiral(true) # Make the bullet spiral
bullet.set_orbit_offset(randf_range(-PI, PI)) # Set the bullet's initial offset in the orbit to a random value
get_parent().add_child(bullet) # Add the bullet to the current scene
func _on_coin_pickup():
score += 1
score_label.text = "Coins: " + str(score)
bullet.gd
extends RigidBody3D
var speed = 25 # Speed of the bullet
var _direction = Vector3.ZERO
var spiral = false # Whether the bullet should spiral
var rotation_speed = 5.0 # Speed of the rotation
var orbit_offset = -0.9 # Initial offset in the orbit
var orbit_radius = 0.3 # Radius of the orbit
var lifetime = 20 # Lifetime of the bullet in seconds
Called when the node enters the scene tree for the first time.
func _ready():
gravity_scale = 0
linear_velocity = _direction.normalized() * speed
$Timer.start(lifetime) # Start the timer
connect(“body_entered”, _on_body_entered) # Connect the body_entered signal to the _on_body_entered function
func _physics_process(delta):
if spiral:
# Adjust the bullet’s local position to make it oscillate up and down
transform.origin += _direction.cross(Vector3.UP) * sin(orbit_offset) * orbit_radius
orbit_offset += rotation_speed * delta
func set_direction(value):
_direction = value
func set_spiral(value):
spiral = value
func set_orbit_offset(value):
orbit_offset = value
func _on_Timer_timeout():
queue_free() # Delete the bullet when the timer times out
func _on_body_entered(body):
if body.name != “Bullet”: # Replace “Bullet” with the actual name of your bullet node
spiral = false # Stop the spiral when the bullet collides with something other than another bullet
rotation_speed = 0 # Reset the rotation speed
orbit_offset = 0 # Reset the orbit offset
orbit_radius = 0 # Reset the orbit radius