| | 1 | | using DCL.Helpers; |
| | 2 | | using System.Collections.Generic; |
| | 3 | | using UnityEngine; |
| | 4 | |
|
| | 5 | | public class MaterialTransitionController : MonoBehaviour |
| | 6 | | { |
| | 7 | | enum State |
| | 8 | | { |
| | 9 | | NOT_LOADED, |
| | 10 | | SHOWING_LOADED, |
| | 11 | | FINISHED, |
| | 12 | | INVALID, |
| | 13 | | } |
| | 14 | |
|
| | 15 | | State state = State.NOT_LOADED; |
| | 16 | |
|
| 1 | 17 | | private static int ShaderId_CullYPlane = Shader.PropertyToID("_CullYPlane"); |
| 1 | 18 | | private static int ShaderId_FadeThickness = Shader.PropertyToID("_FadeThickness"); |
| 1 | 19 | | private static int ShaderId_FadeDirection = Shader.PropertyToID("_FadeDirection"); |
| 1 | 20 | | private static int ShaderId_LoadingColor = Shader.PropertyToID("_LoadingColor"); |
| | 21 | |
|
| | 22 | | Material loadingMaterial; |
| | 23 | |
|
| 352 | 24 | | [System.NonSerialized] public float delay = 0.5f; |
| 352 | 25 | | [System.NonSerialized] public bool useHologram = true; |
| 352 | 26 | | [System.NonSerialized] public float fadeThickness = 10; |
| | 27 | | [System.NonSerialized] public System.Action onFinishedLoading; |
| | 28 | |
|
| | 29 | | static Material hologramMaterial; |
| | 30 | |
|
| | 31 | | List<Material> loadingMaterialCopies; |
| | 32 | | Material hologramMaterialCopy; |
| | 33 | |
|
| | 34 | | public Material[] finalMaterials; |
| | 35 | | Material[] cullingFXMaterials; |
| | 36 | |
|
| | 37 | | Renderer targetRendererValue; |
| | 38 | |
|
| | 39 | | Renderer targetRenderer |
| | 40 | | { |
| | 41 | | get |
| | 42 | | { |
| 757 | 43 | | if (targetRendererValue == null) |
| | 44 | | { |
| 333 | 45 | | targetRendererValue = GetComponent<Renderer>(); |
| | 46 | | } |
| | 47 | |
|
| 757 | 48 | | return targetRendererValue; |
| | 49 | | } |
| | 50 | | } |
| | 51 | |
|
| 0 | 52 | | public GameObject placeholder { get; private set; } |
| 0 | 53 | | public Renderer placeholderRenderer { get; private set; } |
| | 54 | |
|
| | 55 | | float lowerYRendererBounds; |
| | 56 | | float topYRendererBounds; |
| | 57 | | float currentCullYPlane; |
| | 58 | | float time; |
| | 59 | |
|
| 0 | 60 | | public bool materialReady { get; private set; } |
| | 61 | |
|
| | 62 | | public bool canSwitchMaterial |
| | 63 | | { |
| 98 | 64 | | get { return materialReady && state != State.FINISHED; } |
| | 65 | | } |
| | 66 | |
|
| | 67 | | public void PopulateTargetRendererWithMaterial(Material[] newMaterials, bool updateCulling = false) |
| | 68 | | { |
| 424 | 69 | | if (newMaterials == null) |
| 0 | 70 | | return; |
| | 71 | |
|
| | 72 | | Material material; |
| 1696 | 73 | | for (int i = 0; i < newMaterials.Length; i++) |
| | 74 | | { |
| 424 | 75 | | material = newMaterials[i]; |
| | 76 | |
|
| 424 | 77 | | if (material == null) |
| | 78 | | { |
| 0 | 79 | | Debug.Log("ENTRE A UN CASO ROTO"); |
| 0 | 80 | | state = State.FINISHED; |
| 0 | 81 | | return; |
| | 82 | | } |
| | 83 | |
|
| 424 | 84 | | material.SetColor(ShaderId_LoadingColor, Color.clear); |
| 424 | 85 | | material.SetFloat(ShaderId_FadeDirection, 0); |
| 424 | 86 | | material.SetFloat(ShaderId_FadeThickness, fadeThickness); |
| | 87 | |
|
| 424 | 88 | | if (updateCulling) |
| 318 | 89 | | material.SetFloat(ShaderId_CullYPlane, currentCullYPlane); |
| | 90 | | } |
| | 91 | |
|
| 424 | 92 | | targetRenderer.sharedMaterials = newMaterials; |
| 424 | 93 | | } |
| | 94 | |
|
| | 95 | | void UpdateCullYValueFXMaterial() |
| | 96 | | { |
| 1889 | 97 | | if (cullingFXMaterials != null) |
| | 98 | | { |
| 7556 | 99 | | for (int i = 0; i < cullingFXMaterials.Length; i++) |
| | 100 | | { |
| 1889 | 101 | | Material material = cullingFXMaterials[i]; |
| 1889 | 102 | | material.SetFloat(ShaderId_CullYPlane, currentCullYPlane); |
| | 103 | | } |
| | 104 | | } |
| 1889 | 105 | | } |
| | 106 | |
|
| | 107 | | void UpdateCullYValueHologram() |
| | 108 | | { |
| 2207 | 109 | | if (hologramMaterialCopy != null) |
| 0 | 110 | | hologramMaterialCopy.SetFloat(ShaderId_CullYPlane, currentCullYPlane); |
| 2207 | 111 | | } |
| | 112 | |
|
| | 113 | | void PrepareCullingFXMaterials() |
| | 114 | | { |
| 318 | 115 | | cullingFXMaterials = new Material[finalMaterials.Length]; |
| 1272 | 116 | | for (int i = 0; i < finalMaterials.Length; i++) |
| | 117 | | { |
| 318 | 118 | | cullingFXMaterials[i] = new Material(finalMaterials[i]); |
| | 119 | | } |
| 318 | 120 | | } |
| | 121 | |
|
| | 122 | | private void Awake() |
| | 123 | | { |
| 340 | 124 | | state = State.NOT_LOADED; |
| 340 | 125 | | time = 0; |
| 340 | 126 | | materialReady = false; |
| 340 | 127 | | } |
| | 128 | |
|
| | 129 | | private void Start() |
| | 130 | | { |
| 333 | 131 | | Renderer tr = targetRenderer; |
| | 132 | |
|
| 333 | 133 | | if (float.IsInfinity(tr.bounds.min.y) || float.IsNaN(tr.bounds.min.y)) |
| | 134 | | { |
| 0 | 135 | | Destroy(this); |
| 0 | 136 | | return; |
| | 137 | | } |
| | 138 | |
|
| 333 | 139 | | if (float.IsInfinity(tr.bounds.max.y) || float.IsNaN(tr.bounds.max.y)) |
| | 140 | | { |
| 0 | 141 | | Destroy(this); |
| 0 | 142 | | return; |
| | 143 | | } |
| | 144 | |
|
| 333 | 145 | | tr.enabled = false; |
| | 146 | |
|
| 333 | 147 | | if (useHologram) |
| | 148 | | { |
| 0 | 149 | | InitHologram(); |
| | 150 | | } |
| | 151 | |
|
| 333 | 152 | | lowerYRendererBounds = GetLowerBoundsY(tr); |
| 333 | 153 | | topYRendererBounds = GetTopBoundsY(tr); |
| 333 | 154 | | currentCullYPlane = lowerYRendererBounds; |
| 333 | 155 | | } |
| | 156 | |
|
| | 157 | | void InitHologram() |
| | 158 | | { |
| 0 | 159 | | placeholder = new GameObject("Load Placeholder"); |
| | 160 | |
|
| 0 | 161 | | placeholder.transform.SetParent(transform, false); |
| 0 | 162 | | placeholder.transform.ResetLocalTRS(); |
| | 163 | |
|
| 0 | 164 | | placeholderRenderer = placeholder.AddComponent<MeshRenderer>(); |
| 0 | 165 | | MeshFilter newMeshFilter = placeholder.AddComponent<MeshFilter>(); |
| 0 | 166 | | newMeshFilter.sharedMesh = GetComponent<MeshFilter>().sharedMesh; |
| | 167 | |
|
| 0 | 168 | | if (hologramMaterial == null) |
| 0 | 169 | | hologramMaterial = Resources.Load("Materials/HologramMaterial") as Material; |
| | 170 | |
|
| 0 | 171 | | hologramMaterialCopy = new Material(hologramMaterial); |
| 0 | 172 | | placeholderRenderer.sharedMaterials = new Material[] {hologramMaterialCopy}; |
| 0 | 173 | | } |
| | 174 | |
|
| | 175 | | private void Update() |
| | 176 | | { |
| 2233 | 177 | | if (targetRendererValue == null) |
| | 178 | | { |
| 0 | 179 | | DestroyPlaceholder(); |
| 0 | 180 | | state = State.INVALID; |
| 0 | 181 | | return; |
| | 182 | | } |
| | 183 | |
|
| 2233 | 184 | | switch (state) |
| | 185 | | { |
| | 186 | | case State.NOT_LOADED: |
| | 187 | | { |
| 318 | 188 | | currentCullYPlane += (topYRendererBounds - currentCullYPlane) * 0.1f; |
| 318 | 189 | | currentCullYPlane = Mathf.Clamp(currentCullYPlane, lowerYRendererBounds, topYRendererBounds); |
| 318 | 190 | | time += Time.deltaTime; |
| | 191 | |
|
| 318 | 192 | | UpdateCullYValueHologram(); |
| | 193 | |
|
| 318 | 194 | | if (materialReady && time > delay) |
| | 195 | | { |
| 318 | 196 | | currentCullYPlane = topYRendererBounds; |
| 318 | 197 | | targetRendererValue.enabled = true; |
| | 198 | |
|
| 318 | 199 | | PrepareCullingFXMaterials(); |
| 318 | 200 | | PopulateTargetRendererWithMaterial(cullingFXMaterials, true); |
| | 201 | |
|
| 318 | 202 | | state = State.SHOWING_LOADED; |
| | 203 | | } |
| | 204 | |
|
| 318 | 205 | | break; |
| | 206 | | } |
| | 207 | |
|
| | 208 | | case State.SHOWING_LOADED: |
| | 209 | | { |
| 1889 | 210 | | currentCullYPlane += (lowerYRendererBounds - currentCullYPlane) * 0.05f; |
| 1889 | 211 | | currentCullYPlane = Mathf.Clamp(currentCullYPlane, lowerYRendererBounds, topYRendererBounds); |
| | 212 | |
|
| 1889 | 213 | | UpdateCullYValueHologram(); |
| 1889 | 214 | | UpdateCullYValueFXMaterial(); |
| | 215 | |
|
| 1889 | 216 | | if (currentCullYPlane <= lowerYRendererBounds + 0.1f) |
| | 217 | | { |
| | 218 | | // We don't update the culling value in the final material to avoid affecting the already-loaded mes |
| 8 | 219 | | PopulateTargetRendererWithMaterial(finalMaterials); |
| | 220 | |
|
| 8 | 221 | | DestroyPlaceholder(); |
| 8 | 222 | | state = State.FINISHED; |
| | 223 | | } |
| | 224 | |
|
| 8 | 225 | | break; |
| | 226 | | } |
| | 227 | |
|
| | 228 | | case State.FINISHED: |
| | 229 | | { |
| 26 | 230 | | onFinishedLoading?.Invoke(); |
| 26 | 231 | | Destroy(this); |
| | 232 | | break; |
| | 233 | | } |
| | 234 | | } |
| 1907 | 235 | | } |
| | 236 | |
|
| | 237 | | private void OnDestroy() |
| | 238 | | { |
| 340 | 239 | | DestroyPlaceholder(); |
| | 240 | |
|
| 340 | 241 | | if (loadingMaterialCopies != null) |
| | 242 | | { |
| 0 | 243 | | for (int i = 0; i < loadingMaterialCopies.Count; i++) |
| | 244 | | { |
| 0 | 245 | | Material m = loadingMaterialCopies[i]; |
| 0 | 246 | | if (m != null) |
| | 247 | | { |
| 0 | 248 | | Destroy(m); |
| | 249 | | } |
| | 250 | | } |
| | 251 | | } |
| 340 | 252 | | } |
| | 253 | |
|
| | 254 | | void DestroyPlaceholder() |
| | 255 | | { |
| 348 | 256 | | Destroy(hologramMaterialCopy); |
| 348 | 257 | | hologramMaterialCopy = null; |
| | 258 | |
|
| 348 | 259 | | if (placeholder != null) |
| | 260 | | { |
| 0 | 261 | | Destroy(placeholder); |
| | 262 | | } |
| | 263 | |
|
| 348 | 264 | | if (cullingFXMaterials != null) |
| | 265 | | { |
| 1304 | 266 | | for (int i = 0; i < cullingFXMaterials.Length; i++) |
| | 267 | | { |
| 326 | 268 | | Destroy(cullingFXMaterials[i]); |
| | 269 | | } |
| | 270 | | } |
| 348 | 271 | | } |
| | 272 | |
|
| | 273 | | public void OnDidFinishLoading(Material finishMaterial) |
| | 274 | | { |
| 365 | 275 | | finalMaterials = new Material[] {finishMaterial}; |
| 365 | 276 | | materialReady = true; |
| 365 | 277 | | } |
| | 278 | |
|
| | 279 | | public float GetLowerBoundsY(Renderer targetRenderer) |
| | 280 | | { |
| 333 | 281 | | return targetRenderer.bounds.min.y - fadeThickness; |
| | 282 | | } |
| | 283 | |
|
| | 284 | | public float GetTopBoundsY(Renderer targetRenderer) |
| | 285 | | { |
| 333 | 286 | | return targetRenderer.bounds.max.y + fadeThickness; |
| | 287 | | } |
| | 288 | |
|
| | 289 | | public static void ApplyToLoadedObject(GameObject meshContainer, bool useHologram = true, float fadeThickness = 20, |
| | 290 | | float delay = 0) |
| | 291 | | { |
| 0 | 292 | | Renderer[] renderers = meshContainer.GetComponentsInChildren<Renderer>(); |
| | 293 | |
|
| 0 | 294 | | for (int i = 0; i < renderers.Length; i++) |
| | 295 | | { |
| 0 | 296 | | Renderer r = renderers[i]; |
| | 297 | |
|
| 0 | 298 | | if (r.gameObject.GetComponent<MaterialTransitionController>() != null) |
| | 299 | | continue; |
| | 300 | |
|
| 0 | 301 | | MaterialTransitionController transition = r.gameObject.AddComponent<MaterialTransitionController>(); |
| 0 | 302 | | Material finalMaterial = r.sharedMaterial; |
| 0 | 303 | | transition.delay = delay; |
| 0 | 304 | | transition.useHologram = useHologram; |
| 0 | 305 | | transition.fadeThickness = fadeThickness; |
| 0 | 306 | | transition.OnDidFinishLoading(finalMaterial); |
| | 307 | | } |
| 0 | 308 | | } |
| | 309 | | public void ForceStop() |
| | 310 | | { |
| 22 | 311 | | state = State.FINISHED; |
| 22 | 312 | | } |
| | 313 | | } |