TargetExpection Object Does Not Match Target Type [Solved]

i got stuck on a small problem with MethodInfo. heres the code.

[SerializeField]
    protected string className;

    [SerializeField]
    protected string functionName;
protected void ShouldSpawn()
    {
        if (shouldSpawn == true) // Checking if we should start spawning
        {
            if (spawnWithCustomComponent == true)
            {
                if (customComponent != null)
                {
                    System.Type newType = customComponent.GetComponent(className).GetType();
                    MethodInfo newMethod = newType.GetMethod(functionName);
                    newMethod.Invoke(newMethod, null);
                    Debug.Log(newMethod.Name);
                    Debug.Log(newMethod.Name);

                }
            }

FunctionName is the name of the method.
ClassName is the name of the class.

the error i get is the name of this thread

So what’s the error? You forgot to add any kind of error message to work with.

Besides that, there’s no reason to make it that complicated. Use interfaces to invoke methods on components that do not have anythign else in common. This is more type safe, faster and less error prone. Reflection is the worst thing you could use in this situation.

Also, the ‘newMethod’ variable is actually of type System.Type. It’s an irritating name. So your comments behind the calls to Debug.Log don’t match either. The first one should show a method name, the second should show the type name.

About the Invoke part of your snippet, noone knows what the function that ‘functionName’ is supposed to identify looks like, so it’s difficult to guess. Perhaps parameters don’t match, who know… information is missing here.

what kind of information? cause it should just invoke the method i have called. from another class. but it gives me that
TargetExeception Object Does Not Match Target Type.
how do i go about using interfaces to invoke ? cause it’s only suppose to invoke that method and not all components that uses that interfaces unless i am missing something

Oh i forgot about the thread’s title. My bad, sorry for that.

Well, you’re passing the object’s type (an instance of System.Type) instead of the object itself. You need to pass the object you get from calling GetComponent on customComponent (or any instance of the same / a derived type) to it, not the ‘newMethod’ variable.

But again, this is an awful solution. You shouldn’t even need to use reflection here. Looking at the code, It’s absolutely the wrong tool in my opinion.

what would you do instead? :smile: and also i tried to do it with customComonent but it still does the same. even through the object has a instance…

basicly what i am trying to do is to make a semi dynamic call to a custom component aka if the user wishes to have use a different lets say spawner then the one i have atm. then they could write down the class name and function name. and use that. sort of deal

Sorry, little tired here and I’m constantly confused by your irritating naming of variables, haha.
Edited my post while you responded. Of course don’t pass customComponent, but the component you get from calling GetComponent on it (or instance of that type). Because that’s where you get the method from.

You should use interfaces instead and should not rely on “className” and “functionName” variables. This is prone to error and will mess your application up as soon as you change a small thing… If you use that more often, you’re application will be doomed unless you implement a more robust extension that does show you all available methods for a given type… similar to UnityEvents.
But it’ll still be slow and not the best approach.

so i managed to make it spawn what i want which is good but again my className and functionName are simply just string values. and the naming made the most sense to me. can u give me a small example of how i would do it with interface? like what kind of function should be in that interface?

[SerializeField]
    protected string className;

    [SerializeField]
    protected string functionName;
protected void ShouldSpawn()
    {
        if (shouldSpawn == true) // Checking if we should start spawning
        {
            if (spawnWithCustomComponent == true)
            {
                if (customComponent != null)
                {
                    System.Type newType = customComponent.GetComponent(className).GetType();
                    MethodInfo newMethod = newType.GetMethod(functionName);
                    newMethod.Invoke(customComponent.GetComponent(className), null);

                }
            }

In what context would this code be being used, just curious?
Like you are building a tool for devs or players? Is this custom component something they can add or choose from options you’ve (only) made?
Just curious as I was reading:)

well i am trying to build a pretty dynamic spawnManager that handles anytype of spawn like inside a box,sphear etc. and i am making this for a small company, and i am a intern, so i am trying to do my best and create something that would make it much much eaiser for them to spawn different things. or repeated spawn.

and the CustomComponent is actually just a Unity gameObject that you put in and it will get whatever function that you need to use in order to A start the component or close it. atleast that is my idea. i am trying to find a way to make it able to use scripts instead of actual gameobjects. and somehow attach that script to a desired object.

Ahh okay. That was useful information, I think. (for anyone else coming by to read/reply).
I am too tired right now. :slight_smile: Good luck, look forward to seeing how it goes for ya.

Thanks :smile:

The naming is confusing for a Unity-User, since your ‘customComponent’ is apparently a GameObject, but the name suggests it’s some type of UnityEngine.Component. That’s very context-sensitive and leads - at most for programmers and experience Unity-Users - to confusion. Of course you can always look up the variable’s declaration, but this shouldn’t be the only option in the first place to make sense of the code. :slight_smile:

Also the ‘newMethod’ variable is actually bad naming, since it suggests it’s more like a reference to a ‘MethodInfo’ rather than a ‘System.Type’. This is of course something you have to get on with in the first place, but for anyone else who might look at your code, this will be annoying for sure.

Since you just said you’re working for a company, this should be even more relevant and important to keep an eye on.

In regards to your actual question, you might want to design an abstract base component that offers a certain method you’d like to invoke for spawning something. This is more type safe and does not need any awareness about case-sensitive, code-based knowledge of type-names and related method-names that belong to a type.

E.g. someone that uses your scripts will be able to simply put in an object that actually fits into the inspector slot, rather than typing in

  • a component name (was it XyzCompeont or XYZCompeont or XYZcomponent, or …)
  • a method that belongs to the component (ABCSomething, AbcSomething, ABCsomething…)
  • Does XYZComponent even have an AbcSomething method? or is it a DefSomething method in this case?

As soon as you decide to refactor one of these types or methods, the naming and the whole setup will be messed up and throw hard-to-debug errors, as the types/methods will no longer be found.

As others have said - use an interface. Implement the interface in different ways to spawn stuff differently

public interface ISpawner
{
    void Spawn();
}

public class CubeSpawner : MonoBehaviour, ISpawner
{
    public void Spawn() { }
}

public class SphereSpawner : MonoBehaviour, ISpawner
{
    public void Spawn() { }
}


someObject.GetComponent<ISpawner>().Spawn();
1 Like

the thing is the SpawnManager is the one behind having to spawn everything. thats my idea and if the user wishes to use a different script i would offer them that ability to plug in the script and then i would someone get the methods in that script and maybe even create a dropdown of possible methods that can be executed. perhaps.

also i understand about case-sensitive and such. however i ltiterly just thought up doing this so obviously i will go through quite a few stages before i am happy. however i only got 16 day’s left my internship and well :smile: not the fastest programmer on earth but i am extreamly happy for the suggestions everyone did :smile:. also everything that has been said by everyone is something i cant learn much from but i diff take it as a warning for whatever i do.

Thank you

Interface is still the way to go. If someone wants to make a custom spawner then you say to them implement this interface and attach it the spawn manager GameObject. It’s just a method call so it’s faster than reflecting the method info. It’s safer because the compiler enforces the contract not some text field in an Inspector somewhere and it prevents someone from just inputting some rando method that doesn’t even do spawning.

1 Like