using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; public class ShinyThings : MonoBehaviour { public WorldCursor Cursor; //Attributes for Highlighting of Facts when Mouse-Over private FactObject lastFactSelection; //Variables for Pushout-Highlighting private static float timerDuration = 2.5f; public GameObject directionalLight; private Color darkColor = new (0.3f, 0.3f, 0.3f); public Material pushoutMaterial; public GameObject Fireworks_Animation, RainPrefab; // Start is called before the first frame update public void Start() { if (Cursor == null) Cursor = GetComponent<WorldCursor>(); if (directionalLight == null) directionalLight = FindObjectOfType<Light>().gameObject; CommunicationEvents.PushoutFactEvent.AddListener(HighlightFact); CommunicationEvents.PushoutFactFailEvent.AddListener(StartPushoutFactFailHighlighting); CommunicationEvents.AnimateExistingFactEvent.AddListener(HighlightWithFireworks); } // Update is called once per frame public void Update() { Highlighting(Cursor.Hit); } private void Highlighting(RaycastHit hit) { FactObject selected_fact_obj = hit.transform?.GetComponentInChildren<FactObject>(); //Set the last Fact unselected if (this.lastFactSelection != null && (selected_fact_obj == null || this.lastFactSelection != selected_fact_obj)) { ApplyMaterial(lastFactSelection, lastFactSelection.Default); this.lastFactSelection = null; } //Set the Fact that was Hit as selected if (selected_fact_obj != null && hit.transform != null && (hit.transform.CompareTag("Selectable") || hit.transform.CompareTag("SnapZone")) && (this.lastFactSelection == null || this.lastFactSelection != selected_fact_obj)) { ApplyMaterial(selected_fact_obj, selected_fact_obj.Selected); this.lastFactSelection = selected_fact_obj; } void ApplyMaterial(FactObject root, Material new_mat) => root.CoroutineCascadeForChildrenAllRenderer( (_, renderer) => renderer.ProgrammMaterialChange(new[] { (0f, 1f, new_mat), }) ); } public static void HighlightFact(Fact startFact, FactObject.FactMaterials tmp_mat) { FactObject selected_fact_obj = startFact.Representation.GetComponentInChildren<FactObject>(); selected_fact_obj.CoroutineCascadeForChildrenAllRenderer( (fact_obj, renderer) => renderer.ProgrammMaterialChange(new[] { (0f, 1f, fact_obj.materials[(int) tmp_mat]), (timerDuration, 1f, fact_obj.Default), }) ); } public void HighlightWithFireworks(Fact fact) { StartCoroutine(BlossomAndDie()); HighlightFact(fact, FactObject.FactMaterials.Solution); IEnumerator BlossomAndDie() { GameObject firework = GameObject.Instantiate(Fireworks_Animation); firework.transform.position = fact.Representation.transform.position; 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; GameObject.Destroy(firework); } } public void StartPushoutFactFailHighlighting(Fact startFact) { StartCoroutine(BlossomAndDie()); IEnumerator BlossomAndDie() { Color start = directionalLight.GetComponent<Light>().color; IEnumerator<float> num = LerpfTime(0, 1, 1); while (num.MoveNext()) { directionalLight.GetComponent<Light>().color = Color.Lerp(start, darkColor, num.Current); yield return null; } GameObject rainwork = GameObject.Instantiate(RainPrefab, new Vector3(0, 40, 0), Quaternion.identity); yield return new WaitForSeconds(2*timerDuration); GameObject.Destroy(rainwork); num = LerpfTime(0, 1, 1); while (num.MoveNext()) { directionalLight.GetComponent<Light>().color = Color.Lerp(darkColor, start, num.Current); yield return null; } } IEnumerator<float> LerpfTime(float start, float end, float time) { float start_time = Time.time, end_time = start_time + time; while(end_time >= Time.time) yield return Mathf.Lerp(start, end, (Time.time - start_time) / time); } } }