99using Unity . BossRoom . Gameplay . Messages ;
1010using Unity . BossRoom . Infrastructure ;
1111using VContainer ;
12+ using Random = System . Random ;
1213
1314public class MessageFeed : MonoBehaviour
1415{
@@ -96,9 +97,20 @@ void OnLifeStateChangedEvent(LifeStateChangedEventMessage eventMessage)
9697 }
9798 }
9899
100+ [ ContextMenu ( "Add RandomMessage" ) ]
101+ public void AddRandomMessage ( )
102+ {
103+ var rand = new Random ( nameof ( AddRandomMessage ) . GetHashCode ( ) ) ;
104+ m_Messages . Add ( new Message { isShown = true , startTime = Time . realtimeSinceStartup , message = rand . Next ( ) . ToString ( ) } ) ;
105+ }
106+
99107 void Start ( )
100108 {
101109 var root = doc . rootVisualElement ;
110+
111+ // you could load this template from a template uxml, don't need to be a part of the visual tree
112+ // could make it a prop on this monobehaviour
113+ // VisualTreeAsset messageTempalte; or load it via Resources api, than you don't need to hide them
102114 var templateLabel = root . Q < Label > ( "messageLabel" ) ;
103115 var templateBox = root . Q < VisualElement > ( "messageBox" ) ;
104116
@@ -108,13 +120,45 @@ void Start()
108120
109121 m_Messages = new List < Message > ( ) ;
110122
111- // Create a container for all messages
112- m_MessageContainer = new VisualElement ( ) ;
123+ // Create a container for all messages
124+ var listView = root . Q < ListView > ( "messageList" ) ;
125+ listView . makeItem += ( ) =>
126+ {
127+ // Create a new message if no reusable messages are available
128+ var newBox = new VisualElement ( ) ;
129+ newBox . AddToClassList ( "messageBox" ) ;
130+ //newBox.style.position = Position.Absolute; // Explicitly position it
131+
132+ // Position the new message box below the last message
133+ //newBox.style.top = m_MessageContainer.childCount * (messageHeight + verticalSpacing);
134+
135+ var newLabel = new Label ( ) ;
136+ newLabel . AddToClassList ( "message" ) ;
137+ newBox . Add ( newLabel ) ;
138+
139+
140+ newBox . style . opacity = 1 ;
141+ newBox . style . display = DisplayStyle . Flex ;
142+
143+ newBox . RegisterCallback < AttachToPanelEvent > ( ( e ) => StartCoroutine ( FlyInWithBounce ( e . target as VisualElement , - 300 , 50 , 0.2f , 0.2f ) ) ) ;
144+
145+ return newBox ;
146+ } ;
147+
148+ listView . bindItem += ( element , i ) =>
149+ {
150+ element . Q < Label > ( ) . text = m_Messages [ i ] . message ;
151+ } ;
152+
153+ // collection change events will take care of creating and disposing items
154+ listView . itemsSource = m_Messages ;
155+
156+
157+ m_MessageContainer = listView ;
113158 m_MessageContainer . style . flexDirection = FlexDirection . Column ; // Arrange messages vertically
114159
115160 // make sure other visual elements don't get pushed down by the message container
116161 m_MessageContainer . style . position = Position . Absolute ;
117- doc . rootVisualElement . Add ( m_MessageContainer ) ;
118162 }
119163
120164 void OnDestroy ( )
@@ -132,11 +176,11 @@ void Update()
132176 if ( m . isShown )
133177 {
134178 // Check if a message should begin fading out
135- if ( Time . realtimeSinceStartup - m . startTime > 5 && m . messageBox . style . opacity == 1 )
136- {
137- StartFadeout ( m , 1f ) ;
138- m . isShown = false ;
139- }
179+ // if (Time.realtimeSinceStartup - m.startTime > 5 && m.style.opacity == 1)
180+ // {
181+ // StartFadeout(m, 1f);
182+ // m.isShown = false;
183+ // }
140184 }
141185 }
142186 }
@@ -161,40 +205,22 @@ void ShowMessage(string message)
161205
162206 if ( newMessage == null )
163207 {
164- // Create a new message if no reusable messages are available
165- var newBox = new VisualElement ( ) ;
166- newBox . AddToClassList ( "messageBox" ) ;
167- newBox . style . position = Position . Absolute ; // Explicitly position it
168- // Position the new message box below the last message
169- //newBox.style.top = m_MessageContainer.childCount * (messageHeight + verticalSpacing);
170-
171- var newLabel = new Label ( ) ;
172- newLabel . AddToClassList ( "message" ) ;
173- newBox . Add ( newLabel ) ;
174-
175208 newMessage = new Message ( )
176209 {
177210 isShown = true ,
178211 startTime = Time . realtimeSinceStartup ,
179- messageBox = newBox ,
180- Label = newLabel
181212 } ;
182213
183- m_MessageContainer . Add ( newBox ) ; // Add the message box to the parent container
184214 m_Messages . Add ( newMessage ) ; // Add to the list of messages
185215 }
186216
187217 // Set the properties of the reused or new message
188218 newMessage . isShown = true ;
189- newMessage . Label . text = message ;
219+
190220 newMessage . startTime = Time . realtimeSinceStartup ;
191- newMessage . messageBox . style . opacity = 1 ;
192- newMessage . messageBox . style . display = DisplayStyle . Flex ;
193-
194- // Start a fly-in animation
195- StartCoroutine ( FlyInWithBounce ( newMessage . messageBox , - 300 , 50 , 0.2f , 0.2f ) ) ;
221+ newMessage . message = message ;
196222 }
197-
223+
198224 IEnumerator FlyInWithBounce ( VisualElement element , float startLeft , float targetLeft , float duration , float bounceDuration )
199225 {
200226 float elapsedTime = 0 ;
@@ -243,6 +269,7 @@ IEnumerator FlyInWithBounce(VisualElement element, float startLeft, float target
243269 element . style . left = targetLeft ;
244270 }
245271
272+ /*
246273 static void StartFadeout(Message message, float opacity)
247274 {
248275 message.messageBox.schedule.Execute(() =>
@@ -259,12 +286,13 @@ static void StartFadeout(Message message, float opacity)
259286 }
260287 }).Every((long)0.1f).Until(() => opacity <= 0);
261288 }
289+ */
262290
291+ // if you bind the itemsource to the list you don't actually have to manually do this
263292 class Message
264293 {
265294 public bool isShown ;
266295 public float startTime ; // The time when the message was shown
267- public VisualElement messageBox ;
268- public Label Label ;
296+ public string message ;
269297 }
270298}
0 commit comments