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 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(); 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); } } } }