181 lines
5.0 KiB
C#
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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|