How can I freeze player input during a cutscene?

Godot Version

Godot 4.4.1-stable

Question

Hi everyone. I’m nearly done with my first large practice project in Godot, a simple platformer, but I’ve hit a snag at the very end - literally, the end cutscene. I want to have my player character frozen while the cutscene plays.

I settled on creating a ‘Freeze’ state in my Finite State Machine system, that stops the player’s input entirely. So far, so good, but now I’m not actually sure how to call this state…

I have a very simple ‘Cutscene triggered’ Area2D that I want the player to enter to trigger the ‘Freeze’ state:

extends Area2D

func _on_body_entered(body: Node2D) -> void:
	if body is Player:
		$"../AnimationPlayer".play("FadeIn")

So basically my question is - how do I use a signal to force the player into a specific state?

since you know the body is Player then you can use what ever function the player has to change to your frozen state body.freeze()

Thank you for the response! Unfortunately that doesn’t seem to work here:

image

Of course I should have been clearer as to my setup. I have my FSM utilizing nodes with scripts attached:

And here is the script I have attached to the root Player node:

class_name Player
extends CharacterBody2D

#region Variables
const HEALTH: int = 15
@onready var animations: AnimatedSprite2D = $Animations
@onready var states:= $PlayerState
@onready var death_timer: Timer = %DeathTimer
#endregion

#region Functions
func _ready() -> void:
	#Initializes the state machine, passing a reference of the player to the states
	#That way, it can move and react accordingly
	states.init(self)

func freeze() -> void:
	states.Freeze
	print("Test")

func death() -> void:
		Engine.time_scale = 0.5
		self.get_node("CollisionShape2D").queue_free()
		death_timer.start()
		Globals.score = 0
		
	
func _unhandled_input(event: InputEvent) -> void:
	states.process_input(event)
	
	
func _physics_process(delta: float) -> void:
	states.process_physics(delta)
	

func _process(delta: float) -> void:
	states.process_frame(delta)
	

func _on_death_timer_timeout() -> void:
	Engine.time_scale = 1.0
	get_tree().reload_current_scene()
#endregion

The freeze function I added gives me this error:

image

What should my approach be?

Your errors describe a very different line of code, like you wrote Player.freeze() instead of body.freeze(). However I highly doubt this function does change states, you may even get a warning along the lines of “Statement has no effect”; but I do not know how you set up your state machine.

func freeze() -> void:
	states.Freeze
	print("Test")
1 Like

Yes, you’re correct, I have gotten that error!

image

And you were also right that I mistyped the body.freeze() function. The print statement works, at least, so I can call the function. Now I just need to force it into what state I want.

I was able to freeze the player!


func _on_body_entered(body: Node2D) -> void:
	if body is Player:
		body.freeze()
		body.set_physics_process(false) 
		body.set_process_input(false)
		body.set_process_unhandled_input(false)
		$"../AnimationPlayer".play("FadeIn")


Its not exactly what I wanted with the call to a new state but I’ll settle for this for now, thanks to your help. Thank you!

1 Like