Skip to content

Commit ba5336d

Browse files
committed
fix: fixing new MessageFeed so it displays messages dynamically
1 parent 1e01173 commit ba5336d

File tree

9 files changed

+339
-131
lines changed

9 files changed

+339
-131
lines changed

Assets/Prefabs/State/PostGameState.prefab

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ MonoBehaviour:
4747
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
4848
m_Name:
4949
m_EditorClassIdentifier:
50-
GlobalObjectIdHash: 2751448866
50+
GlobalObjectIdHash: 4221458659
5151
InScenePlacedSourceGlobalObjectIdHash: 2795900295
5252
DeferredDespawnTick: 0
53-
Ownership: 1
53+
Ownership: 0
5454
AlwaysReplicateAsRoot: 0
5555
SynchronizeTransform: 0
5656
ActiveSceneSynchronization: 0

Assets/Prefabs/UI/UIToolkit/PostGameUICanvasUITK.prefab

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ Transform:
3030
m_LocalPosition: {x: 0, y: 0, z: 0}
3131
m_LocalScale: {x: 1, y: 1, z: 1}
3232
m_ConstrainProportionsScale: 0
33-
m_Children: []
33+
m_Children:
34+
- {fileID: 2100339957089282678}
3435
m_Father: {fileID: 0}
3536
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
3637
--- !u!114 &2063287831439623020
@@ -65,4 +66,121 @@ MonoBehaviour:
6566
m_Name:
6667
m_EditorClassIdentifier:
6768
m_PostGameUIDocument: {fileID: 2063287831439623020}
68-
m_MessageFeedDocument: {fileID: 0}
69+
--- !u!1 &5550880791410142769
70+
GameObject:
71+
m_ObjectHideFlags: 0
72+
m_CorrespondingSourceObject: {fileID: 0}
73+
m_PrefabInstance: {fileID: 0}
74+
m_PrefabAsset: {fileID: 0}
75+
serializedVersion: 6
76+
m_Component:
77+
- component: {fileID: 2100339957089282678}
78+
- component: {fileID: 1286002055205536738}
79+
m_Layer: 5
80+
m_Name: MessageFeed
81+
m_TagString: Untagged
82+
m_Icon: {fileID: 0}
83+
m_NavMeshLayer: 0
84+
m_StaticEditorFlags: 0
85+
m_IsActive: 1
86+
--- !u!4 &2100339957089282678
87+
Transform:
88+
m_ObjectHideFlags: 0
89+
m_CorrespondingSourceObject: {fileID: 0}
90+
m_PrefabInstance: {fileID: 0}
91+
m_PrefabAsset: {fileID: 0}
92+
m_GameObject: {fileID: 5550880791410142769}
93+
serializedVersion: 2
94+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
95+
m_LocalPosition: {x: 0, y: 0, z: 0}
96+
m_LocalScale: {x: 1, y: 1, z: 1}
97+
m_ConstrainProportionsScale: 0
98+
m_Children:
99+
- {fileID: 5886284794912537810}
100+
m_Father: {fileID: 7855837178462082302}
101+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
102+
--- !u!114 &1286002055205536738
103+
MonoBehaviour:
104+
m_ObjectHideFlags: 0
105+
m_CorrespondingSourceObject: {fileID: 0}
106+
m_PrefabInstance: {fileID: 0}
107+
m_PrefabAsset: {fileID: 0}
108+
m_GameObject: {fileID: 5550880791410142769}
109+
m_Enabled: 1
110+
m_EditorHideFlags: 0
111+
m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
112+
m_Name:
113+
m_EditorClassIdentifier:
114+
m_PanelSettings: {fileID: 11400000, guid: 30704bc49d34869449e8bfdb3ab57841, type: 2}
115+
m_ParentUI: {fileID: 2063287831439623020}
116+
sourceAsset: {fileID: 9197481963319205126, guid: 79e0526232b7b2246a02c77f935c2b2a, type: 3}
117+
m_SortingOrder: 0
118+
m_WorldSpaceSizeMode: 1
119+
m_WorldSpaceWidth: 1920
120+
m_WorldSpaceHeight: 1080
121+
--- !u!1 &8225198564806970540
122+
GameObject:
123+
m_ObjectHideFlags: 0
124+
m_CorrespondingSourceObject: {fileID: 0}
125+
m_PrefabInstance: {fileID: 0}
126+
m_PrefabAsset: {fileID: 0}
127+
serializedVersion: 6
128+
m_Component:
129+
- component: {fileID: 5886284794912537810}
130+
- component: {fileID: 6577115012106585769}
131+
- component: {fileID: 8405269881768119238}
132+
m_Layer: 5
133+
m_Name: MessageItem
134+
m_TagString: Untagged
135+
m_Icon: {fileID: 0}
136+
m_NavMeshLayer: 0
137+
m_StaticEditorFlags: 0
138+
m_IsActive: 1
139+
--- !u!4 &5886284794912537810
140+
Transform:
141+
m_ObjectHideFlags: 0
142+
m_CorrespondingSourceObject: {fileID: 0}
143+
m_PrefabInstance: {fileID: 0}
144+
m_PrefabAsset: {fileID: 0}
145+
m_GameObject: {fileID: 8225198564806970540}
146+
serializedVersion: 2
147+
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
148+
m_LocalPosition: {x: 0, y: 0, z: 0}
149+
m_LocalScale: {x: 1, y: 1, z: 1}
150+
m_ConstrainProportionsScale: 0
151+
m_Children: []
152+
m_Father: {fileID: 2100339957089282678}
153+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
154+
--- !u!114 &6577115012106585769
155+
MonoBehaviour:
156+
m_ObjectHideFlags: 0
157+
m_CorrespondingSourceObject: {fileID: 0}
158+
m_PrefabInstance: {fileID: 0}
159+
m_PrefabAsset: {fileID: 0}
160+
m_GameObject: {fileID: 8225198564806970540}
161+
m_Enabled: 1
162+
m_EditorHideFlags: 0
163+
m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
164+
m_Name:
165+
m_EditorClassIdentifier:
166+
m_PanelSettings: {fileID: 11400000, guid: 30704bc49d34869449e8bfdb3ab57841, type: 2}
167+
m_ParentUI: {fileID: 2063287831439623020}
168+
sourceAsset: {fileID: 9197481963319205126, guid: 67ec44aea0b0f484c86c6489932cfcad, type: 3}
169+
m_SortingOrder: 0
170+
m_WorldSpaceSizeMode: 1
171+
m_WorldSpaceWidth: 1920
172+
m_WorldSpaceHeight: 1080
173+
--- !u!114 &8405269881768119238
174+
MonoBehaviour:
175+
m_ObjectHideFlags: 0
176+
m_CorrespondingSourceObject: {fileID: 0}
177+
m_PrefabInstance: {fileID: 0}
178+
m_PrefabAsset: {fileID: 0}
179+
m_GameObject: {fileID: 8225198564806970540}
180+
m_Enabled: 1
181+
m_EditorHideFlags: 0
182+
m_Script: {fileID: 11500000, guid: 5972d28314a4d794cbe88ba0120b39c0, type: 3}
183+
m_Name:
184+
m_EditorClassIdentifier:
185+
doc: {fileID: 6577115012106585769}
186+
AddMessage: 0

Assets/Prefabs/UI/UIToolkit/USS/MessageFeed.uss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@
4343
transition-property: position;
4444
transition-duration: 2s;
4545
position: relative;
46-
top: 100px;
46+
top: -537px;
4747
left: 10px;
48+
overflow: scroll;
49+
flex-direction: column;
4850
}
4951

5052
.messageList {

Assets/Scenes/PostGame.unity

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:62f3d6e8211c3f6077a052be1427d998c2e87db9ae673cf3207195e58b03d0dd
3-
size 36846
2+
oid sha256:210256cb84e18304ddd5a5b6639fd1f381c07c16d428d5783ea70484d0e8a258
3+
size 31377

Assets/Scripts/Gameplay/GameState/ServerPostGameState.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public class ServerPostGameState : GameStateBehaviour
2323

2424
[SerializeField]
2525
PostGameUI m_PostGameUI;
26+
27+
[SerializeField]
28+
MessageFeed m_MessageFeed;
2629

2730
public override GameState ActiveState { get { return GameState.PostGame; } }
2831

@@ -44,6 +47,7 @@ protected override void Configure(IContainerBuilder builder)
4447
base.Configure(builder);
4548
builder.RegisterComponent(m_NetworkPostGame);
4649
builder.RegisterComponent(m_PostGameUI);
50+
builder.RegisterComponent(m_MessageFeed);
4751
}
4852

4953
void OnNetworkSpawn()
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
using UnityEngine.UIElements;
5+
using Unity.BossRoom.ConnectionManagement;
6+
using Unity.BossRoom.Gameplay.GameplayObjects;
7+
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
8+
using Unity.BossRoom.Gameplay.Messages;
9+
using Unity.BossRoom.Infrastructure;
10+
using VContainer;
11+
using System.Linq;
12+
13+
public class MessageFeed : MonoBehaviour
14+
{
15+
[SerializeField]
16+
UIDocument doc;
17+
18+
List<Message> m_messages;
19+
20+
VisualElement messageContainer;
21+
22+
DisposableGroup m_Subscriptions;
23+
24+
[Inject]
25+
void InjectDependencies(
26+
#if UNITY_EDITOR || DEVELOPMENT_BUILD
27+
ISubscriber<CheatUsedMessage> cheatUsedMessageSubscriber,
28+
#endif
29+
ISubscriber<DoorStateChangedEventMessage> doorStateChangedSubscriber,
30+
ISubscriber<ConnectionEventMessage> connectionEventSubscriber,
31+
ISubscriber<LifeStateChangedEventMessage> lifeStateChangedEventSubscriber
32+
)
33+
{
34+
m_Subscriptions = new DisposableGroup();
35+
#if UNITY_EDITOR || DEVELOPMENT_BUILD
36+
m_Subscriptions.Add(cheatUsedMessageSubscriber.Subscribe(OnCheatUsedEvent));
37+
#endif
38+
m_Subscriptions.Add(doorStateChangedSubscriber.Subscribe(OnDoorStateChangedEvent));
39+
m_Subscriptions.Add(connectionEventSubscriber.Subscribe(OnConnectionEvent));
40+
m_Subscriptions.Add(lifeStateChangedEventSubscriber.Subscribe(OnLifeStateChangedEvent));
41+
}
42+
43+
#if UNITY_EDITOR || DEVELOPMENT_BUILD
44+
void OnCheatUsedEvent(CheatUsedMessage eventMessage)
45+
{
46+
ShowMessage($"Cheat {eventMessage.CheatUsed} used by {eventMessage.CheaterName}");
47+
}
48+
#endif
49+
50+
void OnDoorStateChangedEvent(DoorStateChangedEventMessage eventMessage)
51+
{
52+
ShowMessage(eventMessage.IsDoorOpen ? "The Door has been opened!" : "The Door is closing.");
53+
}
54+
55+
void OnConnectionEvent(ConnectionEventMessage eventMessage)
56+
{
57+
switch (eventMessage.ConnectStatus)
58+
{
59+
case ConnectStatus.Success:
60+
ShowMessage($"{eventMessage.PlayerName} has joined the game!");
61+
break;
62+
case ConnectStatus.ServerFull:
63+
case ConnectStatus.LoggedInAgain:
64+
case ConnectStatus.UserRequestedDisconnect:
65+
case ConnectStatus.GenericDisconnect:
66+
case ConnectStatus.IncompatibleBuildType:
67+
case ConnectStatus.HostEndedSession:
68+
ShowMessage($"{eventMessage.PlayerName} has left the game!");
69+
break;
70+
}
71+
}
72+
73+
void OnLifeStateChangedEvent(LifeStateChangedEventMessage eventMessage)
74+
{
75+
switch (eventMessage.CharacterType)
76+
{
77+
case CharacterTypeEnum.Tank:
78+
case CharacterTypeEnum.Archer:
79+
case CharacterTypeEnum.Mage:
80+
case CharacterTypeEnum.Rogue:
81+
case CharacterTypeEnum.ImpBoss:
82+
switch (eventMessage.NewLifeState)
83+
{
84+
case LifeState.Alive:
85+
ShowMessage($"{eventMessage.CharacterName} has been reanimated!");
86+
break;
87+
case LifeState.Fainted:
88+
case LifeState.Dead:
89+
ShowMessage($"{eventMessage.CharacterName} has been defeated!");
90+
break;
91+
default:
92+
throw new ArgumentOutOfRangeException();
93+
}
94+
95+
break;
96+
}
97+
}
98+
99+
void Start()
100+
{
101+
var root = doc.rootVisualElement;
102+
var templateLabel = root.Q<Label>("messageLabel");
103+
var templateBox = root.Q<VisualElement>("messageBox");
104+
105+
// Hide the default template elements
106+
templateLabel.style.display = DisplayStyle.None;
107+
templateBox.style.display = DisplayStyle.None;
108+
109+
m_messages = new List<Message>();
110+
111+
// Create a container for all messages
112+
messageContainer = new VisualElement();
113+
messageContainer.style.flexDirection = FlexDirection.Column; // Arrange messages vertically
114+
115+
// make sure other visual elements don't get pushed down by the message container
116+
messageContainer.style.position = Position.Absolute;
117+
doc.rootVisualElement.Add(messageContainer);
118+
}
119+
120+
void OnDestroy()
121+
{
122+
if (m_Subscriptions != null)
123+
{
124+
m_Subscriptions.Dispose();
125+
}
126+
}
127+
128+
static void StartFadeout(Message message, float opacity)
129+
{
130+
message.messageBox.style.opacity = opacity;
131+
message.messageBox.schedule.Execute(() =>
132+
{
133+
opacity -= 0.01f;
134+
message.messageBox.style.opacity = opacity;
135+
if (opacity <= 0)
136+
{
137+
message.messageBox.style.display = DisplayStyle.None;
138+
message.startTime = 0;
139+
}
140+
}).Every((long)0.1f).Until(() => opacity <= 0);
141+
}
142+
143+
void ShowMessage(string message)
144+
{
145+
// Limit maximum number of active messages
146+
int maxMessages = 10;
147+
if (m_messages.Count(m => m.isShown) >= maxMessages)
148+
{
149+
// Find the oldest active message and start fading it out
150+
var oldestMessage = m_messages.FirstOrDefault(m => m.isShown && m.startTime > 0);
151+
if (oldestMessage != null)
152+
{
153+
StartFadeout(oldestMessage, 1f);
154+
oldestMessage.isShown = false;
155+
}
156+
}
157+
158+
// Reuse or create a new message
159+
foreach (var m in m_messages)
160+
{
161+
if (!m.isShown)
162+
{
163+
m.isShown = true;
164+
m.Label.text = message;
165+
m.messageBox.style.display = DisplayStyle.Flex;
166+
m.startTime = Time.realtimeSinceStartup;
167+
168+
return;
169+
}
170+
}
171+
172+
// Create a new message container
173+
var newBox = new VisualElement();
174+
newBox.AddToClassList("messageBox");
175+
176+
var newLabel = new Label();
177+
newLabel.text = message;
178+
newLabel.AddToClassList("message");
179+
180+
newBox.Add(newLabel);
181+
182+
var newMessage = new Message()
183+
{
184+
isShown = true,
185+
startTime = Time.realtimeSinceStartup,
186+
messageBox = newBox,
187+
Label = newLabel
188+
};
189+
190+
messageContainer.Add(newBox);
191+
m_messages.Add(newMessage);
192+
}
193+
194+
195+
class Message
196+
{
197+
public bool isShown;
198+
public float startTime; // The time when the message was shown
199+
public VisualElement messageBox;
200+
public Label Label;
201+
}
202+
}
File renamed without changes.

0 commit comments

Comments
 (0)