Marquee
Scrolling message across the bottom of the screen
Marquee.cs
1 // Copyright 2018,19 (C) paul@marrington.net http://www.askowl.net/unity-packages
2 using CustomAsset.Mutable;
3 using UnityEngine;
4 using UnityEngine.UI;
5 
6 namespace Askowl {
7  /// <a href="http://bit.ly/2CSCmQR">Visual object to display a message scrolling across the screen</a><inheritdoc/>
8  public class Marquee : MonoBehaviour {
9  [SerializeField] private Integer charactersPerSecond = default;
10  [SerializeField] private Integer repeats = default;
11  [SerializeField] private String showing = default;
12  [SerializeField] private Trigger showingComplete = default;
13 
14  private Text content;
15  private Fiber display;
16  private int repeat;
17  private Scroller scroller;
18  private string textToDisplay;
19 
20  /// hook into emitters for displaying text and recording completion then prepare the visual
21  protected void Awake() {
22  void show(Emitter emitter) {
23  var text = showing.Value;
24  if (string.IsNullOrEmpty(text)) return;
25  textToDisplay = text;
26  repeat = 0;
27  display.Go();
28  }
29 
30  float pixelsPerSecond = 0;
31 
32  void prepare(Fiber fiber) {
33  if (string.IsNullOrEmpty(textToDisplay)) {
34  fiber.Break();
35  return;
36  }
37  repeat = repeats + 1;
38  content.text = textToDisplay;
39  content.resizeTextMaxSize = content.cachedTextGenerator.fontSizeUsedForBestFit;
40  var rect = content.rectTransform;
41  rect.SetSizeWithCurrentAnchors(axis: RectTransform.Axis.Horizontal, size: content.preferredWidth);
42  scroller.Reset();
43  Vector3[] corners = new Vector3[4];
44  rect.GetWorldCorners(corners);
45  float pixelsWide = corners[2].x - corners[0].x;
46  float pixelsPerCharacter = (pixelsWide / textToDisplay.Length);
47  pixelsPerSecond = charactersPerSecond * pixelsPerCharacter;
48  }
49 
50  void step(Fiber fiber) {
51  if (!scroller.Step(pixelsPerSecond * Time.fixedUnscaledDeltaTime) || (repeat == 0)) fiber.Break();
52  }
53 
54  display = Fiber.Instance.Do(prepare).Begin.Begin.Do(step).Again.Until(_ => --repeat <= 0);
55  display.OnComplete.Listen(_ => showingComplete.Fire());
56  showing.Emitter.Listen(show);
57  if (showing.Emitter.Firings > 0) show(showing.Emitter);
58  }
59 
60  private void OnDestroy() => display.Dispose();
61 
62  /// Use this for initialization - specifically to prepare the scroller
63  protected internal void Start() {
64  RectTransform viewport = GetComponent<RectTransform>();
65  content = GetComponentInChildren<Text>();
66 
67  scroller = new Scroller(content: content.rectTransform, viewport: viewport) {
68  StepSize = {x = -1, y = 0}
69  };
70  }
71 
72  /// Stop scrolling
73  protected internal void OnDisable() {
74  repeat = 0;
75  scroller.Reset();
76  content.text = null;
77  }
78  }
79 }
void Awake()
hook into emitters for displaying text and recording completion then prepare the visual ...
Definition: Marquee.cs:21
Visual object to display a message scrolling across the screen
Definition: Marquee.cs:8