• 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
7
Question by Skjalg · Dec 15, 2010 at 02:37 AM · editorwindowzoom

How can I zoom out properly within a EditorWindow

Hi,

As the title asks, I am wondering how I can zoom gui components out properly within a EditorWindow. My code is as follows:

Matrix4x4 before = GUI.matrix; //Scale my gui matrix GUI.matrix = Matrix4x4.Scale(new Vector3(zoomScale, zoomScale, zoomScale)); //Draw my zoomed GUI DrawGUI();

//reset the matrix GUI.matrix = before;

The problem I am getting is that the insides of the editorwindow is moving outside of its limits. alt text

Comment
Add comment · Show 2
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 Skjalg · Dec 15, 2010 at 01:30 PM 0
Share

I have tried setting the position of the editorwindow, but that results in some weird behaviour.

avatar image Bunny83 · Dec 22, 2010 at 03:41 AM 0
Share

Hmm that's really strange... i've showed the actual matrix within the GUI (Vector4Field) but it's just the identity matrix. The matrix is relative to the upper left corner of the window. All stuff you do with GUILayout and so on are computed on top of this matrix. Changing the matrix in between will screw up the relative positions. And it seems like the input-handling of the GUI controls don't get transformed by this matrix (at least not everything: the mouse cursor changes the shape when you hover over the original position of an control). That behaviour makes this property quite useless

4 Replies

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

Answer by Bunny83 · Dec 22, 2010 at 04:53 AM

An evil workaround-hack for custom windows would be applying a translation matrix before scaling and then revert the translation. That way you can move the vanishing point for scaling to a fix position within the window.

 Matrix4x4 before = GUI.matrix;
 //Scale my gui matrix
 Matrix4x4 Translation = Matrix4x4.TRS(new Vector3(0,25,0),Quaternion.identity,Vector3.one);
 Matrix4x4 Scale = Matrix4x4.Scale(new Vector3(zoomScale, zoomScale, zoomScale));
 GUI.matrix = Translation*Scale*Translation.inverse;
 
 //Draw my zoomed GUI
 DrawGUI();
 
 //reset the matrix
 GUI.matrix = before;



edit

Here's an example editorwindow:

 using UnityEngine;
 using UnityEditor;
 
 public class ScaleTest : EditorWindow
 {
     [MenuItem("Window/ScaleTest")]
     static void Init()
     {
         EditorWindow.GetWindow(typeof(ScaleTest));
     }
 
     float zoomScale = 1.0f;    
     Vector2 vanishingPoint = new Vector2(0,21);
 
     void OnGUI()
     {
         Matrix4x4 oldMatrix = GUI.matrix;
 
         //Scale my gui matrix
         Matrix4x4 Translation = Matrix4x4.TRS(vanishingPoint,Quaternion.identity,Vector3.one);
         Matrix4x4 Scale = Matrix4x4.Scale(new Vector3(zoomScale, zoomScale, 1.0f));
         GUI.matrix = Translation*Scale*Translation.inverse;
 
         // Draw the GUI
         GUI.Button(new Rect(0, 0 , position.width*1.5f, 30),"Foo");
         GUI.Button(new Rect(0, 35, 50,                  30),"Bar");
         EditorGUI.FloatField(new Rect(0, 70, 50,30),0.0f);
 
         //reset the matrix
         GUI.matrix = oldMatrix;
 
         // Just for testing (unscaled controls at the bottom)
         GUILayout.FlexibleSpace();
         vanishingPoint = EditorGUILayout.Vector2Field("vanishing point",vanishingPoint);
         zoomScale = EditorGUILayout.Slider("zoom",zoomScale,1.0f/25.0f,2.0f);
     }
 
 }

But as i said already the EditorGUI stuff is not designed to be scaled. You will get a strange behaviour. If you want to scale it down to have more space to draw, that won't work because GUI.matrix also affects the clipping rect of the window. If you scale down the GUI, the drawable area will also shrink.

Here's an overview how it works:

scaling


second edit

I just found a built in function that do the same but even better :D. The EditorGUI problem will be the same (clip rect and mouse cursor) but you can specify the vanishing point in client coordinates like you do with all the GUI stuff.

That will scale around the "client coordinate" [0,0].

GUIUtility.ScaleAroundPivot(Vector2.one * zoomScale,Vector2.zero);

Comment
Add comment · Show 4 · 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 Skjalg · Jan 05, 2011 at 07:20 PM 0
Share

I'm not getting this to work.

avatar image Skjalg · Mar 21, 2011 at 09:45 AM 0
Share

Could you perhaps post me a complete script where you have this working? I have tried so many variants of what you have posted here now that I'm starting to believe there's some code missing...

avatar image Skjalg · Mar 22, 2011 at 07:45 PM 0
Share

Thank you for all your hard work, but without having more space to draw on, then this isn't usable...

avatar image vexe · May 21, 2015 at 07:55 AM 0
Share

@Bunny83 what 'vanishing point' to give if I wanted to zoom out straight up? / zoom in towards the mouse position?

avatar image
3

Answer by martin_ecker · Sep 15, 2012 at 12:40 AM

I wrote a blog post on this topic recently that solves (or "hacks around", if you will) the problem of the clipping rect being incorrect after scaling via GUI.matrix. Check it out here: http://martinecker.com/martincodes/unity-editor-window-zooming/

Comment
Add comment · Show 5 · 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 TakuanDaikon · Aug 09, 2014 at 01:31 PM 1
Share

I'd love more details on this hack, and your blog appears to be non-functional :(

avatar image NeonTheCoder TakuanDaikon · Jun 07, 2018 at 11:13 AM 0
Share

http://archive.is/f5yTk A working link.

avatar image NeonTheCoder · Jun 07, 2018 at 11:13 AM 0
Share

I love the tutorial thank you! And yes your blog is not functional for some reason it only loads half the page then crashes, however someone archived it here: http://archive.is/f5yTk before your blog stopped working. It is a great tutorial thank you.

avatar image martin_ecker NeonTheCoder · Jul 02, 2018 at 04:56 PM 0
Share

Thanks for letting me know that there was a problem on my blog. i wasn't aware but I think I fixed it now. Cheers, $$anonymous$$artin

avatar image Bikrone · Jun 08, 2020 at 10:44 PM 0
Share

Your tutorial works perfectly for me. I must login to thank you :)

avatar image
0

Answer by vexe · May 21, 2015 at 07:45 AM

Here's a version of Bunny's that uses mouse wheel instead of slider to zoom. I'm not sure about the 'e.Use()' at the end. I'm also not certain what's the best value for the 'vanishing point'

 using UnityEngine;
 using UnityEditor;
 
 public class ScaleTest : EditorWindow
 {
     [MenuItem("Window/ScaleTest")]
     static void Init()
     {
         EditorWindow.GetWindow(typeof(ScaleTest));
     }
 
     float zoomScale = 1.0f;
 
     void OnGUI()
     {
         Matrix4x4 oldMatrix = GUI.matrix;
 
         //Scale my gui matrix
         Vector2 vanishingPoint = new Vector2(0, 20);
         Matrix4x4 Translation = Matrix4x4.TRS(vanishingPoint, Quaternion.identity, Vector3.one);
         Matrix4x4 Scale = Matrix4x4.Scale(new Vector3(zoomScale, zoomScale, 1.0f));
         GUI.matrix = Translation * Scale * Translation.inverse;
 
         // Draw the GUI
         GUI.Button(new Rect(0, 0, position.width * 1.5f, 30), "Foo");
         GUI.Button(new Rect(0, 35, 50, 30), "Bar");
         EditorGUI.FloatField(new Rect(0, 70, 50, 30), 0.0f);
 
         //reset the matrix
         GUI.matrix = oldMatrix;

         var e = Event.current;
         if (e.type == EventType.ScrollWheel)
         {
             var zoomDelta = 0.1f;
             zoomDelta = e.delta.y < 0 ? zoomDelta : -zoomDelta;
             zoomScale += zoomDelta;
             zoomScale = Mathf.Clamp(zoomScale, 0.25f, 1.25f);
             e.Use();
         }
     }
 }


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 klaviers · Dec 03, 2016 at 09:34 AM

I am trying to get this to work and also to be able to use scrolling. I had to treat scale>=1 differently then scale<1. This is not perfect but if you can use it and manage to make it better, please post your code!

 public static Vector2 scrollPosition = new Vector2(0,0);
 Rect virtualWindow = new Rect (0, 0, 1000, 1000);
 float maxX=0;
 float maxY=0;
 private static Vector2 pivotPoint;
 private static Vector2 scale_ = new Vector2(scale, scale);

 void OnGUI()
 {
     
     maxX=0;
     maxY=0;
     scale = EditorGUI.Slider(new Rect(position.width/2-100,50,150,20),scale,.5f, 2);
     drawScrollable(scale);
     }

 private void drawScrollable(float scale)
 {
     
     pivotPoint = new Vector2(position.width / 2, position.height / 2);
     scale_.x=scale;
     scale_.y=scale;
     
     
     
     
     Rect clippedArea =  virtualWindow;//.ScaleSizeBy(scale, Vector2.zero);
     
     
     float posAdjX = 0;
     float posAdjY = 0;
     float leftAdjX = 0;
     float leftAdjY = 0;
     Rect scaledVirtualWindow = virtualWindow;
     if(scale>=1f)
         {
             clippedArea.y += 24*scale;
             pivotPoint.x+=scrollPosition.x/2f;
             pivotPoint.y+=scrollPosition.y/2f;
             scaledVirtualWindow = virtualWindow.ScaleSizeBy(scale,pivotPoint);
             
             
         }
     else
         {
             clippedArea.y += 24/scale;
             pivotPoint.x+=scrollPosition.x;
             pivotPoint.y+=scrollPosition.y;
             
             posAdjX=position.width*(scale+1f)-(position.width*scale);
             posAdjY=position.height*(scale+1f)-(position.height*scale);
             
             leftAdjX = (position.width-(posAdjX/scale))/4f;
             leftAdjY = (position.height-(posAdjY/scale))/4f;            
         }
             
     GUI.Label(new Rect(position.width/2-150,70,550,20),
         " svw.left="+scaledVirtualWindow.left+" svw.width="+scaledVirtualWindow.width);
     GUI.Label(new Rect(position.width/2-150,100,550,20),
         " clipped.left="+clippedArea.left+" clipped.width="+clippedArea.width+"  adjustX="+leftAdjX);
     
     
     
     GUI.EndGroup();
     //if(scrollPosition.y<0)scrollPosition.y=0;
     scrollPosition = 
     GUI.BeginScrollView ( new Rect (leftAdjX,leftAdjY,position.width+posAdjX, position.height+posAdjY), scrollPosition, scaledVirtualWindow);
     if(scrollPosition.y<0)scrollPosition.y=0;
     if(scrollPosition.x<0)scrollPosition.x=0;
     Matrix4x4 oldMatrix = GUI.matrix;
         GUIUtility.ScaleAroundPivot(scale_, pivotPoint);
         
             GUI.BeginGroup(clippedArea);


                 drawDialogNodes();//my method to draw nodes
                 drawLinks();    //my method to draw the links
                 
             GUI.EndGroup();
         GUI.matrix = oldMatrix;
     
     GUI.EndScrollView();

     GUI.BeginGroup(new Rect(.0f, 24, Screen.width, Screen.height-24));

 }
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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Issue with custom editor window zooming feature 0 Answers

Accessing GameObjects from Editor static class in Plugins...not. 1 Answer

How to test iOS Joysticks in Editor Game Window? 1 Answer

Editor crashes on EditorWindow.Close() 0 Answers

Open scene and load prefab 1 Answer


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