I want to add a script to avoid them spawn overlapsed, so I added a script in Enemy prefab:
public Spawner spawner;
and later
if (other.gameObject.tag == "Enemy")
{
Destroy(gameObject);
spawner.count -= 1;
}
It should reduce the “count” variable to automatically spawn another one in a new position.
My problem is, as Enemy and the Spawner are both prefab entities, it access some random value in the original prefab, and not the one in the created gameobject.
I tried also making a gameobject to store the value, but unity don’t allow to link prefabs to gameobjects.
Please don’t use the 2D-Physics tag unless your question is actually about 2D-Physics. This puts it in the 2D product area and I also get a notification expecting to answer a 2D-physics question.
This is a basic scripting/prefab question so you should use those tags.
I’l update the tags for you but please use them correctly.
Are you asking for how to avoid spawning where something already is? Go check some Youtube tutorials, there’s many ways. I also have a bunch of examples in my MakeGeo project, such as these one, one for 2D and one for 3D:
Fully set up and operation in the scene.
Or are you asking how to Destroy something? If that’s it, looks like the script above is Destroy()ing the GameObject it is hosted upon if conditions are met. If that doesn’t work, then…
Sounds like you wrote a bug… and that means… time to start debugging!
By debugging you can find out exactly what your program is doing so you can fix it.
Use the above techniques to get the information you need in order to reason about what the problem is.
You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.
Once you understand what the problem is, you may begin to reason about a solution to the problem.
you need to move the spawner.count -= 1; to before Destroy(gameObject); or else it delete’s the game object before its able to change the count variable.
Destroy doesn’t actually destroy an object until the end of frame. The rest of the code will still execute.
The spawner needs to pass itself to the object it spawns, so said spawned object will be referencing its particular spawner instance, and not your prefab asset on disk.
Finally I just used Physics.CheckSphere as it was the fastest way to do this.
If somebody wants to do it the other way for some reason, there are lots of ways.
As spiney199 said, one is to reference the particular instantiated object to its own spawner. Didn’t try, but probably making it child is a good idea.
You can save the instantiated objects in arrays, and as enemy is self destroying, that GameObject in the array will be null next frame and you can re-spawn them. (I know this is a mediocre solution, but in my game objects are only spawned once so could be fine)
Other sollution I found is creating an empty Gameobject and store the values you want to make global by the function GameObject.Find (as you can’t reference gameobjects in prefabs)
Any values you want to store, like saving a value from a GameObject that’s about to be destroyed, can be stored in a static script. These can’t be attached to any GameObject, so they’ll never be destroyed when moving to another scene. The script and all values and methods in it will be globally accessible from any other script in any scene without needing to “find” it.
Note: I’m not totally clear on the difference if you make the class non-static (but still use static variables and methods). Both work.
/////////// example static class to hold global variables and methods
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class globalValues
{
public static int myInt = 5;
public static void myGlobalFunction()
{
Debug.Log("hey");
}
}
/////////////
get/set values, call methods in it from any other script, anywhere, anytime
print(globalValues.myInt); // original value
globalValues.myInt = 99;
print(globalValues.myInt); // changed value
globalValues.myGlobalFunction();