using System.Collections.Generic; using UnityEngine; namespace MSCO { /// /// Kleine Hinweise oben rechts (unter der Ping-Anzeige), z.B. "Bob joined" / "Bob left". /// Gleiten von rechts herein, bleiben ein paar Sekunden und blenden dann aus. Höchstens 4 gleichzeitig. /// public class Toasts { const float Lifetime = 4.5f; const float SlideIn = 0.25f; const float FadeOut = 0.6f; const float Width = 250f; const float Height = 36f; const int MaxShown = 4; class Toast { public string Text; public string Detail; public Color Dot; public float Start; } readonly List toasts = new List(); GUIStyle box, title, detail; Texture2D dotTex; public void Add(string text, string detail, Color dot) { toasts.Add(new Toast { Text = text, Detail = detail, Dot = dot, Start = Time.realtimeSinceStartup }); if (toasts.Count > MaxShown) toasts.RemoveAt(0); } public void Draw() { if (toasts.Count == 0) return; EnsureStyles(); float now = Time.realtimeSinceStartup; toasts.RemoveAll(t => now - t.Start > Lifetime); Color before = GUI.color; float y = 40f; // unter der Ping-Anzeige for (int i = toasts.Count - 1; i >= 0; i--) // neueste oben { Toast t = toasts[i]; float age = now - t.Start; float slide = Mathf.Clamp01(age / SlideIn); slide = 1f - (1f - slide) * (1f - slide); // weich abbremsen float alpha = Mathf.Clamp01((Lifetime - age) / FadeOut); var r = new Rect(Screen.width - 12 - Width + (1f - slide) * (Width + 20f), y, Width, Height); GUI.color = new Color(1f, 1f, 1f, alpha); UiTheme.DrawShadow(r); GUI.Box(r, GUIContent.none, box); GUI.color = new Color(t.Dot.r, t.Dot.g, t.Dot.b, alpha); GUI.DrawTexture(new Rect(r.x + 14, r.y + Height / 2f - 4, 8, 8), dotTex); GUI.color = new Color(1f, 1f, 1f, alpha); GUI.Label(new Rect(r.x + 32, r.y, r.width - 40, Height), t.Text, title); if (!string.IsNullOrEmpty(t.Detail)) { float w = title.CalcSize(new GUIContent(t.Text)).x; GUI.Label(new Rect(r.x + 32 + w + 6, r.y, r.width - 46 - w, Height), t.Detail, detail); } y += Height + 6f; } GUI.color = before; } void EnsureStyles() { if (box != null && box.normal.background != null) return; box = UiTheme.Card(new Color(0.06f, 0.06f, 0.07f, 0.92f), 6); title = new GUIStyle(GUI.skin.label) { fontSize = 13, fontStyle = FontStyle.Bold, alignment = TextAnchor.MiddleLeft }; title.normal.textColor = Color.white; title.wordWrap = false; detail = new GUIStyle(title) { fontStyle = FontStyle.Normal, fontSize = 12 }; detail.normal.textColor = UiTheme.Muted; dotTex = RoundDot(16); } static Texture2D RoundDot(int size) { var t = new Texture2D(size, size, TextureFormat.ARGB32, false); float c = (size - 1) / 2f; for (int x = 0; x < size; x++) for (int y = 0; y < size; y++) { float d = Mathf.Sqrt((x - c) * (x - c) + (y - c) * (y - c)); t.SetPixel(x, y, new Color(1f, 1f, 1f, Mathf.Clamp01(c + 0.5f - d))); } t.Apply(); t.hideFlags = HideFlags.HideAndDontSave; return t; } } }