Merge branch 'main' into DamianBranch

This commit is contained in:
2025-10-13 10:17:54 +00:00
24 changed files with 4634 additions and 2074 deletions

View File

@@ -1,14 +1,12 @@
using Bootstrap;
using System;
using UnityEditor;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.InputSystem;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.Playables;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace CinematicsM
namespace Cinematics
{
/// <summary>
/// Handles loading, playing and unloading cinematics
@@ -20,6 +18,10 @@ namespace CinematicsM
private Image cinematicSprites;
public PlayableAsset cinematicToPlay;
// Dictionary to track addressable handles by PlayableDirector
private Dictionary<PlayableDirector, AsyncOperationHandle<PlayableAsset>> _addressableHandles
= new Dictionary<PlayableDirector, AsyncOperationHandle<PlayableAsset>>();
public static CinematicsManager Instance
{
get
@@ -41,8 +43,24 @@ namespace CinematicsM
private void OnEnable()
{
// Subscribe to application quit event to ensure cleanup
Application.quitting += OnApplicationQuit;
}
private void OnDisable()
{
// Unsubscribe from application quit event
Application.quitting -= OnApplicationQuit;
// Clean up any remaining addressable handles when disabled
ReleaseAllHandles();
}
private void OnApplicationQuit()
{
ReleaseAllHandles();
}
/// <summary>
/// Plays a cinematic from an object reference and returns the PlayableDirector playing the timeline
/// </summary>
@@ -59,6 +77,9 @@ namespace CinematicsM
{
cinematicSprites.enabled = false;
Debug.Log("Cinematic stopped!");
// Release the addressable handle associated with this director
ReleaseAddressableHandle(director);
}
/// <summary>
@@ -66,18 +87,73 @@ namespace CinematicsM
/// </summary>
public PlayableDirector LoadAndPlayCinematic(string key)
{
// Load the asset via addressables
var handle = Addressables.LoadAssetAsync<PlayableAsset>(key);
var result = handle.WaitForCompletion();
// Store the handle for later release
_addressableHandles[playableDirector] = handle;
Debug.Log($"[CinematicsManager] Loaded addressable cinematic: {key}");
return PlayCinematic(result);
}
// Update is called once per frame
void Update()
{
}
private void Awake()
/// <summary>
/// Skips the currently playing cinematic if one is active
/// </summary>
public void SkipCurrentCinematic()
{
if (playableDirector != null && playableDirector.state == PlayState.Playing)
{
Debug.Log("Skipping current cinematic");
playableDirector.Stop();
}
}
/// <summary>
/// Checks if a cinematic is currently playing
/// </summary>
public bool IsCinematicPlaying()
{
return playableDirector != null && playableDirector.state == PlayState.Playing;
}
/// <summary>
/// Releases the addressable handle associated with a specific PlayableDirector
/// </summary>
private void ReleaseAddressableHandle(PlayableDirector director)
{
if (_addressableHandles.TryGetValue(director, out var handle))
{
Debug.Log($"[CinematicsManager] Releasing addressable handle for cinematic");
Addressables.Release(handle);
_addressableHandles.Remove(director);
}
}
/// <summary>
/// Releases all active addressable handles
/// </summary>
private void ReleaseAllHandles()
{
foreach (var handle in _addressableHandles.Values)
{
if (handle.IsValid())
{
Addressables.Release(handle);
}
}
_addressableHandles.Clear();
}
private void Start()
{
if (!SceneManager.GetActiveScene().name.ToLower().Contains("mainmenu"))
{
return;
}
_instance = this;
if (!SceneManager.GetActiveScene().name.ToLower().Contains("mainmenu"))

View File

@@ -0,0 +1,112 @@
using Input;
using UnityEngine;
using UnityEngine.UI;
namespace Cinematics
{
public class SkipCinematic : MonoBehaviour, ITouchInputConsumer
{
[Header("Configuration")]
[SerializeField] private float holdDuration = 2.0f;
[SerializeField] private Image radialProgressBar;
private float _holdStartTime;
private bool _isHolding;
private bool _skipPerformed;
void Start()
{
// Reset the progress bar
if (radialProgressBar != null)
{
radialProgressBar.fillAmount = 0f;
}
}
void OnEnable()
{
// Register as override consumer when enabled
InputManager.Instance.RegisterOverrideConsumer(this);
}
void OnDisable()
{
// Unregister when disabled
InputManager.Instance.UnregisterOverrideConsumer(this);
}
void Update()
{
// Only process while cinematic is playing and we're holding
if (_isHolding && CinematicsManager.Instance.IsCinematicPlaying())
{
float holdTime = Time.time - _holdStartTime;
float progress = Mathf.Clamp01(holdTime / holdDuration);
// Update progress bar
if (radialProgressBar != null)
{
radialProgressBar.fillAmount = progress;
}
// Check if we've held long enough to skip
if (progress >= 1.0f && !_skipPerformed)
{
_skipPerformed = true;
DoSkipCinematic();
}
}
}
private void DoSkipCinematic()
{
CinematicsManager.Instance.SkipCurrentCinematic();
Debug.Log("Cinematic skipped via touch hold");
// Reset UI
if (radialProgressBar != null)
{
radialProgressBar.fillAmount = 0f;
}
// Remember to clear up input override
InputManager.Instance.UnregisterOverrideConsumer(this);
}
#region ITouchInputConsumer Implementation
public void OnTap(Vector2 position)
{
// Not using tap for skipping
}
public void OnHoldStart(Vector2 position)
{
// Start tracking hold time
_isHolding = true;
_skipPerformed = false;
_holdStartTime = Time.time;
Debug.Log("Starting cinematic skip gesture");
}
public void OnHoldMove(Vector2 position)
{
// Hold movement is tracked in Update method
}
public void OnHoldEnd(Vector2 position)
{
// Reset state when hold ends
_isHolding = false;
// Reset UI
if (radialProgressBar != null)
{
radialProgressBar.fillAmount = 0f;
}
Debug.Log("Cinematic skip gesture canceled");
}
#endregion
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5526348c1593f9b43987b0edcaccdd24