- Home /
Spawning at collision free Location
Hello there! Let's make this straight. The Object i'm spawning it does spawned overlapping with other object. Those objects have collider already. But it doesn't work. Hmm kindly seek for your help any kind soul ^^. Thank you!
Here's the code.
using UnityEngine;
using System.Collections;
public class SpawnSys : MonoBehaviour
{
public float spawnTime = 5f; // The amount of time between each spawn.
public float spawnDelay = 3f; // The amount of time before spawning starts.
// public float xRange = 1.0f;
// public float yRange = 1.0f;
public GameObject[] enemy;
private bool canSpawn;
//public GameObject prefab;// Array of enemy prefabs.
void Start ()
{
// Start calling the Spawn function repeatedly after a delay .
InvokeRepeating("Spawn", spawnDelay, spawnTime);
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Seabed")
{
canSpawn = false;
}
else
{
canSpawn = true;
}
}
void Spawn ()
{
if (canSpawn == true)
{
float randomX = Random.Range(-8f,10f);
float randomY = Random.Range (1.5f,2.8f);
int enemyIndex = Random.Range(0,enemy.Length);
//Instantiate(enemy[enemyIndex],transform.position, transform.rotation);
Instantiate(enemy[enemyIndex], new Vector3(randomX, randomY, 0), Quaternion.identity);
}
}
}
Answer by CanCo · Oct 21, 2015 at 10:21 AM
Some things I do:
- Create a list of positions where the enemies can be spawned (or better, a cube area range),
- Using raycast (spherecast, capsulecast
- Place them in the sky (this seriously isn't recommended, but funny to watch).
I wrote a code, basically what happens is it runs the function SpawnRandom the set amount of times (toSpawn), runs a raycast downwards checking if there is anything below a randomly chosen spot, if there's something below it will check if the tag of the collider (transform in the code) is the specified spawning tag (string tag). I used the default "Respawn" tag. Here's the simple code:
using UnityEngine;
using System.Collections;
public class spawns : MonoBehaviour {
public Transform enemy;
public int toSpawn = 10;
public Vector3 size; //DOES NOT USE THE Y-SIZE!!
public string tag;
private RaycastHit hit;
void Start () {
for(int n = 0; n < toSpawn; n++) {
SpawnRandom(n);
}
}
void SpawnRandom (int n) {
if (Physics.Raycast(transform.position + new Vector3(Random.Range(-size.x/2, size.x/2), 0, Random.Range(-size.z/2, size.z/2)), Vector3.down, out hit))
{
if (hit.transform.tag == tag)
{
Instantiate(enemy, hit.point + hit.normal * 0.5f, Quaternion.identity);
}
}
}
void OnDrawGizmosSelected () {
Gizmos.color = new Color(0, 1, 0, 0.4f);
Gizmos.DrawCube(transform.position, size);
Gizmos.color = new Color(0, 1, 0, 1);
Gizmos.DrawWireCube(transform.position, size);
}
}
Hello Canco! I'm kinda new to Unity, so may I request for a example of the codes from you? So I can use it as reference ^_^.
Okay, I've created a code for you. It will probably have to be modified to your situation (I forgot to mention that it checks the raycast from the y-position).
Hey Canco, You know what, so sorry I forgot to tell you that i'm creating 2D. It seems like your code only work for 3D. Or is it work for both?
Haha my bad!
Answer by npatch · Oct 21, 2015 at 11:21 AM
You can create a layer (there's the Ignore Raycast layer as well but I haven't used that so I can't vouch for that) and then go to Edit->Project Settings-> Physics and uncheck collisions from all layers with that new one in the Layer Collision Matrix. Basically you are telling Unity that anything in that layer should not collider with any other layer.
Then instantiate your enemies anywhere...
The only thing you have to do is when you want their colliders to work, just change their layer to either Default or some other layer you've made for enemies which can collide with other layers.
Hey npatch~ Your solutions I've tried but it seems not that effective. :) Or maybe it just that I couldn't make it. But I'll try to figure out in a moment!
Actually I misread, sorry for that. CanCo was on point.
Another solution would be to use RigidBody on the enemies to have them use the Physics module and once you spawn something inside a collider the physics alone will propel it outside since they collide.You can add a slight height to the spawning point to let it collide straight away without getting spawned inside like this:
GameObject spawned = Instantiate<GameObject>(prefab);
spawned.transform.SetParent(spawnPoint);
spawned.transform.localPosition = new Vector3(0,1,0);
Though this solution depends on whether you want to use Physics at all.
In any way, the Layer Collision $$anonymous$$atrix is going to help you tremendously once you get a feel for it so take a look at it anyway since collisions are part of the engine and it's going to be way faster than trying to do everything from code and using raycasts.
For now I'm glad you got an answer that helped you and worked for you.
Guess what, the rigidbody you say it apply well for my 2D game just that the object takes time to move out from the collider. Although is not hard coded but still there! Yes I will look into the Layer Collision $$anonymous$$atrix in future! Thank you very much and appreciate your help!
Your answer