using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using static FactWrapper; public class ShinyThings : MonoBehaviour { public WorldCursor Cursor; //Attributes for Highlighting of Facts when Mouse-Over private List<FactObject3D> LastFactSelection = new(); //Variables for Pushout-Highlighting private static float timerDuration = 2.5f; private IEnumerator rain_wait; private IEnumerator rain; public Light directionalLight; private Color darkColor = new(0.2f, 0.2f, 0.2f); private Color light_colour; private GameObject active_rainwork; public GameObject Fireworks_Animation, RainPrefab; private void OnEnable() { CommunicationEvents.PushoutFactFailEvent.AddListener(LetItRain); CommunicationEvents.AnimateExistingAsSolutionEvent.AddListener(HighlightWithFireworks); } private void OnDisable() { CommunicationEvents.PushoutFactFailEvent.RemoveListener(LetItRain); CommunicationEvents.AnimateExistingAsSolutionEvent.RemoveListener(HighlightWithFireworks); } private void Awake() { rain = rain_wait = IEnumeratorExtensions.yield_break; if (Cursor == null) Cursor = GetComponent<WorldCursor>(); if (directionalLight == null) directionalLight = FindObjectOfType<Light>(); light_colour = directionalLight.color; } public void Update() { if (Cursor?.Hits != null) HighlightCurserHit(Cursor.Hits); } private void HighlightCurserHit(RaycastHit[] hits) { List<FactObject3D> selected_fact_objs = hits .Select(h => h.transform?.GetComponentInChildren<FactObject3D>()) .Where(f => f != null) .ToList(); //Set the last Facts unselected foreach (var lastFact in LastFactSelection) if (lastFact != null // if Fact was deleted && !selected_fact_objs.Contains(lastFact)) _ApplyMaterial(lastFact, lastFact.Default); //Set the Facts that were Hit as selected foreach (var fact_obj in selected_fact_objs) if (!LastFactSelection.Contains(fact_obj)) _ApplyMaterial(fact_obj, fact_obj.Selected); LastFactSelection = selected_fact_objs; return; void _ApplyMaterial(FactObject3D root, Material new_mat) => root.CoroutineCascadeForMeAndChildrenAllRenderer( (_, renderer) => renderer.ProgrammMaterialChange(new[] { (0f, GlobalBehaviour.AnimationLerpDuration, new_mat), }) ); } public void HighlightWithFireworks(Fact fact, FactMaterials mat) { rain_wait = IEnumeratorExtensions.yield_break; //stop rain StartCoroutine(_BlossomAndDie()); CommunicationEvents.AnimateExistingFactEvent.Invoke(fact.Id, mat); IEnumerator _BlossomAndDie() { GameObject firework = GameObject.Instantiate (Fireworks_Animation , fact.WorldRepresentation.transform ); yield return new WaitForSeconds(timerDuration); firework.transform.GetChild(0) .GetComponent<ParticleSystem>() .Stop(); var sparks = firework.transform.GetChild(1) .GetComponent<ParticleSystem>(); sparks.Stop(); while (sparks.IsAlive()) yield return null; Destroy(firework); } } public void LetItRain() { // check if couroutine is waiting or finished if (!rain_wait.MoveNext() || !rain.MoveNext()) { StopCoroutine(rain); StartCoroutine(rain = _BlossomAndDie()); } rain_wait = IEnumeratorExtensions.ClockForSeconds(timerDuration); //reset timer IEnumerator _BlossomAndDie() { Destroy(active_rainwork); active_rainwork = Instantiate(RainPrefab, new Vector3(0, 40, 0), Quaternion.identity); Color start = directionalLight.color; // may not be original one for (IEnumerator<float> lerper = MathfExtensions.LerpInTime(0, 1, GlobalBehaviour.AnimationLerpDuration) ; lerper.MoveNext();) { directionalLight.color = Color.Lerp(start, darkColor, lerper.Current); yield return null; } while (rain_wait.MoveNext()) yield return null; for (IEnumerator<float> lerper = MathfExtensions.LerpInTime(0, 1, GlobalBehaviour.AnimationLerpDuration) ; lerper.MoveNext();) { directionalLight.color = Color.Lerp(darkColor, light_colour, lerper.Current); yield return null; } Destroy(active_rainwork); } } }