Can't access member of a thing in a list, even though I checked for the right type

Hi everyone,

I’m trying to do something with a member of a class that I found in a list.

In my example, I want my characters (agent) to freak out (Panic()) when they are near a scary thing (panicSource). PanicSource is in fact derived from PanicObject: (I stripped out everything that I think isn’t part of my Problem).

public class PanicSource : PanicObject {
//[…]
	public float scariness;
//[…]
}

panicObjects is an abstract list of all the PanicObjects. They register themselves.

public class PanicObject : MonoBehaviour {
//[…]
	//static list of all the PanicObjects
	public static List<PanicObject> panicObjects = new List<PanicObject>();
	//constructor
	public PanicObject(){
		//add myself to the list
		panicObjects.Add(this);
	}
//[…]
    }

and then, In my character class, I go through all the panicObjects and if they’re a a PanicSource, I want to do something.

//[…]
    foreach (var thing in PanicObject.panicObjects) {
    			//… some checks for distance etc.
    			if (thing is PanicSource) {
    				agent.Panic (thing.scariness); //this is where my error is
    			}
    		}
//[…]

However, “scariness” apparently isn’t a member of the thing, (even though the previous check makes sure that the thing is a PanicSource which has that public member.

(error CS1061: Type PanicObject' does not contain a definition for scariness’ and no extension method
scariness' of type PanicObject’
could be found. Are you missing an
assembly reference?)

Thanks in advance!

Although the thing is a PanicSource. But since it is referenced inside a List , when you take it from the list, it has an interface of a PanicObject. You need to cast it back to PanicSource. Try it:

 foreach (var thing in PanicObject.panicObjects) {
                 //… some checks for distance etc.
                 PanicSource panicSource=thing as PanicSource;
                 if (panicSource) {
                     agent.Panic (panicSource.scariness); //this is where my error is
                 }
             }

Lets start with this.

if(thing is PanicSource) - ‘is’ tells if thing implements PanicSource in its class hierarchy
then you try to acces scariness in type PanicObject which is not implemented, what you have to do is to cast PanicObject to PanicSource and then acces scariness .

PanicSource panicSource = thing as PanicSource;
if(panicSource != null)
  agent.Panic(panicSource.scariness);

there are two problems here:
First of all, don’t use a MonoBehaviours constructor, use Awake instead. All I know is you can run into problems because the constructor is called twice, adding everything twice to your list and therefore executing everything twice.

second, you check for the type but you keep it as the base class which does not know about scaryness. Either move it to ScaryObject with protected as it’s access modifier (recommended), or cast the ScaryObject up to PanicSource.