using System; using System.Collections; using System.Collections.Generic; #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; namespace Kamgam.SkyClouds { /// /// The sky cloud observer implements two things:
/// * A mask (if available)
/// * Fading (if available) ///
public class SkyCloudObserver : MonoBehaviour { public float FadeStartDistance = 2f; public float FadeEndDistance = 0.5f; protected SkyCloudMask _mask; public SkyCloudMask Mask { get { if (_mask == null) { _mask = this.GetComponentInChildren(includeInactive: true); } return _mask; } } public float MaskScale { get => (Mask == null) ? 1f : Mask.transform.localScale.x; set { if (Mask != null) Mask.transform.localScale = Vector3.one * value; } } public float MaskPadding { get => (Mask == null) ? 0f : Mask.Padding; set { if (Mask != null) Mask.Padding = value; } } public Camera Camera { get => transform.GetComponentInParent(); } public Material FadeMaterial; [System.NonSerialized] private Vector3 _closestPosition; [System.NonSerialized] private SkyCloud _closestCloud; public void Start() { if (Mask != null) { Mask.Padding = Mask.Padding; } } public void Update() { // Cals distance and find closest cloud. float distance = SkyCloud.GetMinDistance(transform.position, out _closestPosition, out _closestCloud, distanceLimit: 10f); // Update properties based on closest cloud. if(_closestCloud != null && _closestCloud.gameObject != null) { FadeStartDistance = _closestCloud.ObserverFadeStartDistance; FadeEndDistance = _closestCloud.ObserverFadeEndDistance; if (_mask != null) { MaskScale = _closestCloud.ObserverMaskScale; MaskPadding = _closestCloud.ObserverMaskPadding; // Handle dynamic cloud materials var material = _closestCloud.CloudMaterial; if (material != null && !Mask.SkyCouldMaterials.Contains(_closestCloud.CloudMaterial)) { Mask.SkyCouldMaterials.Add(_closestCloud.CloudMaterial); } } } // Update fade float alpha = Mathf.Clamp01((distance - FadeEndDistance) / FadeStartDistance); if (_closestCloud != null && _closestCloud.gameObject != null) { FadeMaterial.color = new Color( _closestCloud.ObserverFadeColor.r, _closestCloud.ObserverFadeColor.g, _closestCloud.ObserverFadeColor.b, 1f - alpha); } else { FadeMaterial.color = new Color(1f, 1f, 1f, 1f - alpha); } #if UNITY_EDITOR registerPlayModeCallback(); #endif } #if UNITY_EDITOR private static bool registeredPlayModeCallback = false; private void registerPlayModeCallback() { if (!registeredPlayModeCallback) { registeredPlayModeCallback = true; EditorApplication.playModeStateChanged += onPlayModeChanged; } } private void onPlayModeChanged(PlayModeStateChange change) { if (change == PlayModeStateChange.EnteredEditMode || change == PlayModeStateChange.EnteredPlayMode) { // Init alpha with 0 var col = FadeMaterial.color; col.a = 0f; FadeMaterial.color = col; } } //private void OnDrawGizmos() //{ // Gizmos.DrawSphere(_closestPosition, 0.1f); //} public void Reset() { string[] materialGUIDs = AssetDatabase.FindAssets("t:Material SkyCloudIntersectionFade"); if (materialGUIDs.Length > 0) { string path = AssetDatabase.GUIDToAssetPath(materialGUIDs[0]); Material material = AssetDatabase.LoadAssetAtPath(path); if (material != null && material.name.StartsWith("SkyCloud")) { FadeMaterial = material; // Init alpha with 0 var col = FadeMaterial.color; col.a = 0f; FadeMaterial.color = col; } EditorUtility.SetDirty(this); } } #endif } #if UNITY_EDITOR [UnityEditor.CustomEditor(typeof(SkyCloudObserver))] public class SkyCloudObserverEditor : UnityEditor.Editor { SkyCloudObserver obj; public void OnEnable() { obj = target as SkyCloudObserver; } public override void OnInspectorGUI() { base.OnInspectorGUI(); if (GUILayout.Button("Add IntersectionFade")) { var fade = obj.transform.Find("SkyClouds_IntersectionFade"); if (fade == null) { string[] fadeGUIDs = AssetDatabase.FindAssets("t:Prefab SkyClouds_IntersectionFade"); if (fadeGUIDs.Length > 0) { string path = AssetDatabase.GUIDToAssetPath(fadeGUIDs[0]); var fadePrefab = AssetDatabase.LoadAssetAtPath(path); var fadeGO = PrefabUtility.InstantiatePrefab(fadePrefab, obj.transform) as GameObject; fadeGO.transform.localPosition = new Vector3(0, 0, obj.Camera.nearClipPlane + 0.0001f); EditorUtility.SetDirty(obj); } } } if (GUILayout.Button("Add Mask")) { var mask = obj.transform.Find("SkyClouds_Mask0"); if (mask == null) { string[] maskGUIDs = AssetDatabase.FindAssets("t:Prefab SkyClouds_Mask0"); if (maskGUIDs.Length > 0) { string path = AssetDatabase.GUIDToAssetPath(maskGUIDs[0]); var maskPrefab = AssetDatabase.LoadAssetAtPath(path); var maskGO = PrefabUtility.InstantiatePrefab(maskPrefab, obj.transform) as GameObject; maskGO.transform.localPosition = new Vector3(0, 0, 0); maskGO.GetComponent().Reset(); EditorUtility.SetDirty(obj); } } } } } #endif }