Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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
0
Question by yoyo · Aug 19, 2013 at 11:58 PM · editorwindowongui

Detect EditorWindow.OnGUI vs. MonoBehaviour.OnGUI to facilitate code sharing?

I'm working on some GUI code (line drawing) that I plan to share between a game component and an editor window. The code is mostly the same, but a couple of things need to be different for use from EditorWindow.OnGUI than for MonoBehaviour.OnGUI. Is there a way to detect which context is active?

EDIT

I want something like this ...

In my component class:

 public class MyComponent: MonoBehaviour
 {
     void OnGUI()
     {
         Drawing.DrawLine(Vector2.zero, Vector2.one * 100.0f);
     }
 }

In my editor window ... public class MyEditorWindow: EditorWindow { void OnGUI() { Drawing.DrawLine(Vector2.zero, Vector2.one * 100.0f); } }

With an implementation that can tell which is which:

 public static class Drawing
 {
     public static DrawLine(Vector2 start, Vector2 end)
     {
         if (isCalledFromEditorWindow)
         {
            ...
         }
         else
         {
            ...
         }
         ...
     }
 }

END EDIT

Here's what I've thought of so far:

  1. Use #if UNITY_EDITOR or Application.isEditor. Sort of works, but I really want the code to be different in the Game panel than it is in my custom editor window, not just different in the editor than in a build.

  2. Pass in an extra parameter to the API indicating that I'm in editor window mode. This would work, but I prefer the caller not have to worry about it.

  3. Use System.Diagnostics.StackTrace to see where I'm being called from. This would work, but would be slow, and what I'm doing is performance-intensive.

What would be great is something like Camera.current.isEditorWindow, but of course that doesn't exist.

Any suggestions?

Comment
Add comment · Show 1
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 yoyo · Aug 20, 2013 at 07:53 PM 0
Share

Turns out my line drawing is fully shareable after all, but I'm still curious to know for future reference.

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Jamora · Aug 21, 2013 at 12:18 AM

Your question doesn't mention if the shared code is static or not, so I'll have a crack at both the alternatives.

In case the shared code is not static, I would create two interfaces: IMonoBehaviourLineDrawer and IEditorLineDrawer. The line drawer class would implement both these interfaces. Then, depending on whether the context is an EditorWindow or a MonoBehaviour, I would just treat the line drawer as the appropriate interface. It would look something like:

 public interface IMonoBehaviourLineDrawer{
     void MonoBehaviourSpecificMethod();
 }
 
 public interface IEditorWindowLineDrawer{
    void EditorWindowSpecificMethod();
 }

 public class LineRenderer : IMonoBehaviourLineDrawer, IEditorWindowLineDrawer
 {/*implementation*/}
 
 //in a MonoBehaviour somewhere
 IMonoBehaviourLineDrawer lineDrawer = new LineRenderer(/*parameters*/);
 lineDrawer.MonoBehaviourSpecificMethod();
 
 //in an EditorWindow
 IEditorWindowLineDrawer lineDrawer = new LineRenderer(/*parameters*/);
 lineDrawer.EditorWindowSpecificMethod();

The methods implemented from the interface would just do whatever specific to the current mode, then call the common code at an appropriate moment.

You might also have to create a hierarchy of interfaces if you have lots of common methods in LineDrawer that you want to call from both modes. Just inherit the above interfaces from ILineDrawer , which contains all the common method declarations.

In case your code is static you could either do an extension method for it, or if you have access to the code just create two different methods that separate between the modes. Basically the same as above, just without the interfaces.

Comment
Add comment · Show 2 · 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 yoyo · Aug 21, 2013 at 05:35 AM 0
Share

Your example shows the $$anonymous$$onoBehaviour and the EditorWindow calling two different methods, which is precisely what I don't want (and if I did I could use different classes). Interfaces could come in handy, but I'd probably choose to have different extensions of the same base class ins$$anonymous$$d. Also note that extension methods are only for instance methods, you can't use them to add static methods.

I will edit my question to be more clear about what I'm trying to do.

avatar image Jamora · Aug 21, 2013 at 12:04 PM 0
Share

$$anonymous$$y example does call two different methods. However, it is completely comparable to the if-else statement in your code currently: one method calls the if-branch, the other method the else branch.

But with a static class using interfaces won't work.

avatar image
0

Answer by Bunny83 · Aug 21, 2013 at 01:00 PM

I would suggest to use a static state variable in your Drawing class which will set the whole class into "editor mode". Since your editor window is a special case the OnGUI code of your editor could look like this

 void OnGUI()
 {
     Drawing.editorMode = true;
     // Your gui stuff
     Drawing.editorMode = false;
 }

That way you don't have to care about the runtime code.

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

17 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Editor GUI Drag Selection Box 1 Answer

Handling NullReferenceException in EditorWindow OnGUI() 0 Answers

How to get an array inside a simple class at Editor window and change arraysize? 0 Answers

How to resize preference window to fit gui contents. 1 Answer

Code executes more than once when key press event is triggered in OnGui in Custom Editor Window 3 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