using System.Collections; using UnityEngine; public class BuildingBehaviourAlt : MonoBehaviour, IListener { public Transform building; [SerializeField] Transform destination = null; [SerializeField] private Color wrongColor = new Color(1, 0, 0, 0.1f); [SerializeField] [ColorUsage(true, true)] private Color wrongOutglowColor = new Color(1, 0, 0, 0.1f); [SerializeField] private AnimationCurve colorChangeCurve = null; [SerializeField] [Min(0.1f)] private float wrongPosAnimTime = 0.5f; [SerializeField] [VectorRange(0f, 1f, 0f, 1f, true)] private Vector2[] visibilityLR = null; private bool buildDone = false; private Color mainColor; private Color outglowColor; private Material[] destinationMaterials; private Material[] buildingMaterials; private bool wrongCoroutineRunning = false; private Vector3 finalPosition; private Vector3 currentEulerAngles; void Start() { building.GetComponent<Renderer>().enabled = false; destination.GetComponent<Renderer>().enabled = true; Bounds b = building.GetComponent<Renderer>().bounds; destination.localScale = building.localScale * 1.01f; buildingMaterials = building.GetComponent<Renderer>().materials; for (int i = 0; i < buildingMaterials.Length; i++) { buildingMaterials[i].SetInt("_HighlightOn", 0); } destinationMaterials = destination.GetComponent<Renderer>().materials; mainColor = destinationMaterials[0].GetColor("_MainColor"); outglowColor = destinationMaterials[0].GetColor("_OutGlowColor"); currentEulerAngles = building.eulerAngles; EventManager.Instance.AddListener(EVENT_TYPE.ON_BUILDING_EYE_CHANGED, this); EventManager.Instance.AddListener(EVENT_TYPE.ON_BUILDING_DEST_EYE_CHANGED, this); } public void Init(Vector3? buildingPosition = null) { if (buildingPosition != null) building.position = buildingPosition.Value; for (int i = 0; i < buildingMaterials.Length; i++) { buildingMaterials[i].SetInt("_HighlightOn", 1); } building.GetComponent<Renderer>().enabled = true; building.GetComponent<Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; finalPosition = destination.position; } public void CheckDistance(float distance) { if (Mathf.Abs(building.position.x - destination.position.x) <= distance && Mathf.Abs(building.position.z - destination.position.z) <= 0.05f) { EventManager.Instance.PostNotification<Object>(EVENT_TYPE.ON_BUILDING_BUILT, this); StopAllCoroutines(); StartCoroutine(FinalizeBuild()); } else { StartCoroutine(WrongPosColorAnim()); } } public void Rotate() { currentEulerAngles += new Vector3(0, 90, 0); building.eulerAngles = currentEulerAngles; destination.eulerAngles = currentEulerAngles; } public void SetDestination(Vector3 pos) { destination.position = pos; } IEnumerator WrongPosColorAnim() { if (wrongCoroutineRunning) yield break; wrongCoroutineRunning = true; float t = 0f; while (t <= wrongPosAnimTime) { t += Time.deltaTime; float percent = Mathf.Clamp01(t / wrongPosAnimTime); float curvePercent = colorChangeCurve.Evaluate(percent); for (int i = 0; i < destinationMaterials.Length; i++) { destinationMaterials[i].SetColor("_MainColor", Color.LerpUnclamped(mainColor, wrongColor, curvePercent)); destinationMaterials[i].SetColor("_OutGlowColor", Color.LerpUnclamped(outglowColor, wrongOutglowColor, curvePercent)); } yield return null; } for (int i = 0; i < destinationMaterials.Length; i++) { destinationMaterials[i].SetColor("_MainColor", mainColor); destinationMaterials[i].SetColor("_OutGlowColor", outglowColor); } wrongCoroutineRunning = false; } IEnumerator FinalizeBuild() { buildDone = true; for (int i = 0; i < buildingMaterials.Length; i++) { buildingMaterials[i].SetInt("_HighlightOn", 0); } float t = 0f; Vector3 startPosition = building.position; float glow = destinationMaterials[0].GetFloat("_OutGlowSize"); float buildingAlphaLeft = buildingMaterials[0].GetFloat("_AlphaLeftEye"); float buildingAlphaRight = buildingMaterials[0].GetFloat("_AlphaRightEye"); float destinationAlphaLeft = destinationMaterials[0].GetFloat("_AlphaLeftEye"); float destinationAlphaRight = destinationMaterials[0].GetFloat("_AlphaRightEye"); while (t <= 1f) { t += Time.deltaTime; building.position = Vector3.Lerp(startPosition, finalPosition, t); for (int i = 0; i < destinationMaterials.Length; i++) { destinationMaterials[i].SetFloat("_AlphaLeftEye", Mathf.Lerp(destinationAlphaLeft, 1f, t)); destinationMaterials[i].SetFloat("_AlphaRightEye", Mathf.Lerp(destinationAlphaRight, 1f, t)); destinationMaterials[i].SetColor("_MainColor", Color.Lerp(mainColor, Color.clear, t)); destinationMaterials[i].SetFloat("_OutGlowSize", Mathf.Lerp(glow, 20f, t)); } for (int i = 0; i < buildingMaterials.Length; i++) { buildingMaterials[i].SetFloat("_AlphaLeftEye", Mathf.Lerp(buildingAlphaLeft, 1f, t)); buildingMaterials[i].SetFloat("_AlphaRightEye", Mathf.Lerp(buildingAlphaRight, 1f, t)); } yield return null; } destination.GetComponent<Renderer>().enabled = false; building.GetComponent<Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On; } public void OnEvent<T>(EVENT_TYPE eventType, Component Sender, T param = default) { switch (eventType) { case EVENT_TYPE.ON_BUILDING_EYE_CHANGED: if (!buildDone && (dynamic)param <= visibilityLR.Length) { int idx = (dynamic)param; for (int i = 0; i < buildingMaterials.Length; i++) { buildingMaterials[i].SetFloat("_AlphaLeftEye", visibilityLR[idx][0]); buildingMaterials[i].SetFloat("_AlphaRightEye", visibilityLR[idx][1]); } } break; case EVENT_TYPE.ON_BUILDING_DEST_EYE_CHANGED: if (!buildDone && (dynamic)param <= visibilityLR.Length) { int idx = (dynamic)param; for (int i = 0; i < destinationMaterials.Length; i++) { destinationMaterials[i].SetFloat("_AlphaLeftEye", visibilityLR[idx][0]); destinationMaterials[i].SetFloat("_AlphaRightEye", visibilityLR[idx][1]); } } break; } } }