Files
monde-usage-unity/Assets/Scripts/Clickable.cs
2024-10-06 14:09:34 +02:00

270 lines
8.0 KiBLFS
C#

#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
[RequireComponent(typeof(Collider2D), typeof(Animator))]
public class Clickable : MonoBehaviour
{
[SerializeField] private string goToSubSceneName;
[SerializeField] private bool isDiscoverable = true;
[SerializeField] private int? discoveredSortingOrder;
private Animator animator;
[SerializeField] public bool discovered = false;
public VideoAsset firstVideoAsset;
public VideoAsset secondVideoAsset;
public List<VideoAsset> listRandomVideoAssets;
[SerializeField] private bool playRandomClipAfterFirst = false;
private List<VideoAsset> shuffledVideoAssets;
[SerializeField] private GameObject discoverParticlePrefab;
[SerializeField] private string discoverText;
[SerializeField]
private FloatingLabelDirection discoverTextDirection = FloatingLabelDirection.Up;
[SerializeField] private float discoverTextOffset = 1;
[SerializeField] private float discoverXTextOffset = 0;
private bool firstVideoPlayed = false;
delegate void onVideoEnd();
public UnityEvent OnClick;
[SerializeField] SchoolManager associatedStory;
private int playedVideoCount = 0;
private bool isTransitioning = false;
[SerializeField] private bool active = true;
private List<VideoAsset> AllVideoAssets => new List<VideoAsset> { firstVideoAsset, secondVideoAsset }.Concat(listRandomVideoAssets).ToList().FindAll(video => video != null);
private bool HasPlayedAllVideos()
{
List<VideoAsset> AllVideoAssets = new List<VideoAsset> { firstVideoAsset, secondVideoAsset }.Concat(listRandomVideoAssets).ToList().FindAll(video => video != null);
return AllVideoAssets.TrueForAll(video => video.PlayCount > 0);
}
public SubScene? AssociatedSubScene = null;
[SerializeField] private bool mute = false;
private SpriteRenderer spriteRenderer;
private int zindex = 0;
void Start()
{
animator = GetComponent<Animator>();
shuffledVideoAssets = new List<VideoAsset>(listRandomVideoAssets);
shuffledVideoAssets.Shuffle();
animator.Play("Idle", 0, UnityEngine.Random.Range(0.3f, 1f));
if (GameManager.singleton.AllUnlocked)
{
discovered = true;
}
spriteRenderer = GetComponent<SpriteRenderer>();
zindex = spriteRenderer.sortingOrder;
}
private FloatingLabel? floatingLabel;
public void Print()
{
Debug.Log("Clickable<" + gameObject.name + "> initialized with " + AllVideoAssets.Count + " video assets");
for (int i = 0; i < AllVideoAssets.Count; i++)
{
Debug.Log("VideoAsset " + i + ": " + AllVideoAssets[i].name + " played " + AllVideoAssets[i].PlayCount + " times");
}
}
// Hover
void OnMouseEnter()
{
if (!GameManager.singleton.CanPlay || isTransitioning) return;
if (active)
{
animator.SetBool("hover", true);
CameraManager.singleton.ShowHoverTexture();
if (!mute) GameManager.singleton.soundManager.PlayHoverSound();
}
if (discoverText != null && discoverText != "")
{
if (floatingLabel != null) Destroy(floatingLabel.gameObject);
floatingLabel = Instantiate(GameManager.singleton.floatingLabelPrefab, transform.position
+ new Vector3(discoverXTextOffset, 0, 0), Quaternion.identity).GetComponent<FloatingLabel>();
floatingLabel.Spawn(discoverText, discoverTextDirection, discoverTextOffset);
}
}
void OnMouseExit()
{
if (!GameManager.singleton.CanPlay || isTransitioning) return;
if (active)
{
animator.SetBool("hover", false);
CameraManager.singleton.ShowDefaultTexture();
if (!mute) GameManager.singleton.soundManager.StopSound();
}
if (floatingLabel != null)
{
floatingLabel.Despawn();
}
}
void Discover()
{
GameManager.singleton.soundManager.PlayDiscoverSound();
discovered = true;
animator.SetTrigger("Discover");
if (discoveredSortingOrder != null)
{
GetComponent<SpriteRenderer>().sortingOrder = discoveredSortingOrder ?? 0;
}
if (discoverParticlePrefab != null)
{
Instantiate(discoverParticlePrefab, transform.position, Quaternion.identity);
}
}
public event Action<Clickable> OnClicked;
public event Action<Clickable> OnVideoPlayed;
public UnityEvent OnVideoPlayedEvent;
private bool NeedDeactivating => active && AssociatedSubScene == null && HasPlayedAllVideos();
public void OnMouseDown()
{
if (!GameManager.singleton.CanPlay || isTransitioning) return;
string clickResult = ProcessClick();
OnClicked?.Invoke(this);
if (NeedDeactivating)
{
active = false;
animator.speed = 0;
}
else if (new List<string> {
"firstVideoPlayed",
"secondVideoPlayed",
"randomVideoPlayed"
}.Contains(clickResult))
{
GameManager.singleton.soundManager.PlayClickSound();
}
}
public void OnVideoEnd()
{
if (NeedDeactivating)
{
active = false;
animator.speed = 0;
}
if (floatingLabel != null) Destroy(floatingLabel.gameObject);
OnVideoPlayed?.Invoke(this);
OnVideoPlayedEvent?.Invoke();
}
public string ProcessClick()
{
OnClick?.Invoke();
if (isDiscoverable && !discovered)
{
Discover();
GameManager.singleton.soundManager.StopHoverSound();
GameManager.singleton.soundManager.PlayDiscoverSound();
return "discovered";
}
if (goToSubSceneName != null && goToSubSceneName != "")
{
CameraManager.singleton.MoveToSubScene(goToSubSceneName, () =>
{
PlayVideo();
});
return "moveToSubscene";
}
return PlayVideo();
}
public string PlayVideo()
{
if (firstVideoAsset != null || secondVideoAsset != null || listRandomVideoAssets.Count > 0)
{
if (firstVideoAsset != null && !firstVideoPlayed)
{
firstVideoPlayed = true;
CameraManager.singleton.PlayVideo(firstVideoAsset, () =>
{
OnVideoEnd();
if (playRandomClipAfterFirst)
{
CameraManager.singleton.PlayVideo(shuffledVideoAssets[playedVideoCount % shuffledVideoAssets.Count], OnVideoEnd);
playedVideoCount++;
}
});
return "firstVideoPlayed";
}
else if (secondVideoAsset != null)
{
CameraManager.singleton.PlayVideo(secondVideoAsset, OnVideoEnd);
return "secondVideoPlayed";
}
else if (listRandomVideoAssets.Count > 0)
{
CameraManager.singleton.PlayVideo(shuffledVideoAssets[playedVideoCount % shuffledVideoAssets.Count], OnVideoEnd);
playedVideoCount++;
return "randomVideoPlayed";
}
}
return "noVideoToPlay";
}
public void Enter()
{
GameManager.singleton.soundManager.StopSound();
isTransitioning = true;
GameManager.singleton.soundManager.PlayEnterSound();
animator.SetTrigger("Enter");
spriteRenderer.sortingOrder = 100;
if (associatedStory != null) associatedStory.TriggerStartAnimation();
}
public void EndEnterOrExit()
{
isTransitioning = false;
animator.SetBool("hover", false);
}
public void Exit()
{
isTransitioning = true;
GameManager.singleton.soundManager.PlayExitSound();
animator.SetTrigger("Exit");
spriteRenderer.sortingOrder = zindex;
}
}