using UnityEngine; using System; using System.Collections; using System.Collections.Generic; namespace WPM { [Serializable] [ExecuteInEditMode] [RequireComponent (typeof(WorldMapGlobe))] public class WorldMapTicker : MonoBehaviour { /// /// This is a constant but can be increased if needed - should be an even number (zero will be on the equator) /// [NonSerialized] public const int NUM_TICKERS = 9; const string TICKERS_LAYER = "TickersLayer"; /// /// The ticker bands where ticker texts scrolls. /// [SerializeField] public TickerBand[] tickerBands; // collection of ticker bands. Changes in its fields have effect immediately on the map. WorldMapGlobe _map; /// /// Accesor to the World Map Globe core API /// public WorldMapGlobe map { get { if (_map == null) _map = GetComponent (); return _map; } } #region internal variables GameObject tickerBaseLayer; Font defaultFont; Material defaultShadowMaterial; #endregion #region Lifecycle events void Awake () { Init (); } void OnDestroy () { GameObject overlayLayer = map.GetOverlayLayer (false, false); if (overlayLayer == null) return; Transform t = overlayLayer.transform.Find (TICKERS_LAYER); if (t != null) { DestroyImmediate (t.gameObject); } map.requestMapperCamShot = true; } void Update () { UpdateTickerBands (); } public void Init () { if (tickerBands == null || tickerBands.Length != NUM_TICKERS) { tickerBands = new TickerBand[NUM_TICKERS]; for (int k = 0; k < NUM_TICKERS; k++) { tickerBands [k] = new TickerBand (); ResetTickerBand (k); } } if (defaultFont == null) { defaultFont = Instantiate (Resources.Load ("Font/Lato")); Material fontMaterial = Instantiate (defaultFont.material); defaultFont.material = fontMaterial; fontMaterial.renderQueue += 5; } if (defaultShadowMaterial == null) { defaultShadowMaterial = Instantiate(defaultFont.material); defaultShadowMaterial.renderQueue--; } UpdateTickerBands (); } public bool UpdateTickerBands () { bool changes = false; if (tickerBands == null) return changes; // Check base ticker layer if (tickerBaseLayer == null) { changes = true; GameObject overlayLayer = map.GetOverlayLayer (true, true); if (overlayLayer == null) return changes; Transform t = overlayLayer.transform.Find (TICKERS_LAYER); if (t == null) { tickerBaseLayer = new GameObject (TICKERS_LAYER); tickerBaseLayer.transform.SetParent (overlayLayer.transform, false); tickerBaseLayer.transform.localPosition = new Vector3 (0, 0, -0.005f); // Note that labels layer has -0.001f depth tickerBaseLayer.layer = overlayLayer.layer; } else { tickerBaseLayer = t.gameObject; } } // Redraw tickers for (int k = 0; k < tickerBands.Length; k++) { TickerBand tickerBand = tickerBands [k]; // Check ticker layer GameObject tickerBandLayer = tickerBands [k].gameObject; if (tickerBandLayer == null) { changes = true; // Check if it's in the scene string name = "Ticker" + k.ToString (); Transform t = tickerBaseLayer.transform.Find (name); if (t != null) { tickerBandLayer = t.gameObject; } else { tickerBandLayer = Instantiate (Resources.Load ("Prefabs/TickerBand")); tickerBandLayer.name = name; tickerBandLayer.hideFlags = HideFlags.DontSave; tickerBandLayer.transform.SetParent (tickerBaseLayer.transform, false); tickerBandLayer.layer = tickerBaseLayer.layer; Material mat = Instantiate (tickerBandLayer.GetComponent ().sharedMaterial); tickerBandLayer.GetComponent ().sharedMaterial = mat; mat.color = new Color (0, 0, 0, 0); } tickerBand.gameObject = tickerBandLayer; } // Controls visibility float goodAlpha; if (tickerBand.visible && !(tickerBand.autoHide && GetTickerTextCount (k) == 0)) { goodAlpha = tickerBand.backgroundColor.a; } else { goodAlpha = 0; } float currentAlpha = tickerBandLayer.GetComponent ().sharedMaterial.color.a; if (!tickerBand.alphaChanging && currentAlpha != goodAlpha) { tickerBand.alphaChanging = true; tickerBand.alphaStart = currentAlpha; tickerBand.alphaTimer = DateTime.Now; } if (!tickerBandLayer.activeSelf && tickerBand.alphaChanging) tickerBandLayer.SetActive (true); // Assign customizable properties if (tickerBandLayer.activeSelf) { // position float posY = tickerBand.verticalOffset * WorldMapGlobe.overlayHeight; if (tickerBandLayer.transform.localPosition.y != posY) { tickerBandLayer.transform.localPosition = new Vector3 (0, posY, tickerBandLayer.transform.localPosition.z); ; changes = true; } // vertical scale float scaleY = tickerBand.verticalSize * WorldMapGlobe.overlayHeight; if (tickerBandLayer.transform.localScale.y != scaleY) { tickerBandLayer.transform.localScale = new Vector3 (WorldMapGlobe.overlayWidth, scaleY, 1.0f); changes = true; } // alpha float alpha; if (tickerBand.alphaChanging) { DateTime now = DateTime.Now; float elapsed = (float)(now - tickerBand.alphaTimer).TotalSeconds; alpha = Mathf.Lerp (tickerBand.alphaStart, goodAlpha, elapsed / tickerBand.fadeSpeed); if (alpha == goodAlpha) { tickerBand.alphaChanging = false; if (goodAlpha == 0) tickerBandLayer.SetActive (false); } } else { alpha = goodAlpha; } // Assigns the color & alpha Color color = new Color (tickerBand.backgroundColor.r, tickerBand.backgroundColor.g, tickerBand.backgroundColor.b, alpha); Material mat = tickerBandLayer.GetComponent ().sharedMaterial; if (mat.color != color) { mat.color = color; changes = true; } } } if (changes) map.requestMapperCamShot = true; return changes; } #endregion #region Public API /// /// Returns number of active ticker texts for all ticker bands. /// public int GetTickerTextCount () { if (tickerBaseLayer != null) return tickerBaseLayer.GetComponentsInChildren (true).Length; else return 0; } /// /// Returns number of active ticker texts in specified ticker band /// public int GetTickerTextCount (int tickerLine) { GameObject tickerBand = tickerBands [tickerLine].gameObject; if (tickerBand != null) return tickerBand.GetComponentsInChildren (true).Length; else return 0; } /// /// Returns the number of active ticker bands /// public int GetTickerBandsActiveCount () { int c = 0; for (int k = 0; k < tickerBands.Length; k++) { if (tickerBands [k].gameObject != null && tickerBands [k].gameObject.activeSelf) c++; } return c; } /// /// Set default parameters for all ticker bands and removes any text on them. /// public void ResetTickerBands () { if (tickerBands == null) return; for (int k = 0; k < tickerBands.Length; k++) ResetTickerBand (k); } /// /// Resets ticker band properties to its defaults and removes any ticker text on it. /// /// Ticker index. public void ResetTickerBand (int tickerBandIndex) { if (tickerBands == null) Init (); if (tickerBandIndex < 0 || tickerBandIndex >= tickerBands.Length) { Debug.LogWarning ("Ticker band index out of range."); return; } TickerBand tickerBand = tickerBands [tickerBandIndex]; tickerBand.verticalSize = 1.0f / NUM_TICKERS; float vpos = (1.0f / NUM_TICKERS) * tickerBandIndex; if (vpos > 0.5f) vpos -= 1.0f; tickerBand.verticalOffset = vpos; tickerBand.autoHide = false; tickerBand.backgroundColor = new Color (0, 0, 0, 0.9f); // default color, can be changed GameObject layer = tickerBand.gameObject; if (layer != null) { TickerTextAnimator[] tta = tickerBand.gameObject.GetComponentsInChildren (true); for (int k = 0; k < tta.Length; k++) { DestroyImmediate (tta [k].gameObject); } } map.requestMapperCamShot = true; } /// /// Adds a new ticker text to a ticker line. /// public void AddTickerText (TickerText tickerText) { if (tickerText == null) { Debug.LogWarning ("Tried to add an empty ticker. Ignoring."); return; } if (tickerBands == null) { Debug.LogWarning ("Tickers has not been initialized properly."); return; } if (tickerText.tickerLine < 0 || tickerText.tickerLine >= tickerBands.Length) { Debug.LogWarning ("Ticker line " + tickerText.tickerLine + " doesn't exist."); return; } TickerBand tickerBand = tickerBands [tickerText.tickerLine]; GameObject tickerBandObj = tickerBand.gameObject; if (tickerBandObj == null) { Debug.LogWarning ("Ticker band " + tickerText.tickerLine + " has been destroyed. Can't add text."); return; } if (tickerText.font == null) { tickerText.font = defaultFont; } if (tickerText.shadowMaterial == null) { tickerText.shadowMaterial = defaultShadowMaterial; } // Creates TextMesh Object Vector2 pos = new Vector2 (tickerText.horizontalOffset, 0); TickerTextAnimator[] previous = tickerBandObj.GetComponentsInChildren (); GameObject tickerTextObj = Drawing.CreateText (tickerText.text, null, tickerBandObj.layer, pos, tickerText.font, tickerText.textColor, tickerText.drawTextShadow, tickerText.shadowMaterial, tickerText.shadowColor, tickerText.textAnchor).gameObject; tickerTextObj.layer = tickerBandObj.layer; if (tickerText.drawTextShadow) { tickerTextObj.transform.Find ("shadow").gameObject.layer = tickerTextObj.layer; } tickerText.gameObject = tickerTextObj; tickerText.textMeshSize = tickerTextObj.GetComponent ().bounds.size; tickerTextObj.transform.SetParent (tickerBandObj.transform, false); // Apply scale (text size) Vector3 parentSize = new Vector3 (WorldMapGlobe.overlayWidth, tickerBand.verticalSize * WorldMapGlobe.overlayHeight, 1.0f); float textScale = 0.003f * tickerText.textMeshSize.y; tickerTextObj.transform.localScale = new Vector3 (textScale * parentSize.y / parentSize.x, textScale, 1.0f); tickerText.textMeshSize *= textScale; TickerTextAnimator tta = tickerTextObj.AddComponent (); tta.tickerText = tickerText; tta.map = map; // Position the text float x = pos.x; if (tickerBand.scrollSpeed != 0) { x = 0.5f + 0.5f * tickerText.textMeshSize.x / parentSize.x; // Adds other previous tickertexts on the band float widthSum = 0; for (int p = 0; p < previous.Length; p++) { widthSum += previous [p].tickerText.textMeshSize.x / parentSize.x; } if (widthSum > 0) x = x + 0.01f + widthSum; if (tickerBand.scrollSpeed > 0) x = -x; } pos = new Vector3 (x, tickerTextObj.transform.localPosition.y); tickerTextObj.transform.localPosition = new Vector3 (pos.x, 0.06f, -0.001f); map.requestMapperCamShot = true; } #endregion } }