progress.
This commit is contained in:
274
addons/cutscene_editor/editor/PreviewManager.gd
Normal file
274
addons/cutscene_editor/editor/PreviewManager.gd
Normal file
@@ -0,0 +1,274 @@
|
||||
@tool
|
||||
class_name PreviewManager
|
||||
extends Node
|
||||
|
||||
# Manager for real-time cutscene preview
|
||||
|
||||
# Signals
|
||||
signal preview_started()
|
||||
signal preview_stopped()
|
||||
signal preview_paused()
|
||||
signal preview_resumed()
|
||||
signal preview_progress(progress: float)
|
||||
signal node_activated(node_name: String)
|
||||
signal node_completed(node_name: String)
|
||||
|
||||
# Properties
|
||||
var is_previewing: bool = false
|
||||
var is_paused: bool = false
|
||||
var current_cutscene: CutsceneManager
|
||||
var preview_scene: Node2D # The scene being previewed
|
||||
var preview_characters: Dictionary = {} # Map of character names to nodes
|
||||
var graph_edit: CutsceneGraphEdit # Reference to the graph editor
|
||||
|
||||
# Preview settings
|
||||
var preview_speed: float = 1.0
|
||||
var show_debug_info: bool = true
|
||||
|
||||
# Initialize the preview manager
|
||||
func _init() -> void:
|
||||
name = "PreviewManager"
|
||||
|
||||
# Set up the preview with a graph editor
|
||||
func setup_preview(graph: CutsceneGraphEdit) -> void:
|
||||
graph_edit = graph
|
||||
|
||||
# Connect to graph change signals
|
||||
if graph_edit:
|
||||
graph_edit.connect("graph_changed", _on_graph_changed)
|
||||
|
||||
# Start the preview
|
||||
func start_preview() -> void:
|
||||
if is_previewing:
|
||||
return
|
||||
|
||||
# Create preview scene
|
||||
_setup_preview_scene()
|
||||
|
||||
# Generate cutscene from current graph
|
||||
var cutscene_resource = graph_edit.save_to_cutscene()
|
||||
var generator = CutsceneGenerator.new()
|
||||
current_cutscene = generator.generate_cutscene(cutscene_resource)
|
||||
|
||||
# Add cutscene to preview scene
|
||||
if preview_scene and current_cutscene:
|
||||
preview_scene.add_child(current_cutscene)
|
||||
|
||||
# Connect to cutscene signals for feedback
|
||||
_connect_cutscene_signals()
|
||||
|
||||
# Start the cutscene
|
||||
current_cutscene.start()
|
||||
|
||||
# Update state
|
||||
is_previewing = true
|
||||
is_paused = false
|
||||
emit_signal("preview_started")
|
||||
|
||||
# Stop the preview
|
||||
func stop_preview() -> void:
|
||||
if not is_previewing:
|
||||
return
|
||||
|
||||
# Stop the cutscene
|
||||
if current_cutscene:
|
||||
current_cutscene.stop()
|
||||
_disconnect_cutscene_signals()
|
||||
|
||||
# Remove from preview scene
|
||||
if current_cutscene.get_parent() == preview_scene:
|
||||
preview_scene.remove_child(current_cutscene)
|
||||
current_cutscene.queue_free()
|
||||
|
||||
# Clean up preview scene
|
||||
_cleanup_preview_scene()
|
||||
|
||||
# Update state
|
||||
is_previewing = false
|
||||
is_paused = false
|
||||
emit_signal("preview_stopped")
|
||||
|
||||
# Pause the preview
|
||||
func pause_preview() -> void:
|
||||
if not is_previewing or is_paused:
|
||||
return
|
||||
|
||||
if current_cutscene:
|
||||
current_cutscene.pause()
|
||||
is_paused = true
|
||||
emit_signal("preview_paused")
|
||||
|
||||
# Resume the preview
|
||||
func resume_preview() -> void:
|
||||
if not is_previewing or not is_paused:
|
||||
return
|
||||
|
||||
if current_cutscene:
|
||||
current_cutscene.resume()
|
||||
is_paused = false
|
||||
emit_signal("preview_resumed")
|
||||
|
||||
# Set preview speed
|
||||
func set_preview_speed(speed: float) -> void:
|
||||
preview_speed = speed
|
||||
# In a real implementation, this would affect the time scale
|
||||
# of the preview scene
|
||||
|
||||
# Set up the preview scene
|
||||
func _setup_preview_scene() -> void:
|
||||
# Create or reuse preview scene
|
||||
if not preview_scene:
|
||||
preview_scene = Node2D.new()
|
||||
preview_scene.name = "PreviewScene"
|
||||
add_child(preview_scene)
|
||||
|
||||
# Set up characters for preview
|
||||
_setup_preview_characters()
|
||||
|
||||
# Set up characters for preview
|
||||
func _setup_preview_characters() -> void:
|
||||
# Clear existing characters
|
||||
preview_characters.clear()
|
||||
|
||||
# Create placeholder characters for preview
|
||||
# In a real implementation, this would load actual character scenes
|
||||
var character1 = _create_preview_character("Character1", Vector2(100, 100))
|
||||
var character2 = _create_preview_character("Character2", Vector2(200, 100))
|
||||
|
||||
preview_characters["Character1"] = character1
|
||||
preview_characters["Character2"] = character2
|
||||
|
||||
# Add to preview scene
|
||||
if preview_scene:
|
||||
preview_scene.add_child(character1)
|
||||
preview_scene.add_child(character2)
|
||||
|
||||
# Create a preview character
|
||||
func _create_preview_character(name: String, position: Vector2) -> Node2D:
|
||||
var character = Node2D.new()
|
||||
character.name = name
|
||||
character.position = position
|
||||
|
||||
# Add a visual representation
|
||||
var sprite = Polygon2D.new()
|
||||
sprite.polygon = PackedVector2Array([
|
||||
Vector2(-10, -20),
|
||||
Vector2(-30, 0),
|
||||
Vector2(-10, 20),
|
||||
Vector2(10, 20),
|
||||
Vector2(30, 0),
|
||||
Vector2(10, -20)
|
||||
])
|
||||
sprite.color = Color(0.5, 0.7, 1.0)
|
||||
character.add_child(sprite)
|
||||
|
||||
return character
|
||||
|
||||
# Clean up the preview scene
|
||||
func _cleanup_preview_scene() -> void:
|
||||
# Remove characters
|
||||
for char_name in preview_characters:
|
||||
var character = preview_characters[char_name]
|
||||
if character.get_parent() == preview_scene:
|
||||
preview_scene.remove_child(character)
|
||||
character.queue_free()
|
||||
|
||||
preview_characters.clear()
|
||||
|
||||
# Connect to cutscene signals for feedback
|
||||
func _connect_cutscene_signals() -> void:
|
||||
if not current_cutscene:
|
||||
return
|
||||
|
||||
# Disconnect existing connections
|
||||
_disconnect_cutscene_signals()
|
||||
|
||||
# Connect to signals
|
||||
current_cutscene.connect("cutscene_started", _on_cutscene_started)
|
||||
current_cutscene.connect("cutscene_completed", _on_cutscene_completed)
|
||||
current_cutscene.connect("cutscene_paused", _on_cutscene_paused)
|
||||
current_cutscene.connect("cutscene_resumed", _on_cutscene_resumed)
|
||||
current_cutscene.connect("action_started", _on_action_started)
|
||||
current_cutscene.connect("action_completed", _on_action_completed)
|
||||
|
||||
# Disconnect from cutscene signals
|
||||
func _disconnect_cutscene_signals() -> void:
|
||||
if not current_cutscene:
|
||||
return
|
||||
|
||||
if current_cutscene.is_connected("cutscene_started", _on_cutscene_started):
|
||||
current_cutscene.disconnect("cutscene_started", _on_cutscene_started)
|
||||
if current_cutscene.is_connected("cutscene_completed", _on_cutscene_completed):
|
||||
current_cutscene.disconnect("cutscene_completed", _on_cutscene_completed)
|
||||
if current_cutscene.is_connected("cutscene_paused", _on_cutscene_paused):
|
||||
current_cutscene.disconnect("cutscene_paused", _on_cutscene_paused)
|
||||
if current_cutscene.is_connected("cutscene_resumed", _on_cutscene_resumed):
|
||||
current_cutscene.disconnect("cutscene_resumed", _on_cutscene_resumed)
|
||||
if current_cutscene.is_connected("action_started", _on_action_started):
|
||||
current_cutscene.disconnect("action_started", _on_action_started)
|
||||
if current_cutscene.is_connected("action_completed", _on_action_completed):
|
||||
current_cutscene.disconnect("action_completed", _on_action_completed)
|
||||
|
||||
# Handle graph changes
|
||||
func _on_graph_changed() -> void:
|
||||
# If we're previewing, restart the preview to reflect changes
|
||||
if is_previewing:
|
||||
stop_preview()
|
||||
start_preview()
|
||||
|
||||
# Handle cutscene started
|
||||
func _on_cutscene_started() -> void:
|
||||
emit_signal("preview_started")
|
||||
|
||||
# Handle cutscene completed
|
||||
func _on_cutscene_completed() -> void:
|
||||
emit_signal("preview_stopped")
|
||||
is_previewing = false
|
||||
is_paused = false
|
||||
|
||||
# Handle cutscene paused
|
||||
func _on_cutscene_paused() -> void:
|
||||
emit_signal("preview_paused")
|
||||
is_paused = true
|
||||
|
||||
# Handle cutscene resumed
|
||||
func _on_cutscene_resumed() -> void:
|
||||
emit_signal("preview_resumed")
|
||||
is_paused = false
|
||||
|
||||
# Handle action started
|
||||
func _on_action_started(action: Action) -> void:
|
||||
# Find the corresponding node in the graph and highlight it
|
||||
var node_name = _find_node_for_action(action)
|
||||
if node_name:
|
||||
emit_signal("node_activated", node_name)
|
||||
|
||||
# Update graph editor visualization
|
||||
if graph_edit:
|
||||
var node = graph_edit.get_node_or_null(node_name)
|
||||
if node and node.has_method("set_state"):
|
||||
node.set_state(BaseGraphNode.NodeState.ACTIVE)
|
||||
|
||||
# Handle action completed
|
||||
func _on_action_completed(action: Action) -> void:
|
||||
# Find the corresponding node in the graph and mark as completed
|
||||
var node_name = _find_node_for_action(action)
|
||||
if node_name:
|
||||
emit_signal("node_completed", node_name)
|
||||
|
||||
# Update graph editor visualization
|
||||
if graph_edit:
|
||||
var node = graph_edit.get_node_or_null(node_name)
|
||||
if node and node.has_method("set_state"):
|
||||
node.set_state(BaseGraphNode.NodeState.COMPLETED)
|
||||
|
||||
# Find node corresponding to an action
|
||||
func _find_node_for_action(action: Action) -> String:
|
||||
# This would need to map actions to nodes
|
||||
# In a real implementation, we would store this mapping when generating the cutscene
|
||||
# For now, we'll return a placeholder
|
||||
return ""
|
||||
|
||||
# Get the preview scene for display
|
||||
func get_preview_scene() -> Node2D:
|
||||
return preview_scene
|
||||
Reference in New Issue
Block a user