x


Get unity to recognize prefab in C#

Hi. This seems like it should be pretty basic. I have a prefab called Grapple_Arrow. It contains meshes and scripts. I want to instantiate one of these when I hit a key, lets say. According to documentation I should do something like:

public class example : MonoBehaviour {
 public Missile projectile;
 void Update() {
  if (Input.GetButtonDown("Fire1")) {
   Missile clone;
   clone = Instantiate(projectile, transform.position, transform.rotation);
   clone.timeoutDestructor = 5;
  }
 }
}

Except that if I do exactly that with my prefab, I get an error:

error CS0246: The type or namespace name `Grapple_Arrow' could not be found. Are you missing a using directive or an assembly reference?

What I can do is this (feels like a workaround):

public class LerpzGrapple : MonoBehaviour {
public GameObject theGrapple;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
    // later change this to getButtonDown
    if (Input.GetKeyDown(KeyCode.Return)) {
        GameObject grapple = Instantiate(theGrapple, transform.position, transform.rotation) as GameObject;
        //grapple.OriginatingObject = gameObject;
        Grapple grappleScript = grapple.GetComponent("Grapple") as Grapple;
        grappleScript.originatingObject = gameObject;
    }
}

}

And lo, it actually instantiates an object (actually I just figured this part out while typing the question). But it seems kind of a roundabout way. Can't I just add a line "using MyPrefab" or #include MyPrefab or something?

As it is, I can only instantiate a generic GameObject (which I even have to cast from Object to GameObject?!) when it seems I could have access to the exact prefab and all its many scripts and properties. (That's how it would be if I was working in pure code anyway.) From my generic GameObject, to access a property I have to do GetComponent()... which, while I don't know how it actually works, it looks like it's doing a string comparison. I hope that's in the precompile stage only. :)

So the crux of my long-winded question here is:

  1. am I doing this right?
  2. Is any part of my code redundant or suboptimal?
  3. Is there an easier / better way (in C#) ?
more ▼

asked Mar 14, 2011 at 08:12 AM

robertbeverly gravatar image

robertbeverly
1 3 2 5

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

2 answers: sort voted first

Your "workaround" is generally how it's done, except you can combine all those steps into one. Also you should generally not use strings in GetComponent (see the docs, although in addition to performance, you get compile-time error checking instead of runtime), and using generics is simpler.

(Instantiate(theGrapple, transform.position, transform.rotation) as GameObject).GetComponent<Grapple>().originatingObject = gameObject;

You could shorten it by declaring the prefab like this:

public Grapple theGrapple;

Then you can cast to Grapple when instantiating:

(Instantiate(theGrapple, transform.position, transform.rotation) as Grapple).originatingObject = gameObject;

What type you use depends primarily on what's most convenient to refer to with the instantiated object.

more ▼

answered Mar 14, 2011 at 08:24 AM

Eric5h5 gravatar image

Eric5h5
107k 51 180 648

public Grapple theGrapple; <---- Yes this is what I want to do! But it throws an error.

Ok, my exact prefab name is Grapple_Arrow in the Project view. I only have the standard includes in my C# file. I declare:

public Grapple_Arrow theGrapple;

As soon as I hit save, I get this error:

The type or namespace name `Grapple_Arrow' could not be found. Are you missing a using directive or an assembly reference?

So what could be wrong with my prefab that would cause this error? What you wrote is what I wanted to do in the first place. I just tried it again and got the error again.

Mar 16, 2011 at 05:48 AM robertbeverly

Just one more note, Grapple is the C# script attached to the Grapple_Arrow prefab.

Mar 16, 2011 at 05:53 AM robertbeverly

@robertbeverly: you can't use the prefab name as a type; it's just an identifier name and isn't generally used in code for anything (aside from Resources.Load). The script/class name (typically they are the same) can be used as a type.

Mar 16, 2011 at 06:08 AM Eric5h5
(comments are locked)
10|3000 characters needed characters left

There's nothing really inherently wrong with how you are instantiating/using grapple. I presume that you are getting that error because Grapple_Arrow is a prefab. Prefabs themselves aren't types, they're components or GameObjects, so you can't create a variable who's type is a prefab name.

more ▼

answered Mar 14, 2011 at 08:26 AM

Lab013 gravatar image

Lab013
415 3 3 14

Please don't use this site for advertising. You can put that sort of thing in your bio.

Mar 14, 2011 at 08:39 AM Eric5h5

Please don't advertise on this site* (I assure you I was not just using this site for advertising). Excuse my ignorance. I presumed from the dividers appearance that it was commonly used as a signature separator under which case the use of a link to my thread would be appropriate. I didn't realize that it is protocol to put a link like that in the semantically incorrect 'bio' section of my profile. Thank you for the correction.

Mar 14, 2011 at 09:06 AM Lab013

Lab013 maybe that's it then? I thought the whole point of prefabs was that you could instantiate them at runtime. I can drag it into the public iVar if it's created as a gameObject. But then I have to treat it like a gameObject until I retrieve its custom components specifically. Kind of weird when you're used to pure code, where if you write a class or a protocol for an object you can always access its known methods or properties.

Mar 16, 2011 at 05:59 AM robertbeverly

@Lab013: sorry, but this isn't a forum, and signatures aren't used.

Mar 16, 2011 at 06:04 AM Eric5h5

@Eric5h5 Yes, I am new to this format, and signatures are used in many areas, as I said, thank you for the correction.

@robertbeverly You can instantiate them at runtime, however, you don't instantiate them by name. You drag the prefab instance from the project view and link it into the GameObject variable in your script.

Mar 16, 2011 at 11:55 PM Lab013
(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:

x3356
x2719
x1971
x687
x52

asked: Mar 14, 2011 at 08:12 AM

Seen: 4965 times

Last Updated: Mar 14, 2011 at 08:12 AM