Transition

This commit is contained in:
2025-07-01 11:45:48 -05:00
parent c7bed57b82
commit 977f17f73b
12 changed files with 237 additions and 23 deletions

View File

@@ -20,6 +20,7 @@ config/icon="res://icon.svg"
PHYSICS="*res://scripts/singletons/GamePhysics.gd"
UI="*res://scenes/singletons/UI.tscn"
PAUSE="*res://scripts/singletons/Pause.gd"
TRANSITION="*res://scenes/singletons/Transition.tscn"
[debug]

View File

@@ -38,10 +38,11 @@ point_count = 2
[node name="Player" parent="." instance=ExtResource("2_rlkm5")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.06402, 1.54702, -2.35884)
[node name="NPC" parent="." node_paths=PackedStringArray("cutscene") instance=ExtResource("4_nb1wl")]
[node name="NPC" parent="." node_paths=PackedStringArray("interactCamera") instance=ExtResource("4_nb1wl")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.20455, 1.94676, -3.51349)
interactType = 2
cutscene = NodePath("../Cutscenes/TestCutscene")
interactType = 1
interactTexts = Array[String](["test"])
interactCamera = NodePath("../TestChatCamera")
[node name="Camera3D" type="Camera3D" parent="." node_paths=PackedStringArray("targetFollow", "pathFollow", "pathMap")]
transform = Transform3D(0.996991, 0.0418507, -0.0652558, 0, 0.841762, 0.539849, 0.0775229, -0.538225, 0.839228, 1.25757, 8.21861, 8.01254)
@@ -52,6 +53,10 @@ pathFollow = NodePath("../PathCamera/PathFollow3D")
pathMap = NodePath("../PathWorld")
metadata/_custom_type_script = "uid://csb0i132lcu0w"
[node name="TestChatCamera" type="Camera3D" parent="."]
transform = Transform3D(0.854722, 0.231437, -0.464637, 0, 0.895106, 0.445854, 0.519087, -0.381081, 0.765066, -6.8472, 4.22457, 0.61366)
fov = 47.0
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_m5dm6")

View File

@@ -18,7 +18,6 @@ size = Vector3(0.705444, 0.680542, 1.17688)
[node name="Player" type="CharacterBody3D"]
script = ExtResource("1_24gqh")
metadata/_custom_type_script = "uid://c0by5m1upv57h"
[node name="Scripts" type="Node" parent="."]
@@ -26,9 +25,10 @@ metadata/_custom_type_script = "uid://c0by5m1upv57h"
script = ExtResource("2_o7et6")
player = NodePath("../..")
[node name="PlayerInteraction" type="Node" parent="Scripts" node_paths=PackedStringArray("interactableArea")]
[node name="PlayerInteraction" type="Node" parent="Scripts" node_paths=PackedStringArray("interactableArea", "player")]
script = ExtResource("3_24gqh")
interactableArea = NodePath("../../InteractableArea")
player = NodePath("../..")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("CapsuleShape3D_2m2ha")

View File

@@ -0,0 +1,20 @@
[gd_scene load_steps=2 format=3 uid="uid://i4ukelrrsujw"]
[ext_resource type="Script" uid="uid://iu3m73wtjlho" path="res://scripts/singletons/Transition.gd" id="1_isjic"]
[node name="Transition" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_isjic")
[node name="Overlay" type="ColorRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2

View File

@@ -1,3 +1,3 @@
class_name InteractableArea extends Area3D
signal interactEvent
signal interactEvent(playerEntity:Player)

View File

@@ -8,46 +8,146 @@ enum InteractType {
# Movement speed in units per second
@export var gravity: float = 24.8
@export var interactType:InteractType = InteractType.NONE
@export_multiline var interactTexts:Array[String] = []
@export var npcLookAtPlayer:bool = true
@export var playerLookAtNPC:bool = true
@export var interactCamera:Camera3D = null
@export var cutscene:Cutscene = null
var nextTextIndex:int = 0
var previousCamera:Camera3D = null
var playerEnt:Player
var conversationEnding:bool = false
func lookAtPlayer() -> void:
if !playerEnt:
return
# Get player position and NPC position
var playerPos = playerEnt.global_transform.origin
var npcPos = global_transform.origin
# Rotate the NPC to look at the player
if npcLookAtPlayer:
var npcDirection = (playerPos - npcPos).normalized()
var npcRotation = Vector3(0, atan2(npcDirection.x, npcDirection.z), 0)
global_transform.basis = Basis.from_euler(npcRotation)
# Rotate the player to look at the NPC
if playerLookAtNPC:
var playerDirection = (npcPos - playerPos).normalized()
var playerRotation = Vector3(0, atan2(playerDirection.x, playerDirection.z), 0)
playerEnt.global_transform.basis = Basis.from_euler(playerRotation)
func showTexts():
TRANSITION.fadeOutStart.disconnect(showTexts)
# Any texts?
if interactTexts.size() == 0:
endTexts()
return
# First text.
UI.TEXTBOX.setText(interactTexts[nextTextIndex])
UI.TEXTBOX.textboxClosing.connect(onTextboxClosing)
func endTexts():
UI.TEXTBOX.textboxClosing.disconnect(onTextboxClosing)
conversationEnding = true
# Do we fade out the camera?
if interactCamera:
TRANSITION.fade(TRANSITION.FadeType.FADE_OUT)
TRANSITION.fadeOutEnd.connect(onFadeOutEnd)
return
# Reset Camera?
if previousCamera:
previousCamera.current = true
previousCamera = null
func _enter_tree() -> void:
$InteractableArea.interactEvent.connect(_on_interact)
$InteractableArea.interactEvent.connect(onInteract)
func _exit_tree() -> void:
$InteractableArea.interactEvent.disconnect(_on_interact)
$InteractableArea.interactEvent.disconnect(onInteract)
UI.TEXTBOX.textboxClosing.disconnect(onTextboxClosing)
TRANSITION.fadeOutEnd.disconnect(onFadeOutEnd)
TRANSITION.fadeInEnd.disconnect(onFadeInEnd)
func _physics_process(delta):
# Apply gravity if not on floor
if !is_on_floor():
velocity += PHYSICS.GRAVITY * delta
move_and_slide()
func _on_interact() -> void:
func onInteract(playerEntity:Player) -> void:
# Reset state
previousCamera = null
nextTextIndex = 0
playerEnt = playerEntity
conversationEnding = false
match interactType:
InteractType.TEXTBOX:
if interactTexts.size() == 0:
PAUSE.cutscenePause()
# If a camera is set, switch to it, otherwise chat immediately.
if !interactCamera:
showTexts()
return
UI.TEXTBOX.setText(interactTexts[nextTextIndex])
UI.TEXTBOX.textboxClosing.connect(onTextboxClosing)
return
# Fade out.
TRANSITION.fade(TRANSITION.FadeType.FADE_OUT)
TRANSITION.fadeOutEnd.connect(onFadeOutEnd)
InteractType.CUTSCENE:
if cutscene:
cutscene.start()
return
if !cutscene:
return
cutscene.start()
_:
return
func onTextboxClosing() -> void:
nextTextIndex += 1
# More text?
if nextTextIndex < interactTexts.size():
UI.TEXTBOX.setText(interactTexts[nextTextIndex])
else:
UI.TEXTBOX.textboxClosing.disconnect(onTextboxClosing)
endTexts()
func onFadeOutEnd() -> void:
# Begin fade back in.
TRANSITION.fadeOutEnd.disconnect(onFadeOutEnd)
TRANSITION.fade(TRANSITION.FadeType.FADE_IN)
TRANSITION.fadeInEnd.connect(onFadeInEnd)
# Is the conversation ending?
if conversationEnding:
# Reset camera.
if previousCamera:
previousCamera.current = true
previousCamera = null
return
# No! We are starting the conversation, make the ents look at each other
lookAtPlayer()
# Change camera
previousCamera = get_viewport().get_camera_3d()
interactCamera.current = true
func onFadeInEnd() -> void:
TRANSITION.fadeInEnd.disconnect(onFadeInEnd)
# Did the conversation end?
if conversationEnding:
PAUSE.cutsceneResume()
return
# Show texts after fade in.
showTexts()

View File

View File

@@ -1,6 +1,7 @@
class_name PlayerInteraction extends Node
@export var interactableArea:Area3D
@export var player:CharacterBody3D
func canInteract() -> bool:
if PAUSE.isMovementPaused():
@@ -26,4 +27,4 @@ func _process(delta: float) -> void:
if !interactable:
return
interactable.interactEvent.emit()
interactable.interactEvent.emit(player)

View File

@@ -5,9 +5,6 @@ const SPEED = 8.0
@export var player:CharacterBody3D
func _ready() -> void:
player = get_parent().get_parent()
func canMove() -> bool:
if PAUSE.isMovementPaused():
return false

View File

@@ -1,6 +1,16 @@
class_name PauseSingleton extends Node
var cutscenePaused:bool = false
func cutscenePause() -> void:
cutscenePaused = true
func cutsceneResume() -> void:
cutscenePaused = false
func isMovementPaused() -> bool:
if cutscenePaused:
return true
if !UI.TEXTBOX.isClosed:
return true
return false

View File

@@ -0,0 +1,79 @@
class_name TransitionSingleton extends Control
enum FadeType {
NONE,
FADE_IN,
FADE_OUT
}
signal fadeOutStart
signal fadeOutEnd
signal fadeInStart
signal fadeInEnd
signal fadeUpdate(t:float)
var fadeType:FadeType = FadeType.NONE
var fadeDuration:float = 0.4
var fadeTime:float = 0.0
func _enter_tree() -> void:
$Overlay.visible = false
func _process(delta: float) -> void:
if fadeType == FadeType.NONE:
return
fadeTime += delta
var t:float = fadeTime / fadeDuration
# Get destination alpha type.
var destAlpha:float = 0.0
var srcAlpha:float
if fadeType == FadeType.FADE_IN:
srcAlpha = 1.0
destAlpha = 0.0
elif fadeType == FadeType.FADE_OUT:
srcAlpha = 0.0
destAlpha = 1.0
# End?
if t >= 1.0:
fadeUpdate.emit(1.0)
var cFade = fadeType
print("Transition: Fade complete")
fadeType = FadeType.NONE
if cFade == FadeType.FADE_OUT:
$Overlay.visible = true
fadeOutEnd.emit()
elif cFade == FadeType.FADE_IN:
$Overlay.visible = false
fadeInEnd.emit()
$Overlay.color.a = destAlpha
return
# TODO: Use curves
$Overlay.color.a = srcAlpha + (destAlpha - srcAlpha) * t
fadeUpdate.emit(t)
pass
func fade(
fade:FadeType = FadeType.FADE_IN,
duration:float = 0.4,
color:Color = Color(0, 0, 0, 1),
):
$Overlay.visible = false
$Overlay.color = color
fadeDuration = duration
fadeTime = 0
fadeType = fade
if fade == FadeType.FADE_IN:
fadeInStart.emit()
$Overlay.color.a = 0
elif fade == FadeType.FADE_OUT:
fadeOutStart.emit()
$Overlay.color.a = 1
$Overlay.visible = true

View File

@@ -0,0 +1 @@
uid://iu3m73wtjlho