- Home /
How to get script component of an object with out using its name?
I am having multilple objects having different name and each having single script but different name. I'm having object reference and want to get script attached on it but without using script name. Does anyone know about it?
Even if there was a way to get the script you want, to use it you would need a cast, which means you need that scripts type. The simplest thing which comes to $$anonymous$$d first is, you should use a custom logic. Like this: try one script, if it is not attached try another and so on. You can also try declaring an abstract class which is ascendant of all of possible scripts you can get. I have not tried this and have no guarantee that it will work. I neither know if a $$anonymous$$onoBehavior script can inherit from another class.
Thanks to interfaces, no need for a cast nor for a manual search of the script.
Thanks for your valuable suggestion. But in C# a class can inherit only one class that's why monobehaviour script cann't inherit another class.
Answer by fafase · Feb 03, 2014 at 08:20 AM
What you need is to look into interfaces First you could declare an interface:
public interface IMyInterface
{
void MethodINeed();
}
then you have all of your other classes, let's use two of them.
public class ClassA:MonoBehaviour,IMyInterface
{
public void MethodINeed(){print("This is ClassA object");}
}
public class ClassB:MonoBehaviour,IMyInterface
{
public void MethodINeed(){print("This is ClassB object");}
}
and now you have your manager somewhere else with the reference to the objects:
public class Manager:MonoBehaviour
{
public void MethodToFindComponent()
{
// Here you have the ref to the object
// you don't know if it has ClassA or ClassB
// Who cares because it has IMyInterface
IMyInterface script = objReference.GetComponent<IMyInterface>();
script.MethodINeed();
}
}
If the object is ClassA it will call the method from ClassA with whatever implementation you made there. If ClassB, then ClassB implementation.
You can also do that with abstract class, the main advantage over interface is that you can drag an abstract class in inspector if it inherits from MonoBehaviour. The downside of it, you can only inherit from one class in C# when you can implements many interfaces.
This might be almost 3 years old but this saved me so much, thank you @fafase, this solved something I've been going nuts over for a full day
Hey there @fafase ! I've been asking you questions on all your answers here, sorry for bothering you so much haha
So using an interface on a class you basically "tag" it, so you can retrieve that class with GetComponent by getting the interface, right? And using this method you really do get access to the whole script itself? Thank you so so much!
You can use GetComponent to retrieve an interface but you won't get access to the full script, only the part that is IInterface.
public class $$anonymous$$yClass: IInterface
{
public void SetSomething(){}
public void Interface$$anonymous$$ethod(){}
}
public interface IInterface
{
void Interface$$anonymous$$ethod();
}
IInterface inter = gameObject.GetComponent<IInterface>();
That inter reference only sees Interface$$anonymous$$ethod. If you need to access the whole object, either use the component type or perform a cast
$$anonymous$$yClass myObj = ($$anonymous$$yClass)gameObject.GetComponent<IInterface>();
But the latter may make little sense.
Thanks for your helpful Answer! But im not quite sure where to put what Class? I have 2 Objects with 1 different Script each. And a Script where i want to call the scripts from.
It says this when i put Class A on 1 script Class B on the other and the rest on my Script where i want to call the others from:
NullReferenceException: Object reference not set to an instance of an object RangedCombat.Update () (at Assets/Code/RangedCombat.cs:24)
Answer by AaronWinterhoff · Feb 03, 2014 at 11:13 AM
What do you want to do with those scripts? That influences how we can answer this question. You can get those scripts, but if you want to do anything with them, then you'll need to do some filtering and casting at some point. This can be done generically, depending on what you're referencing those scripts for. Remember that Unity's transforms, mesh filters, colliders, etc, are all scripts too.
You can use .GetComponent < Component > ()
to get a generic script from there, and cast as you want.
What I've put here will search your object for a script (single as you asked) attached to it, and filter out any that you don't want (transform, etc). It will return the last script attached to it that isn't filtered out. It would be easier to give you a more specific answer if you outline what you need to use that script reference for.
As others have shown, there are a few ways to do this, but it really depends on what you're doing it for. This kind of approach is best done with caching in Start (), and can be useful with Reflection when you are doing Editors on variables for mobile testing, and don't want your designers to have to come to you every time they want to edit another variable on an iOS device.
using UnityEngine;
using System.Collections;
public class ScriptGetter : MonoBehaviour {
public GameObject [] objects; // Objects you want to get scripts from
public void Start () {
scripts = new Component [ objects.Length ];
// Find the Scripts in the GameObjects
for ( int i = 0 ; i < scripts.Length ; i++ ) {
Component [] scriptsOnObject = objects [ i ].GetComponents < Component > ();
// Search each script on the component, and filter out default Unity ones
for ( int j = 0 ; j < scriptsOnObject.Length ; j++ ) {
if ( !UnwantedTypes ( scriptsOnObject [ j ] ) ) {
scripts [ i ] = scriptsOnObject [ j ];
}
}
}
// Display our scripts from our objects
for ( int i = 0 ; i < scripts.Length ; i++ ) {
Debug.Log ( scripts [ i ] );
}
}
private Component [] scripts; // Our cached Scripts will live here
private System.Type [] unwantedTypes = { typeof ( Transform ) , typeof ( Collider ) ,
typeof ( MeshRenderer ) , typeof ( MeshFilter ) };
// Only allow types we want through
private bool UnwantedTypes ( Component _component ) {
for ( int i = 0 ; i < unwantedTypes.Length ; i++ ) {
if ( _component.GetType ().Equals ( unwantedTypes [ i ] ) ) {
return true;
}
}
return false;
}
}
Your answer
Follow this Question
Related Questions
What's the difference between SendMessage and GetComponent? 3 Answers
get variable from a different game object 1 Answer
Turn off CharacterControl Component Through Script? 1 Answer
Can you shorten "GameObject.GetComponent(Script)" to a variable? 3 Answers
What's the difference between the two GetComponents? 1 Answer