Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
1
Question by alexanderameye · Nov 27, 2016 at 07:04 PM · variableinspectorpublicpublic variable

public script variable in inspector

Hello,

like you can say 'public string' and there will be a box displayed in the script window in the inspector, is there a similar variable that let's you click and drag a script in there?

Thanks!

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

2 Replies

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

Answer by Bunny83 · Nov 27, 2016 at 07:36 PM

This boils down to what you understand by "script". If you ask if you can drag a script asset (the actual .cs or .js file) onto a variable, the answer is "no" for runtime scripts and "yes" for editor scripts.

Scripts inside the Unity editor are represented with the editor type "MonoScript". However that's an editor only class that can't be used in a runtime script.


edit

I quickly have written a property drawer which allows you, by simply attaching an attribute to a string variable, to have an object field in the inspector where you can drag and drop MonoScript files. It will extract the class name of the class inside the MonoScript and save that name in the string variable.

Two files are required:

  • MonoScriptPropertyDrawer.cs - this is the actual PropertyDrawer. This file has to be placed in a folder named "editor" inside your assets folder.

  • MonoScriptAttribute.cs - this is just the custom attribute definition. This file must not be inside an editor folder as it is required by your runtime scripts.

I released those under the MIT license in case someone want to change something.

Ohh it has a hidden "feature". You can click the label of the field in the inspector to toggle between object field and the usual text field where you can manually edit the string. Note however if you manually type in a string that doesn't represent the name of a MonoScript the object field can't link properly back.

To use this property drawer you have to import this namespace in the script where you want to have a MonoScriptField:

 using B83.Unity.Attributes;

Then simply add the "MonoScript" attribute to your string variable like this:

 [MonoScript]
 public string typeName;

That's all


[ original post ]
If however you ask if you can drag and drop a script instance the answer is yes. That's actually one of the main features of Unity. You just have to use the type of script you want to use as variable type.

Short example:

 public class MyScript : MonoBehaviour
 {
     public void Foo()
     {
         Debug.Log("Bar");
     }
 }

In another script you can define a variable of type MyScript:

 public MyScript script;
 
 void Start()
 {
     script.Foo();
 }

When those two scripts are assigned to gameobjects in the scene you can drag the gameobject with the MyScript attached onto the variable "script" in the inspector of the other script.

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 raphafortin · Apr 02, 2020 at 08:19 PM 0
Share

Thanks a great bunch! I actually am using both those scripts :)

How would you use this now with a AddComponent("Your monoscript string here");

avatar image olly1014 · Feb 25, 2021 at 05:44 PM 0
Share

Hey, this is extremely useful, thank you! I just have one question:

If I wanted to restrict the scripts I can assign to only those which derive from a certain abstract class (instead of every script in my project) would that be possible? Is there somewhere in MonoScriptPropertyDrawer.cs I can edit to do this?

avatar image olly1014 olly1014 · Feb 25, 2021 at 07:35 PM 0
Share

@Bunny83 ^

avatar image Bunny83 olly1014 · Feb 25, 2021 at 10:10 PM 0
Share

Uhm , that's already built into the property drawer and the MonoScriptAttribute I created. It has an optional type field that you can set to a certain base type. The field will only allow scripts which are assignable to that type. So you can use interfaces or base classes. Something like that:

 [MonoScript(type = typeof(YourBaseClass))]
 public string typeName;

So "YourBaseClass" can be an interface or base class type that the wanted script has to implement.

Show more comments
avatar image
1

Answer by thechayed · Jul 31, 2021 at 06:13 PM

Hey, just wanted to add to @Bunny83's answer and say that it's incredibly important to use GetClass().FullName instead of .Name, because any classes within a Namespace will throw an error.

Here's the updated MonoScriptPropertyDrawer.cs :

 /*****
  * This is a simple PropertyDrawer for string variables to allow drag and drop
  * of MonoScripts in the inspector of the Unity3d editor.
  * 
  * NOTE: This is an editor script and need to be placed in a folder named "editor".
  *       It also requires another runtime file named "MonoScriptAttribute.cs"
  * 
  * Copyright (c) 2016 Bunny83
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
  * deal in the Software without restriction, including without limitation the
  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  * sell copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
  * 
  * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  * 
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  * IN THE SOFTWARE.
  * 
  *****/
 using UnityEngine;
 using UnityEditor;
 using System.Collections.Generic;
 using B83.Unity.Attributes;
 
 namespace B83.Unity.Editor.PropertyDrawers
 {
 
     [CustomPropertyDrawer(typeof(MonoScriptAttribute), false)]
     public class MonoScriptPropertyDrawer : PropertyDrawer
     {
         static Dictionary<string, MonoScript> m_ScriptCache;
         static MonoScriptPropertyDrawer()
         {
             m_ScriptCache = new Dictionary<string, MonoScript>();
             var scripts = Resources.FindObjectsOfTypeAll<MonoScript>();
             for (int i = 0; i < scripts.Length; i++)
             {
                 var type = scripts[i].GetClass();
                 if (type != null && !m_ScriptCache.ContainsKey(type.FullName))
                 {
                     m_ScriptCache.Add(type.FullName, scripts[i]);
                 }
             }
         }
         bool m_ViewString = false;
 
         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
         {
             if (property.propertyType == SerializedPropertyType.String)
             {
                 Rect r = EditorGUI.PrefixLabel(position, label);
                 Rect labelRect = position;
                 labelRect.xMax = r.xMin;
                 position = r;
                 m_ViewString = GUI.Toggle(labelRect, m_ViewString, "", "label");
                 if (m_ViewString)
                 {
                     property.stringValue = EditorGUI.TextField(position, property.stringValue);
                     return;
                 }
                 MonoScript script = null;
                 string typeName = property.stringValue;
                 if (!string.IsNullOrEmpty(typeName))
                 {
                     m_ScriptCache.TryGetValue(typeName, out script);
                     if (script == null)
                         GUI.color = Color.red;
                 }
 
                 script = (MonoScript)EditorGUI.ObjectField(position, script, typeof(MonoScript), false);
                 if (GUI.changed)
                 {
                     if (script != null)
                     {
                         var type = script.GetClass();
                         MonoScriptAttribute attr = (MonoScriptAttribute)attribute;
                         if (attr.type != null && !attr.type.IsAssignableFrom(type))
                             type = null;
                         if (type != null)
                             property.stringValue = script.GetClass().FullName;
                         else
                             Debug.LogWarning("The script file " + script.name + " doesn't contain an assignable class");
                     }
                     else
                         property.stringValue = "";
                 }
             }
             else
             {
                 GUI.Label(position, "The MonoScript attribute can only be used on string variables");
             }
         }
     }
 }
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 · Jul 31, 2021 at 06:16 PM 0
Share

Yes, you're right. I can't actually remember when Unity added proper namespace support but I guess this was already after they introduced it. Anyways I've updated my code. Btw

 script.GetClass().Name

can be replaced by

 type.FullName;

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

63 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 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 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 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

Cannot assign Public GameObject variable in Inspector... 2 Answers

Why can't I to declare public the variable "Clave"? 1 Answer

Can't initialise public vars in Inspector (C#) 2 Answers

Invisible Public Variable in Inspector 5 Answers

Public "char" parameter not showing on inspector? 2 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