Zunesha

Rewind para godot 4+

Jan 13th, 2026 (edited)
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
GDScript 4.31 KB | Gaming | 0 0
  1. #Sistema de Rewind para godot 4+
  2.  
  3. Como usar : crie um node2d  coloque ele como filho do node que deseja aplicar o efeito ,exemplo : o objeto player e coloque o script abaixo nele.Não esqueça de lincar as coisas no inspector :
  4.  
  5. # RewindComponent.gd
  6. extends Node
  7.  
  8. @export var target: Node2D                    # CharacterBody2D (jogador)
  9. @export var sprite: Sprite2D                  # Sprite2D filho
  10. @export var max_history: int = 300
  11. @export var record_rate: int = 1
  12. @export var rewind_step_time: float = 0.016   # ~60 fps
  13. @export var rewind_stop_offset: int = 30      # frames a parar antes do início
  14.  
  15. @onready var anim_player: AnimationPlayer = target.get_node("anin_player") if target else null
  16.  
  17. var state_history: Array[Dictionary] = []
  18. var is_recording: bool = false
  19. var is_rewinding: bool = false
  20. var frame_counter: int = 0
  21. var rewind_timer: float = 0.0
  22. var rewind_index: int = -1
  23.  
  24. func _ready() -> void:
  25.     if target == null:
  26.         target = get_parent() as Node2D
  27.         if target == null:
  28.             push_error("Target (Node2D) não encontrado!")
  29.             queue_free()
  30.             return
  31.    
  32.     if sprite == null:
  33.         sprite = target.get_node("Sprite") as Sprite2D
  34.         if sprite == null:
  35.             push_error("Sprite2D não encontrado!")
  36.             queue_free()
  37.             return
  38.    
  39.     anim_player = target.get_node("anin_player") as AnimationPlayer
  40.     if anim_player == null:
  41.         push_warning("AnimationPlayer 'anin_player' não encontrado!")
  42.  
  43.  
  44. func _physics_process(delta: float) -> void:
  45.     if is_rewinding:
  46.         rewind_timer += delta
  47.         if rewind_timer >= rewind_step_time:
  48.             rewind_timer -= rewind_step_time
  49.             apply_rewind_step()
  50.         return
  51.  
  52.     # Inputs (continuam funcionando normalmente)
  53.     if Input.is_action_just_pressed("record_toggle"):
  54.         if is_recording:
  55.             stop_recording()
  56.         else:
  57.             start_recording()
  58.  
  59.     if Input.is_action_just_pressed("record_stop"):
  60.         stop_recording()
  61.  
  62.     if Input.is_action_just_pressed("rewind") and not is_rewinding and not state_history.is_empty():
  63.         trigger_rewind()
  64.  
  65.     if is_recording:
  66.         frame_counter += 1
  67.         if frame_counter % record_rate == 0:
  68.             state_history.append({
  69.                 "position": target.global_position,
  70.                 "texture": sprite.texture,
  71.                 "frame": sprite.frame,
  72.                 "scale": sprite.scale,
  73.                 "hframes": sprite.hframes
  74.             })
  75.             if state_history.size() > max_history:
  76.                 state_history.remove_at(0)
  77.  
  78.  
  79. # Funções públicas para chamar de outros scripts
  80. func start_recording() -> void:
  81.     if is_recording or is_rewinding:
  82.         return  # Evita iniciar gravação durante rewind ou já gravando
  83.    
  84.     state_history.clear()  # Descarta rewind anterior
  85.     frame_counter = 0
  86.    
  87.     state_history.append({
  88.         "position": target.global_position,
  89.         "texture": sprite.texture,
  90.         "frame": sprite.frame,
  91.         "scale": sprite.scale,
  92.         "hframes": sprite.hframes
  93.     })
  94.    
  95.     is_recording = true
  96.     print("Gravação INICIADA via função - Histórico limpo | Posição inicial: ", target.global_position)
  97.  
  98.  
  99. func stop_recording() -> void:
  100.     if not is_recording:
  101.         return
  102.    
  103.     is_recording = false
  104.     print("Gravação ENCERRADA via função")
  105.  
  106.  
  107. func trigger_rewind() -> void:
  108.     if is_rewinding or state_history.is_empty():
  109.         print("Rewind ignorado: já rebobinando ou sem histórico")
  110.         return
  111.    
  112.     is_rewinding = true
  113.     is_recording = false
  114.     rewind_timer = 0.0
  115.     rewind_index = state_history.size() - 1
  116.     print("Rewind INICIADO via função - Total estados: ", state_history.size())
  117.  
  118.  
  119. func apply_rewind_step() -> void:
  120.     if rewind_index < rewind_stop_offset:
  121.         finish_rewind()
  122.         return
  123.  
  124.     var state = state_history[rewind_index]
  125.     target.global_position = state["position"]
  126.     sprite.texture = state["texture"]
  127.     sprite.frame = state["frame"]
  128.     sprite.scale = state["scale"]
  129.     sprite.hframes = state["hframes"]
  130.     rewind_index -= 1
  131.  
  132.  
  133. func finish_rewind() -> void:
  134.     is_rewinding = false
  135.    
  136.     if anim_player != null:
  137.         var direcao = main.direcao_inicial_player
  138.         if direcao == Vector2.RIGHT:
  139.             anim_player.play("idle_right")
  140.         elif direcao == Vector2.LEFT:
  141.             anim_player.play("idle_left")
  142.         elif direcao == Vector2.UP:
  143.             anim_player.play("idle_up")
  144.         elif direcao == Vector2.DOWN:
  145.             anim_player.play("idle_down")
  146.         else:
  147.             anim_player.play("idle_right")
  148.        
  149.        
  150.         print("Rewind FINALIZADO - Parou ", rewind_stop_offset, " frames antes | Animação: ", anim_player.current_animation)
  151.     else:
  152.         print("Rewind FINALIZADO - AnimationPlayer não encontrado")
  153.    
  154.  
Advertisement
Add Comment
Please, Sign In to add comment