3D Character dashing in movement direction

Im not sure about properties of rigid body as I normally use character body, but I can guess it has velocity. You can play with that variable. For instance, if body.velocity.y > 0 means it is falling. You can use a control statement (if …) to decide if dashing is available.

I figured it out. When you dash, set the property gravity_scale to zero and start the timer node. When the timer emits the signal time out, set gravity_scale to one. See the method here. Example code:

@onready var timer = $dropTimer


if Input.is_action_just_pressed("dash") and can_dash:
	can_dash = false
	apply_central_impulse(twist_pivot.basis * input * DASH_SPEED * delta)
	timer.start() #start might not be the method, but start the timer
	self.gravity_scale = 0

...


func on_dropTimer_timeout():
	self.gravity_scale = 1

This might cause errors and might need set_deferred() or set_property() or something similar.

Ok i’m getting two noteable errors one is

Player.gd:15 @ _ready(): Node not found: “dropTimer” (relative to “/root/FacTut/Player”).

The other is

Attempt to call function ‘start’ in base ‘null instance’ on a null instance

not very sure what they mean and how to really fix them and just to refresh heres my current player script

extends RigidBody3D
class_name Player

var respawn_position := global_position

var mouse_sensitivity := 0.001
var twist_input := 0.0
var pitch_input := 0.0
var DASH_SPEED := 1000 #Change this to change the speed of the dash
var can_dash: bool = false

@onready var character := $Character
@onready var twist_pivot := $TwistPivot
@onready var pitch_pivot := $TwistPivot/PitchPivot
@onready var timer = $dropTimer

func _ready() -> void:
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	
	

func _process(delta: float) -> void:
	var input := Vector3.ZERO
	input.x = Input.get_axis("move_right", "move_left")
	input.z = Input.get_axis("move_back", "move_forward")
	
	apply_central_force(twist_pivot.basis * input * 1200.0 * delta)
	
	if $RayCast3D.is_colliding():
		can_dash = true
	
	if Input.is_action_just_pressed("dash") and can_dash:
		can_dash = false
		apply_central_impulse(twist_pivot.basis * input * DASH_SPEED * delta) #See above for dash speed
		#Start with delta multiplied in, but know that it can be removed if speed issues exist. Check DASH_SPEED first though.
		timer.start() #start might not be the method, but start the timer
		self.gravity_scale = 0

	if Input.is_action_just_pressed("ui_cancel"):
		Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
		
	twist_pivot.rotate_y(twist_input)
	pitch_pivot.rotate_x(pitch_input)
	pitch_pivot.rotation.x = clamp(pitch_pivot.rotation.x, 
	deg_to_rad(-20), 
	deg_to_rad(20)
	)
	twist_input = 0.0
	pitch_input = 0.0
	
	if not input.is_zero_approx():
		var move_direction = twist_pivot.basis * input
		var align = character.transform.looking_at(character.transform.origin - move_direction)
		character.transform = character.transform.interpolate_with(align, delta * 20.0)


func on_dropTimer_timeout():
	self.gravity_scale = 1


func _unhandled_input(event: InputEvent) -> void: 

	if event is InputEventMouseMotion:
		if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
			twist_input = - event.relative.x * mouse_sensitivity
			pitch_input = event.relative.y * mouse_sensitivity

	if event.is_action_pressed("jump"):
		if $RayCast3D.is_colliding():
			apply_central_impulse(Vector3.UP * 16.0)

So what’s happening is that it is trying to find the timer node, but can’t find it (node not found). Because it can’t find the node, it returns a null instance. The variable gets set to the null instance, which then has ‘start’ called on it. There is no method start for null, so it returns an error (Attempt to call function ‘start’ in base ‘null instance’ on a null instance). To fix this, add a timer node as a child of the player called dropTimer (case-sensitive). You will also need to connect its timeout signal to the ‘on_dropTimer_timeout’ function.

Ok this works fine for keeping me in the air but im trying to figure how to do the timeout signal and honestly cant figure out how to set it to the function, it’s probably really simple i know haha

Go here, and scroll down to where it shows how to connect signals. I also recommend reading the whole tutorial to get used to Godot.

1 Like

Thanks so so much ngl I completely blanked about the node panels signal part which I did use before but this all works fine now thanks so much!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.