You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
5.2 KiB
C#

using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.IO;
using UnityEngine;
using UnityEngine.Video;
using TMPro;
public static class CollectionExtension
{
private static System.Random _rng = new System.Random();
public static T RandomElement<T>(this IList<T> list)
{
return list[_rng.Next(list.Count)];
}
public static T RandomElement<T>(this T[] array)
{
return array[_rng.Next(array.Length)];
}
}
class DialogueState
{
string _text, _flag;
DialogueState _parent;
private Dictionary<KeyCode, List<DialogueState>> _next;
public void SetText(string newText)
{
_text = newText;
}
public void SetFlag(string newFlag)
{
_flag = newFlag;
}
public string GetText()
{
return _text;
}
public string GetFlag()
{
return _flag;
}
public DialogueState()
{
_next = new Dictionary<KeyCode, List<DialogueState>>();
SetFlag("None");
}
public DialogueState(string newText)
{
_next = new Dictionary<KeyCode, List<DialogueState>>();
SetText(newText);
SetFlag("None");
}
public DialogueState(string newText, string newFlag)
{
_next = new Dictionary<KeyCode, List<DialogueState>>();
SetText(newText);
SetFlag(newFlag);
}
public void SetNextState(KeyCode key, DialogueState nextState)
{
if (!_next.ContainsKey(key))
_next.Add(key, new List<DialogueState>());
_next[key].Add(nextState);
nextState._parent = this;
}
public DialogueState GetNextState(KeyCode key)
{
if (_next.ContainsKey(key))
return _next[key].RandomElement();
return this;
}
}
public class TVScript : MonoBehaviour
{
public TextMeshPro textMeshPro;
public GameObject player;
public GameObject cinemaPlane;
Dictionary<int, DialogueState> _dialogueStates = new Dictionary<int, DialogueState>();
private DialogueState _currState;
private float _delayTimeBeforeNextInput = 0f;
private bool _videoPlayedAtLeastOnce;
private void ConnectStates(KeyCode key, int i, int j)
{
_dialogueStates[i].SetNextState(key, _dialogueStates[j]);
}
private void Start()
{
// Player
player = GameObject.FindGameObjectsWithTag("Player")[0];
// Initialise dialogue states
using (StreamReader streamReader = new StreamReader("Assets/Texts/dialogues.txt"))
{
string line;
for (int i = 0; (line = streamReader.ReadLine()) != null; i++)
{
_dialogueStates[i] = new DialogueState(line);
}
}
_dialogueStates[29].SetFlag("PlayVideo");
// Connect dialogue states
ConnectStates(KeyCode.B, 0, 1);
ConnectStates(KeyCode.B, 1, 2);
for (int i = 2; i < 6; i++)
{
ConnectStates(KeyCode.Y, i, i + 1);
ConnectStates(KeyCode.N, i, i + 1);
}
ConnectStates(KeyCode.Y, 6, 10);
ConnectStates(KeyCode.N, 6, 7);
ConnectStates(KeyCode.Y, 7, 8);
ConnectStates(KeyCode.N, 7, 8);
ConnectStates(KeyCode.Y, 8, 9);
ConnectStates(KeyCode.N, 8, 9);
ConnectStates(KeyCode.Y, 9, 6);
ConnectStates(KeyCode.N, 9, 7);
for (int i = 10; i < 29; i++)
{
ConnectStates(KeyCode.Y, i, i + 1);
ConnectStates(KeyCode.N, i, i + 1);
}
ConnectStates(KeyCode.Y, 29, 35);
ConnectStates(KeyCode.N, 33, 34);
for (int i = 30; i < 46; i += 2)
{
ConnectStates(KeyCode.Y, 29, i);
ConnectStates(KeyCode.N, 29, i);
ConnectStates(KeyCode.Y, i, i + 1);
ConnectStates(KeyCode.N, i, i + 1);
ConnectStates(KeyCode.Y, i + 1, 29);
ConnectStates(KeyCode.N, i + 1, 29);
}
_currState = _dialogueStates[0];
textMeshPro.SetText(_currState.GetText());
}
private void Update()
{
if (_currState.GetFlag() == "PlayVideo" && !_videoPlayedAtLeastOnce)
{
cinemaPlane.GetComponent<VideoPlayer>().Play();
_videoPlayedAtLeastOnce = true;
}
if (cinemaPlane.GetComponent<VideoPlayer>().isPlaying)
{
return;
}
float distanceToPlayer = Vector3.Distance(player.transform.position, transform.position);
if (distanceToPlayer > 5)
{
textMeshPro.SetText("...");
return;
}
textMeshPro.SetText(_currState.GetText());
if (_delayTimeBeforeNextInput > 0f)
{
_delayTimeBeforeNextInput -= Time.deltaTime;
return;
}
if (!Input.anyKeyDown) return;
if (!Regex.IsMatch(Input.inputString, @"^[a-zA-Z]+$")) return;
if (Input.inputString.Length > 1) return;
KeyCode key = (KeyCode)System.Enum.Parse(typeof(KeyCode), Input.inputString, true);
_currState = _currState.GetNextState(key);
textMeshPro.SetText(_currState.GetText());
_delayTimeBeforeNextInput = 1f;
}
}