Skip to content
Snippets Groups Projects
Select Git revision
  • 11a89986a1e921f957a917846fdab5789ad89a2d
  • main default protected
  • fixing-controller-assets
  • Begin-scene-generation
  • Startup-UI
  • changing-urp-to-unity-builtin
  • Create-Working-Scene
7 results

SpectatorWindow.cs

Blame
  • SpectatorWindow.cs 5.44 KiB
    using UnityEngine;
    
    public class SpectatorWindow : MonoBehaviour
    {
        private static SpectatorWindow instance;
        private Camera spectatorCam;
        private RenderTexture renderTexture;
        private bool showWindow = true;
        private Rect windowRect = new Rect(100, 100, 800, 450);
        
        [Header("Window Settings")]
        [SerializeField] private bool enableWindowDrag = true;
        [SerializeField] private Vector2Int renderResolution = new Vector2Int(1920, 1080);
        [SerializeField] private Vector2 minWindowSize = new Vector2(400, 225);
        [SerializeField] private Vector2 maxWindowSize = new Vector2(1920, 1080);
        
        private bool isResizing = false;
        private Rect resizeHandleRect;
        private Vector2 resizeStartMouse;
        private Vector2 resizeStartSize;
        private readonly float resizeHandleSize = 20f;
    
        private void Awake()
        {
            if (instance == null)
            {
                instance = this;
                DontDestroyOnLoad(gameObject);
            }
            else
            {
                Destroy(gameObject);
                return;
            }
    
            spectatorCam = GetComponent<Camera>();
            if (spectatorCam == null)
            {
                Debug.LogError("No camera attached to SpectatorWindow!");
                return;
            }
    
            InitializeRenderTexture();
        }
    
        private void InitializeRenderTexture()
        {
            renderTexture = new RenderTexture(renderResolution.x, renderResolution.y, 24);
            renderTexture.antiAliasing = 4;
            spectatorCam.targetTexture = renderTexture;
        }
    
        private void OnGUI()
        {
            if (!showWindow) return;
    
            // Create a solid background style
            var backgroundStyle = new GUIStyle(GUI.skin.window);
            var tex = new Texture2D(1, 1);
            tex.SetPixel(0, 0, new Color(0.2f, 0.2f, 0.2f, 1f));
            tex.Apply();
            backgroundStyle.normal.background = tex;
            
            // Draw the window with solid background
            GUI.backgroundColor = Color.black;
            windowRect = GUI.Window(0, windowRect, DrawWindowContents, "Spectator View", backgroundStyle);
    
            // Handle resizing outside of the window function
            HandleResizing();
        }
    
        private void DrawWindowContents(int windowID)
        {
            // Draw black background for render texture area
            GUI.Box(new Rect(0, 20, windowRect.width, windowRect.height - 20), "");
            
            // Draw the render texture
            GUI.DrawTexture(new Rect(0, 20, windowRect.width, windowRect.height - 20), renderTexture);
    
            // Close button
            if (GUI.Button(new Rect(windowRect.width - 25, 2, 20, 16), "X"))
            {
                showWindow = false;
            }
    
            // Draw resize handle (visual indicator)
            resizeHandleRect = new Rect(windowRect.width - resizeHandleSize, 
                                      windowRect.height - resizeHandleSize, 
                                      resizeHandleSize, resizeHandleSize);
            
            GUI.Box(resizeHandleRect, "↘");
    
            // Window dragging (only if not resizing)
            if (enableWindowDrag && !isResizing)
            {
                GUI.DragWindow(new Rect(0, 0, windowRect.width - resizeHandleSize, 20));
            }
        }
    
        private void HandleResizing()
        {
            // Convert resize handle to screen coordinates
            Rect screenResizeRect = new Rect(
                windowRect.x + windowRect.width - resizeHandleSize,
                windowRect.y + windowRect.height - resizeHandleSize,
                resizeHandleSize,
                resizeHandleSize
            );
    
            Event e = Event.current;
            if (e.type == EventType.MouseDown && e.button == 0 && screenResizeRect.Contains(e.mousePosition))
            {
                isResizing = true;
                resizeStartMouse = e.mousePosition;
                resizeStartSize = new Vector2(windowRect.width, windowRect.height);
                e.Use();
            }
            else if (e.type == EventType.MouseUp && e.button == 0)
            {
                isResizing = false;
            }
            else if (isResizing && e.type == EventType.MouseDrag)
            {
                // Calculate new size
                float newWidth = Mathf.Clamp(resizeStartSize.x + (e.mousePosition.x - resizeStartMouse.x),
                                           minWindowSize.x, maxWindowSize.x);
                float newHeight = Mathf.Clamp(resizeStartSize.y + (e.mousePosition.y - resizeStartMouse.y),
                                            minWindowSize.y, maxWindowSize.y);
    
                // Maintain aspect ratio (16:9)
                float targetAspect = 16f / 9f;
                float currentAspect = newWidth / newHeight;
                
                if (currentAspect > targetAspect)
                {
                    newWidth = newHeight * targetAspect;
                }
                else
                {
                    newHeight = newWidth / targetAspect;
                }
    
                // Apply new size
                windowRect.width = newWidth;
                windowRect.height = newHeight;
                
                e.Use();
            }
        }
    
        private void OnDestroy()
        {
            if (renderTexture != null)
            {
                renderTexture.Release();
                Destroy(renderTexture);
            }
        }
    
        // Public methods
        public void ShowWindow() => showWindow = true;
        public void HideWindow() => showWindow = false;
        public void ToggleWindow() => showWindow = !showWindow;
        
        public void SetWindowSize(float width, float height)
        {
            windowRect.width = Mathf.Clamp(width, minWindowSize.x, maxWindowSize.x);
            windowRect.height = Mathf.Clamp(height, minWindowSize.y, maxWindowSize.y);
        }
    }