From f7a2fb5c402f6fd23be221fd2c75038601e0b212 Mon Sep 17 00:00:00 2001 From: pyoneerC Date: Thu, 26 Sep 2024 14:21:35 -0300 Subject: [PATCH] feat: initial cutscene --- Assets/ProgressBar/Script/ProgressBar.cs | 85 +++++++- Assets/Scenes/Reparation.unity | 181 +++++++++++++++++- Assets/Scripts/Camera/CutsceneController.cs | 97 +++------- .../Character/FirstPersonController.cs | 2 +- 4 files changed, 286 insertions(+), 79 deletions(-) diff --git a/Assets/ProgressBar/Script/ProgressBar.cs b/Assets/ProgressBar/Script/ProgressBar.cs index ef0531b..dab8fd4 100644 --- a/Assets/ProgressBar/Script/ProgressBar.cs +++ b/Assets/ProgressBar/Script/ProgressBar.cs @@ -2,39 +2,106 @@ using UnityEngine.UI; using TMPro; +/// +/// Manages the behavior of a progress bar, including updating the fill amount, color, and title. +/// Can be used to visually represent a task's progress. +/// [ExecuteInEditMode] public class ProgressBar : MonoBehaviour { [Header("UI Components")] + [Tooltip("The background image of the progress bar.")] [SerializeField] private Image barBackground; + + [Tooltip("The image that represents the filled portion of the progress bar.")] [SerializeField] private Image bar; + + [Tooltip("The text component that displays the progress title.")] [SerializeField] private TextMeshProUGUI title; [Header("Settings")] + [Tooltip("The current value of the progress bar (0 to 100).")] [Range(0f, 100f)] [SerializeField] private float barValue = 20f; + + [Tooltip("The color of the filled portion of the progress bar.")] [SerializeField] private Color barColor = Color.green; + /// + /// Initializes the progress bar and updates the UI components based on the current value. + /// private void Start() { - if (bar == null || title == null) + ValidateComponents(); + UpdateProgressBar(barValue); + } + + /// + /// Updates the progress bar's fill amount, color, and text based on the provided value. + /// + /// The current progress value (0 to 100). + private void UpdateProgressBar(float value) + { + // Ensure the value is clamped between 0 and 100. + value = Mathf.Clamp(value, 0f, 100f); + + if (bar != null) + { + // Update the bar's fill amount and color. + bar.fillAmount = value / 100f; + bar.color = barColor; + } + + if (title != null) { - Debug.LogError("Bar or Title component is missing."); - return; + // Update the title text to reflect the current value. + title.text = $"Fixing... ({value:F0}%)"; } + } + /// + /// Called automatically by Unity whenever a serialized field is modified in the Inspector. + /// Ensures that changes in the Inspector are immediately reflected in the UI. + /// + private void OnValidate() + { + ValidateComponents(); UpdateProgressBar(barValue); } - private void UpdateProgressBar(float value) + /// + /// Validates that all required UI components (bar, title) are assigned, and logs an error if any are missing. + /// + private void ValidateComponents() { - bar.fillAmount = value / 100f; - bar.color = barColor; - title.text = $"Fixing... ({value:F0}%)"; + if (bar == null) + { + Debug.LogError("Bar component is missing. Please assign a valid Image for the progress bar."); + } + + if (title == null) + { + Debug.LogError("Title component is missing. Please assign a valid TextMeshProUGUI for the title."); + } } - private void OnValidate() + /// + /// Sets the value of the progress bar and updates the UI accordingly. + /// + /// The new progress value (0 to 100). + public void SetValue(float newValue) + { + barValue = newValue; + UpdateProgressBar(barValue); + } + + /// + /// Sets the color of the progress bar and updates the UI accordingly. + /// + /// The new color for the filled portion of the progress bar. + public void SetColor(Color newColor) { + barColor = newColor; UpdateProgressBar(barValue); } -} \ No newline at end of file +} diff --git a/Assets/Scenes/Reparation.unity b/Assets/Scenes/Reparation.unity index 0f291c3..3bc1560 100644 --- a/Assets/Scenes/Reparation.unity +++ b/Assets/Scenes/Reparation.unity @@ -2550,7 +2550,7 @@ PrefabInstance: objectReference: {fileID: 1475119614} - target: {fileID: 114769781544105922, guid: 5eefba205a58c8c4a937c97b87c185a3, type: 3} propertyPath: barValue - value: 86.2 + value: 46.4 objectReference: {fileID: 0} - target: {fileID: 114769781544105922, guid: 5eefba205a58c8c4a937c97b87c185a3, type: 3} propertyPath: m_Enabled @@ -17905,6 +17905,9 @@ PrefabInstance: - targetCorrespondingSourceObject: {fileID: 4459864850019384750, guid: 6bacecc4f3df9584198879c73a6b6c36, type: 3} insertIndex: -1 addedObject: {fileID: 1128651451} + - targetCorrespondingSourceObject: {fileID: 4459864850019384750, guid: 6bacecc4f3df9584198879c73a6b6c36, type: 3} + insertIndex: -1 + addedObject: {fileID: 1128651459} - targetCorrespondingSourceObject: {fileID: 4459864851310106424, guid: 6bacecc4f3df9584198879c73a6b6c36, type: 3} insertIndex: -1 addedObject: {fileID: 848670200} @@ -17958,6 +17961,11 @@ MonoBehaviour: m_MipBias: 0 m_VarianceClampScale: 0.9 m_ContrastAdaptiveSharpening: 0 +--- !u!20 &848670201 stripped +Camera: + m_CorrespondingSourceObject: {fileID: 4459864851310106426, guid: 6bacecc4f3df9584198879c73a6b6c36, type: 3} + m_PrefabInstance: {fileID: 848670198} + m_PrefabAsset: {fileID: 0} --- !u!1001 &849679832 PrefabInstance: m_ObjectHideFlags: 0 @@ -24698,7 +24706,21 @@ MonoBehaviour: m_EditorClassIdentifier: welderPrefab: {fileID: 1071434719} rayDistance: 100 - playerCamera: {fileID: 0} + playerCamera: {fileID: 848670201} +--- !u!114 &1128651459 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 635657467} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4a01d43f8d9f455193df9fb30c944807, type: 3} + m_Name: + m_EditorClassIdentifier: + splineParent: {fileID: 2055782988} + speed: 0.1 --- !u!4 &1130256303 stripped Transform: m_CorrespondingSourceObject: {fileID: -5819118886272102141, guid: e0f672a015f8fee418afd70dfd718f0d, type: 3} @@ -32515,7 +32537,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_text: Fixing... (86%) + m_text: Fixing... (46%) m_isRightToLeft: 0 m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} @@ -33171,6 +33193,7 @@ Transform: - {fileID: 557190189} - {fileID: 1964668404} - {fileID: 2098095642} + - {fileID: 2055782988} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1497520578 @@ -45694,6 +45717,158 @@ PrefabInstance: m_AddedGameObjects: [] m_AddedComponents: [] m_SourcePrefab: {fileID: 9199261849990390558, guid: 95d3d6bd77177bd4b978473257fc8079, type: 3} +--- !u!1 &2055782987 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2055782988} + - component: {fileID: 2055782989} + m_Layer: 0 + m_Name: Camera Cutscene Spline + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2055782988 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2055782987} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 3.1365824, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1495273419} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &2055782989 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2055782987} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dab5c7d4c32e743048dfca98e2d5914f, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Spline: + m_EditModeType: 1 + m_Knots: [] + m_MetaData: [] + m_Closed: 0 + m_IntData: + m_Data: [] + m_FloatData: + m_Data: [] + m_Float4Data: + m_Data: [] + m_ObjectData: + m_Data: [] + m_Splines: + - m_EditModeType: 1 + m_Knots: + - Position: + x: 43.720047 + y: -18.72 + z: -79.8086 + TangentIn: + x: 0 + y: 0 + z: -24.665 + TangentOut: + x: 0 + y: 0 + z: 24.665 + Rotation: + value: + x: 0 + y: -0.3112445 + z: -0 + w: 0.95032984 + - Position: + x: 14.590047 + y: -20 + z: 13.361394 + TangentIn: + x: 0 + y: 0 + z: -16.995 + TangentOut: + x: 0 + y: 0 + z: 16.995 + Rotation: + value: + x: 0 + y: 0.87226963 + z: 0 + w: -0.48902518 + - Position: + x: -32.409954 + y: -38.78 + z: -23.638607 + TangentIn: + x: 0 + y: 0 + z: -7.6307874 + TangentOut: + x: 0 + y: 0 + z: 7.6307874 + Rotation: + value: + x: 0 + y: 0.965639 + z: 0 + w: -0.25988716 + - Position: + x: -50.409954 + y: -34.1 + z: -92.6386 + TangentIn: + x: 0 + y: 0 + z: -22.576 + TangentOut: + x: 0 + y: 0 + z: 22.576 + Rotation: + value: + x: 0 + y: 0.9727732 + z: 0 + w: 0.23175892 + m_MetaData: + - Mode: 2 + Tension: 0.5 + - Mode: 2 + Tension: 0.5 + - Mode: 2 + Tension: 0.5 + - Mode: 2 + Tension: 0.5 + m_Closed: 1 + m_IntData: + m_Data: [] + m_FloatData: + m_Data: [] + m_Float4Data: + m_Data: [] + m_ObjectData: + m_Data: [] + m_Knots: + m_KnotsLink: [] --- !u!1001 &2056055168 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Camera/CutsceneController.cs b/Assets/Scripts/Camera/CutsceneController.cs index ba12412..1f55c88 100644 --- a/Assets/Scripts/Camera/CutsceneController.cs +++ b/Assets/Scripts/Camera/CutsceneController.cs @@ -1,4 +1,5 @@ using UnityEngine; +using UnityEngine.Splines; /// /// Manages the cutscene sequence by controlling the cutscene camera's movement @@ -7,89 +8,53 @@ /// public class CutsceneController : MonoBehaviour { - /// - /// The camera used for the cutscene. - /// - public Camera cutsceneCamera; + private Camera playerCamera; // Regular gameplay camera + public Transform splineParent; // The parent GameObject that controls the spline path + public float speed = 1.0f; // Speed at which the cutscene camera follows the spline - /// - /// The camera used for regular gameplay. - /// - public Camera playerCamera; + private Camera cutsceneCamera; // Camera for the cutscene + private SplineContainer splineContainer; // Reference to the spline + private float duration = 8.0f; // Duration of the cutscene + private float elapsedTime = 0f; // Time elapsed since the start of the cutscene - /// - /// The parent GameObject that controls the spline path for the cutscene. - /// - public Transform splineParent; - - /// - /// The speed at which the cutscene camera follows the spline. - /// - public float speed = 1.0f; - - /// - /// Duration of the cutscene in seconds. - /// - private float duration = 6.0f; - - /// - /// Time elapsed since the start of the cutscene. - /// - private float elapsedTime = 0f; - - /// - /// Starting position of the cutscene camera. - /// - private Vector3 startPosition; - - /// - /// Target position for the cutscene camera to move towards. - /// - private Vector3 targetPosition; - - /// - /// Initializes the cutscene by setting the appropriate cameras and calculating - /// the target position along the spline. - /// - void Start() + private void Start() { - // Disable the player camera and enable the cutscene camera to start the cutscene - playerCamera.gameObject.SetActive(false); + playerCamera = Camera.main; + cutsceneCamera = new GameObject("Cutscene Camera").AddComponent(); cutsceneCamera.gameObject.SetActive(true); + playerCamera.gameObject.SetActive(false); - // Store the initial position of the cutscene camera - startPosition = cutsceneCamera.transform.position; - - // Set the target position to the position of the spline parent - targetPosition = splineParent.position; // Modify this to follow a specific point on your spline if needed + splineContainer = splineParent.GetComponent(); + if (splineContainer != null) return; + Debug.LogError("No SplineContainer found on the spline parent."); + return; } - /// - /// Updates the cutscene camera's position over time, and switches back to the - /// player camera once the cutscene duration is reached. - /// - void Update() + private void Update() { - // Accumulate the time elapsed since the start of the cutscene elapsedTime += Time.deltaTime; - // Move the cutscene camera along the spline until the duration is reached if (elapsedTime < duration) { - // Calculate the interpolation factor (t) based on elapsed time - float t = elapsedTime / duration; + // Normalize the elapsed time to a 0-1 range + float normalizedTime = elapsedTime / duration; + + // Get normalized progress along the spline (from 0 to 1) + float splineProgress = normalizedTime; + + // Move the camera along the spline based on progress + Vector3 targetPosition = splineContainer.EvaluatePosition(splineProgress); + Vector3 targetDirection = splineContainer.EvaluateTangent(splineProgress); - // Move the camera towards the target position using linear interpolation - cutsceneCamera.transform.position = Vector3.Lerp(startPosition, targetPosition, t); + // Set camera position and rotation along the spline + cutsceneCamera.transform.position = targetPosition; + cutsceneCamera.transform.rotation = Quaternion.LookRotation(targetDirection); } else { - // Once the cutscene duration has elapsed, destroy the cutscene camera - // and re-enable the player camera - Destroy(cutsceneCamera.gameObject); + // After cutscene duration, switch back to the player camera playerCamera.gameObject.SetActive(true); - - // Disable this script to prevent further updates + Destroy(cutsceneCamera.gameObject); enabled = false; } } diff --git a/Assets/Scripts/Character/FirstPersonController.cs b/Assets/Scripts/Character/FirstPersonController.cs index e3666c0..04ff334 100644 --- a/Assets/Scripts/Character/FirstPersonController.cs +++ b/Assets/Scripts/Character/FirstPersonController.cs @@ -413,7 +413,7 @@ void FixedUpdate() if (hideBarWhenFull && Mathf.Approximately(_sprintRemaining, sprintDuration)) { - _sprintBarCg.alpha -= 3 * Time.deltaTime; + //_sprintBarCg.alpha -= 3 * Time.deltaTime; } targetVelocity = transform.TransformDirection(targetVelocity) * walkSpeed;