Insanely huge initial commit

This commit is contained in:
2026-02-21 16:40:15 -08:00
parent 208d626100
commit f74c547a13
33825 changed files with 5213498 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ArrowController : MonoBehaviour
{
// Left, down, up, right arrow sprites.
[SerializeField] public Sprite[] arrowSprites;
[SerializeField] public GameObject successObject;
[SerializeField] public GameObject failObject;
[SerializeField] public Image image;
[SerializeField] public Image bgImage;
public int key = 0;
public void Init()
{
image.sprite = arrowSprites[key];
}
public void Succeed()
{
GameObject o = Instantiate(successObject);
o.transform.position = transform.position;
o.transform.SetParent(this.transform);
image.color = Color.clear;
bgImage.color = Color.clear;
}
public void Fail()
{
GameObject o = Instantiate(failObject);
o.transform.position = transform.position;
o.transform.SetParent(this.transform);
image.color = Color.clear;
bgImage.color = Color.clear;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 42cbbc58fd0a533479ab2710a02ede7e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,252 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
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;
[SerializeField] public int debugLength = 5;
[SerializeField] public float debugTimeLimit = 30f;
[SerializeField] Button continueButton;
StreamInfo info;
bool isTicking = false;
bool isOver = false;
int passed = 0;
[SerializeField] TextMeshProUGUI clearCountTMPro;
[SerializeField] TextMeshProUGUI timeTMPro;
[SerializeField] TextMeshProUGUI summaryTMPro;
[SerializeField] public int numWon = 0;
float startTimestamp = 0.0f;
float freezeTimestamp = 0.0f;
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.position = arrowGroup.transform.position;
arrow.transform.SetParent(arrowGroup.transform);
arrow.transform.localScale = new Vector3(1, 1, 1);
arrows.Add(arrow);
}
if (wait) {
Invoke("StartTimer", info.startDelay);
}
}
public void Start() {
if (debug) {
Init(new StreamInfo {
numArrows = debugLength,
timeLimit = debugTimeLimit,
startDelay = 1.0f,
endDelay = 1.0f,
infinite = true,
suddenDeath = false
});
}
audioSource = GameObject.FindWithTag("SFX").GetComponent<AudioSource>();
continueButton.gameObject.SetActive(false);
}
public void MakeGlow(int arrowIndex) {
// TODO: implement (make the arrow at ArrowIndex glow)
// use the shader thing
}
void StartTimer() {
startTimestamp = Time.time;
isTicking = true;
MakeGlow(0);
}
void Reset() {
Debug.Log("Reset");
if (isOver)
return;
foreach (ArrowController arrow in arrows) {
Destroy(arrow.gameObject);
}
arrows.Clear();
Init(this.info, false);
isTicking = true;
MakeGlow(0);
}
char GetRank() {
float winRate = numWon * info.numArrows * (1 + resetDelay);
if (winRate > info.timeLimit * 3)
return 'S';
if (winRate > info.timeLimit * 2.5)
return 'A';
if (winRate > info.timeLimit * 2)
return 'B';
if (winRate > info.timeLimit * 1.5)
return 'C';
if (winRate > info.timeLimit * 1)
return 'D';
return 'F';
}
int GetScore(char rank) {
return numWon * 30;
/*
switch (rank) {
case 'S':
return 300;
case 'A':
return 250;
case 'B':
return 200;
case 'C':
return 150;
case 'D':
return 100;
default:
return 0;
}
*/
}
public void GoBack() {
GameData.GLOBAL.IncrementTime();
SceneManager.LoadScene("Manager");
}
void AllowContinue() {
continueButton.gameObject.SetActive(true);
}
void TimesUp() {
Debug.Log("Time's Up!");
isOver = true;
char rank = GetRank();
int score = GetScore(rank);
summaryTMPro.SetText("Time's Up!\nRank: " + rank.ToString() + "\nPay: $" + score.ToString());
GameData.GLOBAL.money += score;
GameData.GLOBAL.workedToday = true;
Invoke("AllowContinue", 1.0f);
}
void TryHit(int key) {
if (isOver)
return;
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);
numWon += 1;
isTicking = false;
Invoke("Reset", resetDelay);
} else {
MakeGlow(passed);
}
}
}
// Update is called once per frame
void Update() {
if (isOver)
return;
// 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);
}
}
clearCountTMPro.SetText(numWon.ToString());
}
void FixedUpdate() {
float time;
if (isTicking) {
time = info.timeLimit - (Time.time - startTimestamp);
if (time <= 0f) {
isTicking = false;
time = 0f;
TimesUp();
}
freezeTimestamp = time;
} else {
time = freezeTimestamp;
}
timeTMPro.SetText(time.ToString("#0.00"));
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3afcad898513dc04d80735eb278fa6dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: