using System.Collections.Generic; using UnityEngine; public class TilesetFade : MonoBehaviour { public float duration = 0.3f; private Dictionary items; private OnlineMaps map; private List materialsForRemove; private void OnDrawTile(OnlineMapsTile tile, Material material) { if (!items.ContainsKey(material)) items.Add(material, new Item(material)); items[material].SetTile(tile); if (material.mainTexture == OnlineMapsRasterTile.emptyColorTexture) items[material].tileData.alpha = 1; } private void OnLateUpdateAfter() { foreach (Material material in materialsForRemove) items.Remove(material); materialsForRemove.Clear(); float alphaDelta = Time.deltaTime / duration; foreach (OnlineMapsTile tile in map.tileManager.tiles) { TileData tileData = tile["data"] as TileData; if (tileData != null) tileData.ClearFlags(); } foreach (KeyValuePair item in items) { item.Value.UpdateMaterial(alphaDelta); } } private void OnTileDisposed(OnlineMapsTile tile) { foreach (KeyValuePair pair in items) { if (pair.Value.ClearReferences(tile)) materialsForRemove.Add(pair.Key); } } private void OnTileLoaded(OnlineMapsTile tile) { tile["data"] = new TileData(); tile.OnDisposed += OnTileDisposed; } private void Start() { items = new Dictionary(); materialsForRemove = new List(); map = OnlineMaps.instance; OnlineMapsTileManager.OnTileLoaded += OnTileLoaded; OnlineMapsTileSetControl.instance.OnDrawTile += OnDrawTile; map.OnLateUpdateAfter += OnLateUpdateAfter; } internal class Item { internal OnlineMapsTile tile; internal TileData tileData; private bool isModified; private Material material; private Vector2 originalScale; private Vector2 originalOffset; public Item(Material material) { this.material = material; } public bool ClearReferences(OnlineMapsTile disposedTile) { if (tile == disposedTile) { tile = null; tileData = null; return true; } return false; } private void FadeIn(float alphaDelta) { OnlineMapsTile currentTile = tile; OnlineMapsTile parent = null; Vector2 scale = originalScale; Vector2 offset = originalOffset; Vector2 parentScale = Vector2.one; Vector2 parentOffset = Vector2.zero; while (currentTile.parent != null) { OnlineMapsTile cParent = currentTile.parent; if (cParent.status == OnlineMapsTileStatus.disposed) { parent = cParent; break; } parentScale = scale / 2; parentOffset.x = offset.x / 2 + (currentTile.x % 2 == 0 ? 0 : 0.5f); parentOffset.y = offset.y / 2 + (currentTile.y % 2 == 0 ? 0.5f : 0); if (parentOffset.y < 0) parentOffset.y += 1; TileData parentData = cParent["data"] as TileData; if (parentData == null) { parent = cParent; break; } if (parentData.alpha >= 1) { parent = cParent; break; } currentTile = cParent; offset = parentOffset; scale = parentScale; } if (parent == null) { parentScale = Vector2.one; parentOffset = Vector2.zero; } TileData data = currentTile["data"] as TileData; data.IncreaseAlpha(alphaDelta); Texture overlayTexture = currentTile.texture; if (parent != null) { material.mainTexture = parent.texture; material.mainTextureScale = parentScale; material.mainTextureOffset = parentOffset; material.SetTexture("_OverlayBackTex", overlayTexture); material.SetTextureScale("_OverlayBackTex", scale); material.SetTextureOffset("_OverlayBackTex", offset); material.SetFloat("_OverlayBackAlpha", data.alpha); isModified = true; } else { data.alpha = 1; material.mainTexture = overlayTexture; material.mainTextureScale = scale; material.mainTextureOffset = offset; material.SetTexture("_OverlayBackTex", overlayTexture); material.SetTextureScale("_OverlayBackTex", scale); material.SetTextureOffset("_OverlayBackTex", offset); material.SetFloat("_OverlayBackAlpha", data.alpha); isModified = true; } } public void SetTile(OnlineMapsTile tile) { this.tile = tile; tileData = tile["data"] as TileData; isModified = false; originalScale = material.mainTextureScale; originalOffset = material.mainTextureOffset; } public void UpdateMaterial(float alphaDelta) { if (tile == null || tileData == null) return; if (tileData.alpha >= 1) { if (!isModified) return; material.mainTexture = tile.texture; material.mainTextureScale = originalScale; material.mainTextureOffset = originalOffset; material.SetTexture("_OverlayBackTex", null); isModified = false; return; } FadeIn(alphaDelta); } } internal class TileData { public float alpha; private bool isIncreased; public void ClearFlags() { isIncreased = false; } public void IncreaseAlpha(float delta) { if (isIncreased) return; alpha += delta; if (alpha >= 1) alpha = 1; isIncreased = true; } } }