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 /
This question was closed Oct 03, 2013 at 02:47 PM by Fattie for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by CiberX15 · Sep 29, 2013 at 01:48 AM · javascriptinheritancemonoscriptjavascript class

How to store a javascript in a variable in the editor then call a function from it?

Well that's a long winded question now isn't it. Let me try and clarify what I am trying to do. I am creating an RPG where the player will be able to walk up to objects in the game and "use" them. I expect the number of things that an object could do will grow quite large so instead of trying to put all the behavior on one script I want to have several individual scripts that can be referenced depending on which behavior I want the object to have.

For example a door would contain a "BaseObject" script component, which has a variable called "InteractScript". Developers could then drag a "door" javascript into the InteractScript inspector. the When the player uses the door in the game "BaseObject" the will call "InteracScript.Activate()"

All interact scripts will all have an Activate() function, but what that function does will very greatly. In this way the "Door" InteracScript would open and close when the Activate() function was called, but the furnace would open a crafting menu.

If you can't tell already I started my programming career in Unrealscript, so I am used to extending classes and passing functions down from inheritance. I know this can be done in Unity too I just haven't got it figured out yet.

Thanks in advance for any help you can provide : )

P.S. please answer with java-script if possible.

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

  • Sort: 
avatar image
1
Best Answer

Answer by CiberX15 · Sep 30, 2013 at 01:18 AM

Ok, I finally got this working exact how I wanted it. What I had to do first was make my base class extend from monobehavior as such:

 class InteractBase extends MonoBehaviour
 {
     function Activate(User : GameObject, Self : GameObject)
     {
         Debug.Log("=============== DEFALUT ACTIVATE =======================");
     }
     
 }

Then I could create new classes that extended from that one and overrode the Aactivate() function as such:

 class Door extends InteractBase
 {
     private var Open = false;
     
     function Activate(User : GameObject, ThisObject : GameObject)
     {
         Debug.Log("========================  OPEN THE DOOR HAL!  ===============================");
         
         if(Open)
         {    
             //CLOSE DOOR
             ThisObject.animation[animation.clip.name].speed = -1;
             ThisObject.animation[animation.clip.name].normalizedTime = 1.0;
             ThisObject.animation.Play();
             Open = false;
             Debug.Log("Close Door");
         }
         else
         {
             //OPEN DOOR
             ThisObject.animation[animation.clip.name].speed = 1;
             ThisObject.animation.Play();
             Open = true;
             Debug.Log("Open Door");
         }
     }
     
     function InteractHit()
     {
         //Debug.Log("DOOR HIT");
     }
     
 
 }

Then in my script that runs on all of my objects I created a variable to store an instance of my custom InteractBase class script. Then when the player used the item, the main script would check if the variable had anything in it, and if so, call Activate() on that object as such:

 var InteractScript : InteractBase;

 
 //called when the player presses interac with this item
 function Interact(User : GameObject)
 {
     if(InteractScript != null)
     {
         InteractScript.Activate(User, gameObject);
     }
 }

Then finally to make it all work, I would attach the script in question, in this case "Door," and then drag the script component in the inspector into the main scripts InteractScript variable which would be attached to the same object.

Once all of this was done, when the player hit use on the object, the main code checked if its InteractScript had anything in it, and if so called the Activate() function on it. In this case causing the door to toggle open and closed.

This was a massive issue that has been holding me back in unity for months. I hope that this helps anyone else trying to do the same thing. : )

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
2

Answer by whydoidoit · Sep 29, 2013 at 05:57 AM

It can be done in Unity - but the question is probably more "should it be done" in Unity. My contention would be that using inheritence to perform these kind of actions ties you in knots. I would always do one of these things:

  • SendMessage (BroadcastMessage)

  • Use interfaces (and maybe create a base class that does the core implementation for me)

  • Use .NET events / delegates

Your easiest method for something as simple as you suggest is to just use SendMessage - it is perfectly fast enough for this kind of interaction.

    SendMessage("Activate")

And any scripts on the object with an Activate function will perform it. This is cool because you could attach two scripts that do different things, one opens the door, the other turns on a Red Light above it. To make that just attach the two scripts. You could also use BroadcastMessage and if the door had children with relevant scripts they would be activated too.

Now the interface method is slightly trickier, but it's faster so if you needed something to happen every frame then you'd go this way perhaps. An example of where I use interfaces is the weapon systems on my AI military vehicles. I can attach any number of weapons to a vehicle, each of which implements an interface that returns it's capacity, firepower, availability etc and provides the method to fire. I need to query this data often, so SendMessage is not applicable (it's really for infrequent events).

So you might say - why don't you make all of your weapons inherit from a base Weapon class? The answer is long bloody experience, where you get a weapon that doesn't fit the base class model and ends up carrying around a load of rubbish that makes no sense to it. Sure it might be fine - but you will end up refactoring thinking "oh right I need a new intermediary class don't I, to describe that group of weapons - right". It all takes too long for my liking. By using an interface I can still create a base Weapon class that most weapons use, but my special cases just don't bother inheriting from it and provide their own implementation.

In fact in that way you can get great mix and match - so a weapon could implement more than one interface to enable simple sub behaviours (like being intefered with electronically or being rechargable etc etc).

The real benefit of this kind of approach really fits with Unity's model. Don't build massively complicated classes and scripts, build simple ones and get them to work together to build a much wider array of effects and behaviours.

The final method would be to use a .NET event or a set of delegates. Using that approach your "Activate" call on a well known script (Activatable.cs?) would raise an event. Other scripts attached to the game object could listen for that event by adding and destroying handlers for it. Events are pretty much as fast as interfaces (meaning it's the same as calling a normal method).

       using System;
       using System.Collections;
       using UnityEngine;

       public class Activatable : MonoBehaviour
       {
           public event Action OnActivated = delegate {};
           public event Action<float> OnDamaged = delegate {};

           public void Damaged(float damage) { OnDamaged(damage); }
           public void Activated() { OnActivated(); }

       }


   //Door.cs
   public class Door : MonoBehaviour
   {
         void OnEnable() { GetComponent<Activatable>().OnActivated += Activated; }
         void OnDisable() { GetComponent<Activatable>().OnActivated -= Activated; }

   

       void Activated()
       {
       }
   }



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 whydoidoit · Sep 29, 2013 at 06:01 AM 0
Share

Oh sorry, that last example was C# - interfaces and events do work in JS. I'd stick to C# myself though - it's a matter of preference, but it's a more flexible language although slightly more verbose for some things that Unity Script.

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

Using functions of Inherited classes 3 Answers

Variables depending on enum selection 0 Answers

Difficulty instantiating to a custom class 2 Answers

Extending a Singleton base class (UJS) (?) 2 Answers

How can I access an inherited method from a separate (collided) object? 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