5

Using the following code I am able to get the Script from "SMG" and apply it to the weaponObject:

weaponObject = GameObject.FindGameObjectWithTag(SMG).GetComponent<SMGScript>();

Is it possible to action something like the following and if so, how?

string variable = "SMG";

weaponObject = GameObject.FindGameObjectWithTag(variable).GetComponent<variable>();

I want to have a number of scripts that I can apply to weaponObject dependant on a variable.

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
user2740515
  • 89
  • 1
  • 2
  • 7

3 Answers3

4

Since I see the weapon has a different name than the script you will need 2 variables.

string variable = "SMG";
string scriptName = "SMGScript";
GameObject.FindGameObjectWithTag(variable).GetComponent(scriptName);

This is not efficient.


Solution

What you want to do is have a parent class and all your weapons will inherit from it.

public interface Weapon
{
}

Then you create all your weapons like this example:

public class M4 : MonoBehaviour, Weapon
{
}

public class MP5: MonoBehaviour, Weapon
{
}

When ever you want to grab the script component you can simply use this:

string tag = "Weapon";

Weapon w = GameObject.FindGameObjectWithTag(tag).GetComponent(typeof(Weapon)) as Weapon;
apxcode
  • 7,696
  • 7
  • 30
  • 41
  • Why not use the generic form of `GetComponent`? Asker has already indicated they understand it. – 31eee384 Jul 21 '15 at 14:53
  • The generic form won't return a component by it's base class. `GetComponent()` won't find the target, but `GetComponent(typeof(Weapon))` will. – Dan Puzey Jul 21 '15 at 23:06
1

Yes it is possible to use variable on GetComponent, like this:

weaponObject = GameObject.FindGameObjectWithTag(variable).GetComponent(variable);

Even though that it is not recommended due to performance reasons, as stated here.

However the thing I'm not sure is how you define this weaponObject, as the script you get from GetComponent may vary and your variable type must be the same as the script you get.

My suggestion is to put all weapons inside a script and give it a type variable (ex: type 1 is machine gun, type 2 is hand gun, etc) to represent each weapon. That way you can get the script like above and find out what type of weapon you're getting by accessing the type:

int weaponType = weaponObject.type;
Jay Kazama
  • 3,167
  • 2
  • 19
  • 25
  • The example you show won't work unless the GameObject has the same name as the script (and in the example from the question it doesn't). In addition using an Enum here is unlikely to be the best solution. – Selali Adobor Aug 18 '14 at 13:28
  • Yes I know that, that's why I said my 3rd paragraph and then offered an alternative for that. Your answer may be the best solution, but mine is not wrong either. If it's not wrong and usable, why not? It's just a matter of preference and efficiency. So if you were the one who downvoted this, please take it back. Thank you. – Jay Kazama Aug 18 '14 at 13:47
-2

You question is specifically asking how to use GetComponent without generics. And in your case the result would be:

string variable = "SMG";

string scriptName = "SMGScript"

weaponObject = GameObject.FindGameObjectWithTag(variable).GetComponent(scriptName);

But generally speaking, this approach to managing objects is unsustainable. As your project gets bigger and bigger, managing objects by name becomes much less feasible.

And I would personally strongly recommend you do not use an Enum to represent your weapons as is suggested in another, as this approach suffers from the same problems, if not on a much larger scale.

It sounds like what you want to do is store a reference to SMGScript.

The easiest way to do that is to create a field in your script, and set the value in the editor.

If the problem is allowing for multiple types of weapons, use a pattern like inheritance:

Define a base class for your weapons:

WeaponScript : MonoBehaviour
{
   public abstract void Fire();
}

Then have SMGScript extend it:

class SMGScript : WeaponScript

Then create a public field to hold a weapon so you can set it in the editor:

public WeaponScript PlayerWeapon; //The editor will let you drop *any* weapon here.

To fire the weapon:

PlayerWeapon.Fire(); //This will let any type of weapon you set in the editor fire

To retrieve the any weapon (Although you probably won't need this, see below):

targetGameObject.GetComponent<WeaponScript>();

If you don't know the object you'll want from the editor (for example, you make the SMG object while the game is running), there is almost always a better way to get a reference.

For example, if this is a pickup, you could use the collision/trigger information to get the correct GameObject.

Or if this is an object that only has a single instance, but you want to define that instance at run-time use the Singleton pattern.

Selali Adobor
  • 2,060
  • 18
  • 30