• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by morphex · May 05, 2015 at 10:54 AM · script.editor-scriptingwindows

Editor Window - How to center a window.

Like the title said, how does one center a popup window for a instance in the Editor?

Using Screen.Width does not work, unless the window is in full screen, and in the primary monitor.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

5 Replies

· Add your reply
  • Sort: 
avatar image
11
Best Answer

Answer by Bunny83 · May 05, 2015 at 05:31 PM

So i guess your actual question is how you can find out the position and size of Unity's main window? Here you go:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEditor;
 using System.Linq;
 
 public static class Extensions
 {
     public static System.Type[] GetAllDerivedTypes(this System.AppDomain aAppDomain, System.Type aType)
     {
         var result = new List<System.Type>();
         var assemblies = aAppDomain.GetAssemblies();
         foreach (var assembly in assemblies)
         {
             var types = assembly.GetTypes();
             foreach (var type in types)
             {
                 if (type.IsSubclassOf(aType))
                     result.Add(type);
             }
         }
         return result.ToArray();
     }
 
     public static Rect GetEditorMainWindowPos()
     {
         var containerWinType = System.AppDomain.CurrentDomain.GetAllDerivedTypes(typeof(ScriptableObject)).Where(t => t.Name == "ContainerWindow").FirstOrDefault();
         if (containerWinType == null)
             throw new System.MissingMemberException("Can't find internal type ContainerWindow. Maybe something has changed inside Unity");
         var showModeField = containerWinType.GetField("m_ShowMode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
         var positionProperty = containerWinType.GetProperty("position", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
         if (showModeField == null || positionProperty == null)
             throw new System.MissingFieldException("Can't find internal fields 'm_ShowMode' or 'position'. Maybe something has changed inside Unity");
         var windows = Resources.FindObjectsOfTypeAll(containerWinType);
         foreach (var win in windows)
         {
             var showmode = (int)showModeField.GetValue(win);
             if (showmode == 4) // main window
             {
                 var pos = (Rect)positionProperty.GetValue(win, null);
                 return pos;
             }
         }
         throw new System.NotSupportedException("Can't find internal main window. Maybe something has changed inside Unity");
     }
 
     public static void CenterOnMainWin(this UnityEditor.EditorWindow aWin)
     {
         var main = GetEditorMainWindowPos();
         var pos = aWin.position;
         float w = (main.width - pos.width)*0.5f;
         float h = (main.height - pos.height)*0.5f;
         pos.x = main.x + w;
         pos.y = main.y + h;
         aWin.position = pos;
     }
 }

Just use Extensions.GetEditorMainWindowPos() to get back the rect of the main window in screen coordinates.

I've also written a simple extension method for the EditorWindow class called "CenterOnMainWin". So inside yout editor window you can simply call CenterOnMainWin() and the window should positioning itself in the center of the main window.

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · May 05, 2015 at 05:36 PM 1
Share

Of course, as you can see on the safety checks, it's possible that this method breaks in the future since we access internal classes / variables via reflection. It's very unlikely that those things will be changed but i just want to say that it's possible.

On the other hand Unity also changed the official API and deprecates things from now and then. So you never have a guarantee that anything will still work in a few years.

edit
Also note that when calling Extensions.GetEditor$$anonymous$$ainWindowPos() or CenterOn$$anonymous$$ainWin() it searches through all class types that exists within Unity and your current project. Then it also uses Resources.FindObjectsOfTypeAll which searches through all objects within Unity. So it's not recommended to call this method on a regular basis (update delegate or OnGUI).

It could be optimised by caching the PropertyInfo value and the mainWindow container window value in a static variable.

avatar image morphex · May 06, 2015 at 07:14 AM 0
Share

Exactly what I needed, and now I feel dumb for not thinking in Reflecting to get the window position.!!


Edit : Quick Question though, how did you find name ContainerWindow? Or how did you know that it was the correct one?

avatar image Bunny83 · May 06, 2015 at 05:34 PM 0
Share

@morphex: Well, i studied Unity's GUI system way back and i know most of the internal structures ^^ (at least on the managed side).

An EditorWindow is actually just a ScriptableObject. That instance is wrapped in a HostView (which is responsible for the "tabs" at the top). The HostView might be embedded in a SplitView (if there are multiple EditorWindows attached next to each other". Finally at the top of the chain you will find the ContainerWindow (also a ScriptableObject) which represents an actual window (in the sense of OS GUI).

There's a special View called $$anonymous$$ainWindow which is the actual View that represents the main window. When the ContainerWindow for the $$anonymous$$ainWindow view is created / shown it uses "Show$$anonymous$$ode.$$anonymous$$ainWindow" (which is an enum and has the value "4"). The showmode is stored inside the ContainerWindow in the internal variable "m_Show$$anonymous$$ode". So you just have to find a ContainerWindow with that showmode and you know it's the main window ^^

This answer was powered by:
http://ilspy.net/

avatar image andreaskuenz · Apr 08, 2020 at 05:04 PM 0
Share

Thanks for the code. Pretty much to do to just get the correct center of the screen. This solution was the only one working for me. So I've used this code to create a 200x200 sized window in the screen center:

 popup window = ScriptableObject.CreateInstance();
         window.position = new Rect(0, 0, 200, 200);
         Extensions.CenterOn$$anonymous$$ainWin(window);


avatar image Bunny83 andreaskuenz · Apr 08, 2020 at 06:08 PM 0
Share

Note that CenterOn$$anonymous$$ainWin is an extension method. So you can simply do

 window.CenterOn$$anonymous$$ainWin();

Also note that this code does not center the window on the screen or desktop but just relative to the Unity main window. Since many people nowadays have a multi-monitor setups and an extended desktop, centering on the desktop wouldn't make much sense.

avatar image andreaskuenz Bunny83 · Apr 09, 2020 at 07:24 AM 0
Share

Thanks for the update. Works perfectly.

avatar image SolidAlloy · Oct 14, 2020 at 12:57 PM 0
Share

Be aware that a new method was added to Unity 2020: EditorGUIUtility.Get$$anonymous$$ainWindowPosition(). It acts the same way as GetEditor$$anonymous$$ainWindowPos() and is obviously faster, so you should use only the CenterOn$$anonymous$$ainWin method with the following modification:

 public static void CenterOn$$anonymous$$ainWin(this UnityEditor.EditorWindow aWin)
 {
      var main = EditorGUIUtility.Get$$anonymous$$ainWindowPosition();
      var pos = aWin.position;
      float w = (main.width - pos.width)*0.5f;
      float h = (main.height - pos.height)*0.5f;
      pos.x = main.x + w;
      pos.y = main.y + h;
      aWin.position = pos;
  }
avatar image
3

Answer by ThomLaurent · May 31, 2017 at 11:51 AM

Actually the correct answer would rather be:

 var window = GetWindow<MyWindow>("Centered Window");
 var position = window.position;
 position.center = new Rect(0f, 0f, Screen.currentResolution.width, Screen.currentResolution.height).center;
 window.position = position;
 window.Show();

using Screen.currentResolution.width and Screen.currentResolution.height.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Jun 01, 2017 at 09:45 AM 3
Share

I would be careful with absolute terms like "correct". The question wasn't about centering the window in the main-screen but centered inside the Unity$$anonymous$$ain window. For example if you have Unity on your second monitor your code would still open the window centered on the main monitor.

EditorWindows are sub-windows of the Unity editor and logically belong to Unity itself and do not act like seperate programs. Your code works for centering an editor window on the main monitor but that's not necessarily what you want.

avatar image
3

Answer by SolidAlloy · Oct 14, 2020 at 01:00 PM

There is a new method added to Unity 2020: EditorGUIUtility.GetMainWindowPosition().

It acts the same way as GetEditorMainWindowPos() but it's obviously faster, so you should use only the CenterOnMainWin method from the Bunny83's answer with the following modification:

 public static void CenterOnMainWin(this EditorWindow window)
 {
     Rect main = EditorGUIUtility.GetMainWindowPosition();
     Rect pos = window.position;
     float centerWidth = (main.width - pos.width) * 0.5f;
     float centerHeight = (main.height - pos.height) * 0.5f;
     pos.x = main.x + centerWidth;
     pos.y = main.y + centerHeight;
     window.position = pos;
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jason_skillman · Nov 03, 2020 at 03:16 AM 1
Share

Thanks, this is exactly what I was looking for.

avatar image
0

Answer by Darcy_zh · Nov 30, 2021 at 07:48 AM

If without 2020, doing this will be much faster

 private static Type GetType (this AppDomain aAppDomain, Type aType, string name)
         {
             var        assemblies   = aAppDomain.GetAssemblies ();
             return assemblies.SelectMany (assembly => assembly.GetTypes ()).FirstOrDefault (type => type.IsSubclassOf (aType) && type.Name == name);
         }
 
 var containerWinType =
                 AppDomain.CurrentDomain.GetType (typeof (ScriptableObject), "ContainerWindow");
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by diogosnows · Mar 23 at 01:45 PM

I was having a similar issue and to get Unity's window center I'm now using:

 var windowCenter = EditorGUIUtility.GetMainWindowPosition().center;

I haven't tested this across multiple setups, but is also working on a recent MacBook which was an issue before.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

10 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Make custom editor for generic class to apply to all current and future child classes 1 Answer

Keep track of how many times the editor goes into play mode? 2 Answers

VS code with unity not working. 1 Answer

LaunchFullTrustProcessForCurrentAppAsync with parameters 0 Answers

Is there a tool to create managed dll wrapper? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges