using System; using System.Threading.Tasks; using UnityEngine; using UnityEngine.UI; public class ShapeDetectionNPC : NPCController { [Header("Shape Detection Minigame Config")] public QuestMarker questMarker; public RadioTransmitter radio; public Transform computerKeyboardKey; public ComputerPrinter computerPrinter; public Printer3DInputHole printerInsertionHole; public Texture2D GeneratedTexture { get; private set; } public Image imageDisplay; public ShapeScanner shapeScanner; public float radioAmount = 1f; // states: // 0 - idle // 1 - noticed player // 2 - player picked up radio // 3 - player spoke into the radio // 4 - player pressed enter on keyboard // 5 - player inserted picture into printer // 6 - finished speaking private int state; private float lastPlayerApproachTime; private void Awake() { state = 0; lastPlayerApproachTime = Time.time; } private void Start() { radio.OnPlayerPickUp += OnPlayerPickedUpRadio; radio.OnPlayerFinishedSpeaking += OnPlayerSpokeIntoRadio; computerPrinter.OnImagePrinted += OnPlayerPrintedImage; printerInsertionHole.OnPlayerInsertedPrintable += OnPlayerInitiatedPrinting; } protected async override void OnPlayerApproach() { if (Time.time < lastPlayerApproachTime + 0.5f) { return; } lastPlayerApproachTime = Time.time; if (state == 0) { state = 1; await CallPlayer(); await Task.Delay(1000); questMarker.MoveTo(radio.transform, true); } } protected override void OnPlayerLeave() { if (Time.time < lastPlayerApproachTime + 0.5f) { return; } if (state == 1) { state = 0; } } private async Task CallPlayer() { if (state == 1) { SpeakVoiceLine(0, radio.gameObject, radioAmount); await Task.Delay(2000); // Has the player maybe picked up the radio during the last 2 seconds? if (state == 1) { SpeakVoiceLine(1, radio.gameObject, radioAmount); Invoke(nameof(CallPlayer), 4f); } } } private async void OnPlayerPickedUpRadio() { if (state == 1) { SpeakVoiceLine(2, radio.gameObject, radioAmount); state = 2; await Task.Delay(5000); } } private void OnPlayerSpokeIntoRadio() { if (state == 2) { SpeakVoiceLine(3, radio.gameObject, radioAmount); state = 3; questMarker.MoveTo(computerKeyboardKey); } } private void OnPlayerPrintedImage() { if (state == 3) { SpeakVoiceLine(4, radio.gameObject, radioAmount); state = 4; questMarker.MoveTo(printerInsertionHole.transform); } } private async void OnPlayerInitiatedPrinting() { if (state == 4) { SpeakVoiceLine(5, radio.gameObject, radioAmount); state = 5; questMarker.MoveTo(shapeScanner.transform, true); } string encodedTexture = Convert.ToBase64String(GeneratedTexture.EncodeToJPG()); byte[] encodedModel = await TrellisClient.Instance.GenerateModel(encodedTexture); GameObject spawnedObject = await ModelGenerationUtils.Instance.SpawnModel(encodedModel); if (state == 5) { state = 6; } } }