Files
ihob/Assets/Scripts/StreamController.cs
2026-02-21 17:04:05 -08:00

181 lines
5.0 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StreamController : MonoBehaviour
{
// May be a flatUI arrow or pixel art arrow.
// Pixel art is used in gameplay streams.
// FlatUI arrows are used in cutaway scene streams.
[SerializeField] public GameObject arrowPrefab;
[SerializeField] public AudioClip hitClip;
[SerializeField] public AudioClip missClip;
[SerializeField] public AudioClip winClip;
[SerializeField] public AudioClip loseClip;
[SerializeField] public GameObject arrowGroup;
[SerializeField] public AudioSource audioSource;
[SerializeField] public List<ArrowController> arrows;
[SerializeField] public float resetDelay = 0.5f;
[SerializeField] public bool debug = false;
StreamInfo info;
bool isTicking = false;
float startTime = 0.0f;
int passed = 0;
public class StreamInfo
{
public int numArrows { get; set; }
public float timeLimit { get; set; }
public float startDelay { get; set; }
public float endDelay { get; set; }
// Whether or not to auto-close the Stream after winning or losing.
// Infinite scenes are for special enjoyment events.
public bool infinite { get; set; }
// In sudden death, missing one arrow fails the event even if
// the timer is still running.
public bool suddenDeath { get; set; }
public Sprite beforeBG { get; set; } = null;
public Sprite winBG { get; set; } = null;
public Sprite loseBG { get; set; } = null;
public AudioClip beforeClip { get; set; } = null;
public AudioClip winClip { get; set; } = null;
public AudioClip loseClip { get; set; } = null;
}
public void Init(StreamInfo info, bool wait = true)
{
this.info = info;
passed = 0;
// Calculate int[] keys
for (int i = 0; i < info.numArrows; i++)
{
ArrowController arrow = Instantiate(arrowPrefab).GetComponent<ArrowController>();
arrow.key = Random.Range(0, 4);
arrow.Init();
arrow.transform.parent = arrowGroup.transform;
arrows.Add(arrow);
}
if (wait)
{
Invoke("StartTimer", info.startDelay);
}
}
public void Start()
{
if (debug)
{
Init(new StreamInfo
{
numArrows = 5,
timeLimit = 5.0f,
startDelay = 1.0f,
endDelay = 1.0f,
infinite = true,
suddenDeath = false
});
}
}
public void MakeGlow(int arrowIndex)
{
// TODO: implement (make the arrow at ArrowIndex glow)
// use the shader thing
}
void StartTimer()
{
isTicking = true;
MakeGlow(0);
}
void Reset()
{
foreach (ArrowController arrow in arrows)
{
Destroy(arrow.gameObject);
}
arrows.Clear();
Init(this.info, false);
isTicking = true;
MakeGlow(0);
}
void TryHit(int key)
{
if (passed < info.numArrows)
{
if (arrows[passed].key == key)
{
// You hit the right arrow, move to the next one
audioSource.PlayOneShot(hitClip);
arrows[passed].Succeed();
passed += 1;
} else
{
arrows[passed].Fail();
if (!info.suddenDeath)
{
audioSource.PlayOneShot(missClip);
isTicking = false;
Invoke("Reset", resetDelay);
} else
{
// TODO: do a lose thing
audioSource.PlayOneShot(loseClip);
}
}
if (passed == info.numArrows)
{
// TODO: do a win thing
audioSource.PlayOneShot(winClip);
if (debug)
{
isTicking = false;
Invoke("Reset", resetDelay);
}
} else
{
MakeGlow(passed);
}
}
}
// Update is called once per frame
void Update()
{
// Process key presses if the delay is over
if (isTicking)
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
Debug.Log("Left");
TryHit(0);
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
Debug.Log("Down");
TryHit(1);
}
if (Input.GetKeyDown(KeyCode.UpArrow))
{
Debug.Log("Up");
TryHit(2);
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
Debug.Log("Right");
TryHit(3);
}
}
}
}