If you want to destroy the game object, please call 'Destroy' on the game object instead.
With the following code, I'm trying to spawn a pedestrian, have it move a certain distance, and then have it "despawn" with Destroy.
public class SpawnPerson : MonoBehaviour {
int x = 2;
public Transform Ped;
void Update () {
if (Input.GetButtonDown ("down")) {
if (Input.GetButtonDown ("down") && x % 2 == 0) {
var clonePed = Instantiate (Ped, new Vector3 (0, 0, -2), Quaternion.identity);
x++;
if (Vector3.Distance(transform.position, Ped.transform.position) > -90)
Destroy(clonePed);
} else {
x++;
}
}
}
}
The problem I'm having is Destroying it.
As far as I can tell, I'm actually trying to Destroy the whole Prefab or something? I keep getting a bunch of different errors saying different things as I try to fix it myself. The last day all I've done is search around, and I've found lots of different problems similar to mine, but none of the solutions have seemed to work.
To move the pedestrian, I have to make it a Transform, no? If I try to make it a GameObject, it doesn't seem to move correctly anymore.
Something I've seen a lot is to do something like:
public var Ped : Transform;
But then I get compiling errors that doesn't even let me try it.
Any help would be great.
Answer by GasPla · Jun 22, 2017 at 11:25 PM
I take it you're pretty new to Unity and coding in general, so I'll try to break this down as much as I can. First I think you need some clarification on the relationship between a GameObject and a Transform.
The pedestrian prefab you're using is a GameObject, and all GameObjects have a Transform component attached to them (just like any other component, like a RigidBody, Collider, etc.).
When you Instantiate the Pedestrian in your code, you're giving it three arguments: the prefab to instantiate ["Ped"], what position you want it to be instantiated at (meaning, the position variables of its Transform) [Vector3 (0, 0, -2)], and what rotation you want it to be instantiated with [Quaternion.Identity]
So in order to move your pedestrian GameObject, you'll need to change the position variables of its Transform component. Nothing in your code above will move the pedestrian, since you never change its position, nor will it ever be destroyed (since it's distance from this SpawnPerson object will never reach > 90). In fact, that part of your code will never evaluate correctly, since distance is always positive (you can't be negative X metres away from something, right?), so you'll have to change it to 90, rather than -90. On top of that, each time you Instantiate a new Pedestrian, clonePed will change to only have a reference to the newest one you've created, so when you check the distance later, you're actually only checking the distance between this object and the latest pedestrian you've created (all the other ones will continue to exist forever!).
So, first thing first:
Instantiating Properly
var clonePed = Instantiate (Ped, new Vector3 (0, 0, -2), Quaternion.identity);
So first a bit of a gotcha -- using var isn't that helpful when you're first starting. Normally, when you make a variable, you give it an explicit type, like float, or string. With var, you're essentially saying "make this variable whatever type it needs to be when something is assigned to it". If you created the following variable:
var number = 10;
Do you know now whether number would be an Int or a Float? You might guess, but why take the risk and guess wrong? So, let's instead ensure that "clonePed" is explicitly a GameObject. Change the line to:
GameObject clonePed = Instantiate (Ped, new Vector3 (0, 0, -2), Quaternion.identity) as GameObject;
The "as GameObject" declaration at the end is important, because otherwise it'll simply get Instantiated as an Object, rather than a GameObject, as that's what the Instantiate function does (don't worry about this distinction too much right now, just know that it's important!).
Next, at the very top, we need to change:
public Transform Ped;
to
public GameObject Ped;
Instantiate wants you to pass it a GameObject in order for it to create something, so you can't pass it a Transform. Once you've changed this line, if you go into the editor and select the object you've got your SpawnPerson script attached to, you'll see a "Ped" field has been added to it. You're going to want to drag your pedestrian prefab from your assets list into this slot in order to assign the prefab to that variable.
Moving the Pedestrian
In order to do this, I'd suggest adding a new script to your pedestrian prefab, call it PedestrianMovement:
public class Pedestrian : MonoBehaviour
{
Vector3 startingPosition;
float speed = 5;
float distanceToTravel = 5;
void Start ()
{
// Get the starting position of the pedestrian so we can compare the distance
startingPosition = transform.position;
}
void Update ()
{
// If the distance the pedestrian has traveled from its starting position is less than 5, move it
if (Vector3.Distance (startingPosition, transform.position) < distanceToTravel)
{
transform.position = new Vector3 (transform.position.x + speed * Time.DeltaTime, transform.position.y, transform.position.z);
}
// Otherwise, if the distance the pedestrian has traveled is greater than 5, destroy it
else
{
Destroy (gameObject);
}
}
}
That script will run when the Pedestrian prefab is Instantiated, and it'll begin moving immediately (I just have it set to move to the right). Once it's moved far enough it'll get destroyed. When calling Destroy, using the variable gameObject (lowercase G) as I have, essentially means "the GameObject that this script is attached to". I've changed the distance to travel to 5 so you can see the effects more immediately without having to wait as long (feel free to change the value of the distanceToTravel variable).
Finally, I'm not sure what your "x" variable is tracking, but as it is now it's going to increase both when a pedestrian is spawned, and every frame as well (the "else" statement). If you can clarify what you're trying to do with this I can try to help with that as well.
I highly recommend starting with some very basic Unity tutorials (either written or on YouTube), since I think it'll make the process of learning a lot less frustrating (since you spent all day hunting down what errors mean without any context!).
Hope that helps!
WOW! I was never expecting an answer so in depth. Thank you so much for taking your time out to help! Very much appreciated.
To start, yes, as you can tell, I'm very new to both C# and Unity. I know CSS and HT$$anonymous$$L fairly well, and when I learned that, I learned the basics of it first and then hopped right in and whenever I ran into a problem/something I didn't know, I would look up whatever it was and learn about that specific thing until I fully understood it. And then I would keep repeating the process. That's basically what I was trying to do with this. I spent a couple days trying to learn the basics from reading/watching/etc. and then went straight into trying to make a simple game.
I actually already have a movement script which actually seems to work pretty well. It does everything I wanted it to do. Right now, I have the down arrow as the control that makes the pedestrian walk down a sidewalk temporarily, just for testing. Eventually I'm planning on giving them a set path they walk by themselves. The script you're seeing right now was only to spawn the pedestrian, and then destroy them after they've moved a certain distance. That was what the if statements and the "x" variable was for. I have the down arrow spawn the "pedestrian" and also make them walk one space down the sidewalk. When I first started with it, they were spawning inside of each other and start flying everywhere. This part was just to make them only spawn every other time I pressed the down arrow just to give them space in between each other. So yeah, that part was temporary. Just for testing purposes.
I'm not going to comment on each part of your reply, but do know that I read everything and learned a ton from it. Again, thank you very much.