x


Issue casting using Type variable? C#

I am receiving error CS0246: "The type or namespace name 't' could not be found. Are you missing a using directive or an assembly reference?" on the following code and I can't figure out why.

using UnityEngine;
using System;
using System.Collections;

public class EventController : MonoBehaviour {
    public string[] scripts;

    void OnTriggerEnter(Collider c) {
       if(c.tag == "Player") {
         for (int i=0; i < scripts.Length; i++) {
          UnityEngine.Object s = gameObject.GetComponent(scripts[i]);
          Type t = Type.GetType(scripts[i]);
          ((t)s).Run(); // This is the error line.
         }
       }
    }
}
more ▼

asked Jan 31 '12 at 06:11 PM

Shawn Miller gravatar image

Shawn Miller
78 8 9 12

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

This doesn't work the way you do it here. System.Type is part of the runtime type information system. It's a special class that describe a certain type. .NET / Mono is a compiled language so it's impossible to compile your code above since the t is not a type, it's a class instance which holds the descriptor of a certain type.

If all those different scripts have a function Run() you should implement an interface in al those types.

Another way would be to use reflection, but it's kinda slow, messy programming style and hard to debug.

edit
Here's an example how to use an interface:

public interface IRunable
{
    void Run();
}

public class SomeScript : MonoBehaviour, IRunable
{
    void Update()
    {
        // ...
    }

    // This is the interface function. Because we derived our class from IRunable,
    // this class must implement the Run() method.
    public void Run()
    {
    }
}


// In your triggering class: 
void OnTriggerEnter(Collider c)
{
    if(c.tag == "Player")
    {
        IRunable[] scripts = (IRunable[])gameObject.GetComponents(typeof(IRunable));
        foreach (IRunable s in scripts)
        {
            s.Run();
        }
    }
}

Here's an example how to use Unity's SendMessage:

void OnTriggerEnter(Collider c)
{
    if(c.tag == "Player")
    {
        SendMessage("Run");
    }
}

And finally a Reflection approach:

void OnTriggerEnter(Collider c)
{
    if(c.tag == "Player")
    {
        for (int i=0; i < scripts.Length; i++)
        {
            MonoBehaviour s = gameObject.GetComponent(scripts[i]);
            Type t = s.GetType();
            System.Reflection.MethodInfo MI = t.GetMethod("Run");
            MI.Invoke(s);
        }
    }
}

Of course you should check all those things against "null". If the desired script isn't attached to the object, GetComponent will return null so accessing "s" afterwards yields to a null-ref-exception. If the script type doesn't have a method called "Run", GetMethod will also return null.

more ▼

answered Jan 31 '12 at 06:45 PM

Bunny83 gravatar image

Bunny83
45.4k 11 49 207

Huh, I could have sworn I've done it this way on another program, guess I'm losing my mind. In any case, thank you for the response and the demonstration as well.

Jan 31 '12 at 09:05 PM Shawn Miller
(comments are locked)
10|3000 characters needed characters left

Class name and file name are not same (EventController)

EventController.cs , public class EventController : MonoBehaviour must be same

more ▼

answered Jan 31 '12 at 07:52 PM

kaimelar gravatar image

kaimelar
41 2 2 3

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

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

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x4166
x41
x29

asked: Jan 31 '12 at 06:11 PM

Seen: 1538 times

Last Updated: Jan 31 '12 at 09:05 PM