Files
ihob/Assets/Scripts/VisualNovel/VNController.cs

153 lines
5.8 KiB
C#
Raw Normal View History

2026-02-21 17:04:05 -08:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using Com.LuisPedroFonseca.ProCamera2D;
public class VNController : MonoBehaviour {
[SerializeField] float bgCrossfadeTime = 0.5f;
[SerializeField] DialogueController dialogueBox;
[SerializeField] VNSpriteController vnSpriteCenter;
[SerializeField] VNSpriteController vnSpriteLeft;
[SerializeField] VNSpriteController vnSpriteRight;
[SerializeField] Image bgBack;
// Used for cross-fading.
[SerializeField] Image bgFront;
[SerializeField] bool LeaveAfterDone = false;
[HideInInspector] VNObjectController vnAssets;
[HideInInspector] AudioSource audioSource;
[HideInInspector] bool isLeaving = false;
[SerializeField] ProCamera2DTransitionsFX transition;
[SerializeField] bool loadExternalAssets = false;
private void Leave() {
SceneManager.LoadScene("Manager");
}
public void Done() {
if (LeaveAfterDone && !isLeaving) {
transition.OnTransitionExitEnded = Leave;
transition.TransitionExit();
isLeaving = true;
}
}
private class SetSpriteOptions {
public Body spriteBody { get; set; } = Body.None;
// Requires spriteBody.
public int spriteHair { get; set; } = 0;
public Expression spriteExpression { get; set; } = Expression.None;
public bool removeSprite { get; set; } = false;
}
private void SetSprite(VNSpriteController spriteController, SetSpriteOptions options) {
int spriteIndex = (int)options.spriteBody - 1;
if (options.spriteBody != Body.None && spriteIndex < vnAssets.sprites.Count) {
spriteController.body.gameObject.SetActive(true);
spriteController.body.sprite = vnAssets.sprites[spriteIndex];
spriteController.hair.gameObject.SetActive(true);
spriteController.hair.sprite = vnAssets.spriteHairs[options.spriteHair];
}
int spriteExpressionIndex = (int)options.spriteExpression - 1;
if (options.spriteExpression != Expression.None && spriteExpressionIndex < vnAssets.spriteExpressions.Count) {
spriteController.expression.gameObject.SetActive(true);
spriteController.expression.sprite = vnAssets.spriteExpressions[spriteExpressionIndex];
}
if (options.removeSprite) {
spriteController.body.gameObject.SetActive(false);
spriteController.hair.gameObject.SetActive(false);
spriteController.expression.gameObject.SetActive(false);
}
Debug.Log("TODO: Effect animation");
}
public void Interact(DialogueInteraction interaction) {
// Cancel any pending crossfades.
if (bgFront != null) {
bgFront.CrossFadeAlpha(1.0f, 0.0f, false);
}
// If there's a new background, fade into it.
if (bgFront != null && bgBack != null && interaction.backgroundIndex > -1) {
if (bgBack.sprite != null) {
bgBack.sprite = bgFront.sprite;
if (interaction.backgroundIndex < vnAssets.backgrounds.Count) {
bgFront.sprite = vnAssets.backgrounds[interaction.backgroundIndex];
bgFront.GetComponent<CanvasRenderer>().SetAlpha(0);
bgFront.CrossFadeAlpha(1.0f, bgCrossfadeTime, false);
Debug.Log(bgFront.color.ToString());
Debug.Log(bgFront.sprite.ToString());
} else {
Debug.LogError("Background index out of range for interaction!");
}
} else {
bgBack.sprite = bgFront.sprite = vnAssets.backgrounds[interaction.backgroundIndex];
bgFront.CrossFadeAlpha(1.0f, 0.0f, false);
}
}
// If there's an audio clip, play it.
if (audioSource != null && interaction.audioClipIndex > -1) {
if (interaction.audioClipIndex < vnAssets.voiceBank.Count) {
audioSource.PlayOneShot(vnAssets.voiceBank[interaction.audioClipIndex]);
} else {
Debug.LogError("AudioClip index out of range for interaction!");
}
}
// If a sprite is defined, set it.
SetSprite(vnSpriteCenter, new SetSpriteOptions() {
spriteBody = interaction.body1,
spriteHair = interaction.hair1,
spriteExpression = interaction.expression1,
removeSprite = interaction.removeBody1,
});
SetSprite(vnSpriteLeft, new SetSpriteOptions() {
spriteBody = interaction.body2,
spriteHair = interaction.hair2,
spriteExpression = interaction.expression2,
removeSprite = interaction.removeBody2,
});
SetSprite(vnSpriteRight, new SetSpriteOptions() {
spriteBody = interaction.body3,
spriteHair = interaction.hair3,
spriteExpression = interaction.expression3,
removeSprite = interaction.removeBody3,
});
// TODO: If there's a music clip, stop the currently running clip and play it.
Debug.Log("TODO: Music change");
}
// Called by DialogueControler to enforce loading before the first Interact.
public void SetUp(Dialogue scene)
{
if (loadExternalAssets) {
vnAssets = Instantiate((GameObject)Resources.Load(VNData.GetDialogueAssetPackFor(scene), typeof(GameObject))).GetComponent<VNObjectController>();
} else {
vnAssets = gameObject.GetComponent<VNObjectController>();
}
audioSource = gameObject.GetComponent<AudioSource>();
if (LeaveAfterDone) {
transition.TransitionEnter();
}
}
// Update is called once per frame
void Update()
{
}
}