NewsPanelUI
Overview
Ticker-style news marquee that scrolls localized lines horizontally and periodically performs a vertical slide-up to swap in the next line. It uses two synchronized TextMeshProUGUI elements (A & B) to create a seamless loop, supports pause via an Atom, and reloads content on language changes. fileciteturn25file0
Data Source & Localization
- Loads a
NewsDataJSON fromResources/News/News(or from a serialized_newsJsonwhen present). - Builds per-line I2 keys
NEWS_000,NEWS_001, … and pulls strings viaLocalizationManager.GetTranslation(key). - If a line contains
{region_name}, the placeholder is replaced with a random Region’s localized name fromGameManager.GetAllRegions(). - Subscribes to
LocalizationManager.OnLocalizeEventand restarts the marquee on language change. fileciteturn25file0
Serialized Fields
State / Control
BoolVariable isPaused— whentrue, all movement halts.
Scroll Settings
float scrollSpeed = 100f— pixels/second (left for marquee, up for slide).float repeatSpacing = 64f— gap between A’s end and B’s start in the loop.float loopDuration = 30f— time to recycle A/B before finishing the cycle.float endDelay = 1f— pause after the final horizontal snap, before slide-up.float startDelay = 1f— pause after slide-up, before the next marquee.
UI
RectTransform maskRect— viewport withRectMask2D.TextMeshProUGUI newsText(A),newsSecondText(B).
Padding
float startPadding = 6f— starting offset at the right edge.float endPadding = 10f— right bound for the finishing snap. fileciteturn25file0
Public API
public void ResizeRectAndPlay();
// Measures the current text, positions both labels, and starts the marquee.
Internally this calls PrepareHorizontalFor(...) then starts ScrollNews(...). fileciteturn25file0
How It Works
Horizontal marquee (A/B loop)
- Both labels show the same string and are placed just outside the right edge (
maskRect.width + startPadding). - The script measures width using
TMP_Text.GetPreferredValues(...)to fit each label’sRectTransform. - While
loopDurationhas not elapsed, both labels move left atscrollSpeed, and when one fully exits on the left it’s moved to the right of its sibling bywidth + repeatSpacing. - After the loop time expires, the script finishes cleanly by snapping whichever label is near the right bound so its right edge lands at
maskRect.width - endPadding, then hands off to slide-up. fileciteturn25file0
Vertical slide-up transition
- Designates the currently visible label as top and the other as bottom (placed just below the viewport).
- Removes one instance of the current line from the rotation and picks a new localized line.
- Only the bottom label’s text is changed; both move up until the bottom reaches the resting Y.
- Marks the new line as pending and, after
startDelay, restarts the marquee with the fresh content. fileciteturn25file0
Notes & Quirks
- The constant
rightStopMargin(10 px) is used to detect when a label is close enough to the right bound to snap precisely. RemoveOneInstance(...)currently removes from the localized key list using the visible text string, which won’t match and thus won’t remove anything — likely a small bug worth adjusting (compare keys, not text).- The serialized
static string newsDataPath = "News\\"is unused at runtime; loading uses the hardcoded"News/News"path. Consider de‑staticizing or removing. fileciteturn25file0
Integration Checklist
- Place the component under a
RectMask2Dviewport and wire A and B TMP labels. - Provide
Resources/News/News.jsonwith aNewsDatapayload (items: string[]). - Add I2 terms
NEWS_000,NEWS_001, … that mirror the JSON order. - Optionally include
{region_name}in lines to inject random region names. - Bind
isPausedto your global pause atom so the marquee respects game state. fileciteturn25file0