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
}
}