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
2
Question by UnityBrains · Dec 13, 2011 at 04:07 PM · c#variableinheritance

Using a script as a member variable in another script.

Hey,

I will preface this by saying I am using C# for my scripts.

I have a script called ButtonAction. It is derived from MonoBehaviour. It has a function named Respond().

I have a script called LoadScene. It is derived from ButtonAction. It also has a funciton named Respond().

I have a script called PlaySound. It is derived from ButtonAction. It also has a function named Respond().

I have a game object. It has a script named StaticObject attached to it.

In the script StaticObject, I want to have a public variable. This variable must, essentially, be a script. More specifically, a ButtonAction script. More specifically still, the variable must hold a script derived from ButtonAction.

In the script StaticObject, I wish to call the Respond() function of the aforementioned member variable, and have the appropriate function be called.

This is to achieve a system where I can have a Prefab that has the StaticObject script attached to it and I can make many instances of said Prefab but have each one execute a different script when clicked without braking the instance link to the prefab.

Any guidance in achieving this would be appreciated.

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
1
Best Answer

Answer by Statement · Dec 13, 2011 at 04:34 PM

Do you mean that you want an easy way to change the implementation of respond? Unity offer limited existing help for this, since what I guess you want to do is make an option to choose an implementation detail for your component (Strategy Pattern).

If you have a known and fixed set of options, you could do with an enum, and add corresponding component to your object during awake. This is a bit quicker to code than the other solutions since you only need to create an enum, a public variable for it and a switch that add the right component to the object.

If it's not known during code design time and enums aren't an options, you could make an editor inspector script that use reflection to find all derived classes and present them as options. You'd then store the name of that class and use AddComponent with the string or type argument overload.

If I misunderstood you and you just need to be able to link to an existing game object that has a ButtonAction script on it, just add a public variable of that type.

 public ButtonAction action;


Update to comment discussion:

 public class Test : MonoBehaviour
 {
     public enum ClickOptions { ClickMethod1, ClickMethod2, ClickMethod3 }
     public ClickOptions click;
 
     void OnGUI()
     {
         if (GUI.Button(new Rect(0, 0, 64, 64), "Click me"))
             SendMessage(click.ToString());
     }
 
     void ClickMethod1() { Debug.Log("Clicked"); }
     void ClickMethod2() { Debug.Log("Clicketyclick"); }
     void ClickMethod3() { Debug.Log("Click click click"); }
 }

This doesn't add much flexibility in regard to scripts. But you could easily do the same with AddComponent(click.ToString()) if the ClickOptions enum contain name of classes you want to support, and send a message later.

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 UnityBrains · Dec 13, 2011 at 07:59 PM 0
Share

Thanks for the reply,

No you didn't misunderstand me and have outlined the options I thought I had available.

I was thinking of using an enum - it's just that switch statements get messy and huge. Thanks agin!

avatar image Statement · Dec 13, 2011 at 09:41 PM 0
Share

You could use the enums mapped to function calls by string. See updated answer.

avatar image
0

Answer by UnityBrains · Dec 13, 2011 at 09:31 PM

Edit: Read the comments. This doesn't work.

I thought I'd update the situation. I now have the exact behaviour I wanted.

I create an empty game object in my scene. I attach this script to it:

 using UnityEngine;
 using System.Collections;
 
 public class TheScript : MonoBehaviour 
 {        
     // Use this for initialization
     void Start () {}        
     // Update is called once per frame
     void Update () {}
     
     void OnGUI()
     {
         if(GUI.Button(new Rect(x, y, 64, 64), Tex))
         {
             gameObject.AddComponent(a.GetClass());
             gameObject.GetComponent(a.GetClass()).SendMessage("Respond");
             Object.Destroy(gameObject.GetComponent(a.GetClass()));
         }
     }
     
     public Texture2D Tex;
     public UnityEditor.MonoScript a;
     public int x;
     public int y;
 }

I have written this base class script:

 using UnityEngine;
 using System.Collections;
 
 public abstract class BaseClass : MonoBehaviour 
 {    
     // Use this for initialization
     void Start () {}        
     // Update is called once per frame
     void Update () {}
     
     abstract public void Respond();
 }

...from which these are derived: using UnityEngine; using System.Collections;

 public class DerivedA : BaseClass 
 {
     // Use this for initialization
     void Start () {}
     // Update is called once per frame
     void Update () {}
     
     override public void Respond()
     {
         print("DerivedA");
     }
 }

...and: using UnityEngine; using System.Collections;

 public class DerivedA : BaseClass 
 {
     // Use this for initialization
     void Start () {}
     // Update is called once per frame
     void Update () {}
     
     override public void Respond()
     {
         print("DerivedA");
     }
 }

So now, when I drag either DerivedA or DerivedB onto the "A" member variable of TheScript in the inspector, the appropriate "Respond" funciton is called. I am posting this to clarify my original question and posting a solution so that if someone else needs to do this later, they can google it and hopefully find this solution. It may also be common knowledge, but if it is, it's not easy to find. Hopefully this post makes it a little easier.

I would, however, like to get some feedback on the code if possible. It may be somewhat naieve in its execution and could be done more safely, efficiently or easily.

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 Statement · Dec 13, 2011 at 09:40 PM 1
Share

You won't be able to release a build with this since you're referencing UnityEditor inside game code which isn't included in the final build (try it yourself). If you could, it would be a nice feature of Unity indeed!

avatar image UnityBrains · Dec 13, 2011 at 10:05 PM 0
Share

Gah. Cool, thanks for the heads up.

avatar image UnityBrains · Dec 13, 2011 at 10:12 PM 0
Share

EDIT: Another update.

I changed TheScript to use a string ins$$anonymous$$d of the $$anonymous$$onoScript value. It behaves the same, but you have to type in the name of hte script you want to have activate (and this builds and runs :P). It's a bit clunkier than I'd like it to be.

Edit again: Thanks for the help Statement. How do you +Reccommend people here? Your enum suggestion is a nice solution.

avatar image Statement · Dec 14, 2011 at 12:58 PM 0
Share

I think you need at least 20 rep to give upvotes.

avatar image FatWednesday · Sep 27, 2012 at 04:13 PM 0
Share

upvoted for you as it was a good point that I hadn't thought of and let to problems in my own code.

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

An OS design issue: File types associated with their appropriate programs 1 Answer

Javascript not being updated, variables being overridden, but C# is fine 1 Answer

Parent Class variables in Child Class's Inspector (C#) 0 Answers

Editing a variable from another script on collision 3 Answers

Multiple Cars not working 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