- Home /
Checking for collision with 2D objects/sprites
I'm very new to Unity and C#, having a background in Java and trying my best to create a game. I currently have 2 sprites as test subjects that spawn in random locations on the screen at the start of the game. I am struggling to figure out how to check for collision in Unity C#. I've researched about Physics2D.Overlap and Physics.Check and OnCollisionEnter2D method and even OnTriggerEnter2D and I just cannot wrap my head around any of the logic. How would I code to check that if one sprite is spawned, the other sprite does not spawn over it by checking if it's collision box is hitting the other sprite's collision box and picks a new place to spawn at the start of the game? Any code examples would help tremendously.
Answer by ShadyProductions · Jun 01, 2020 at 11:10 AM
Colliders have a bounds property that you can use .Intersect(bounds) on of another collider.
ex:
if (collider1.bounds.Intersect(collider2.bounds))
{
// Code here
}
https://docs.unity3d.com/ScriptReference/Collider-bounds.html
Answer by wewewu · Jun 01, 2020 at 11:10 AM
this should be working:
private void OnCollisionEnter2D(Collision2D collision)
{
while (collision.gameObject.name == "Name of the object you don't want to collide with" && respawning)
{
Respawn(); //find a new place
respawning = false; //we don't want to respawn in game, and don't forget to set respawning to true if you start the respawning process
}
}
This doesn't work because the object must be physically instantiated first to trigger collision, which is what he is trying to prevent in the first place. And checking for a gameobject with a hardcoded name in a while loop doesn't seem like good practice.
Answer by tadadosi · Jun 01, 2020 at 01:36 PM
This might do the trick. In this approach I have:
(1) A Factory that spawns gameobjects on random positions and nothing else, it uses its position as center and a public Vector2 to limit the possible positions, and also stores static variables of those vectors to allow other scripts to access them. You can spawn as many objects as you want, just be aware that spawning a lot in small bounds will not yield a good result.
Factory code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectFactory : MonoBehaviour
{
public int objectAmount;
public Vector2 spawnBounds;
public static Vector2 _SpawnBounds;
public static Vector2 _SpawnCenter;
public GameObject prefabToSpawn;
private void Awake()
{
// store static variables
_SpawnCenter = transform.position;
_SpawnBounds = spawnBounds;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
for (int i = 0; i < objectAmount; i++)
{
// spawn the object and forget about it
Instantiate(prefabToSpawn, RandomPointOnBox(transform.position, spawnBounds), Quaternion.identity);
}
}
// this method should be on its own utility script
public static Vector2 RandomPointOnBox(Vector2 center, Vector2 size)
{
float spawnPosX = Random.Range(center.x - size.x / 2, center.x + size.x / 2);
float spawnPosY = Random.Range(center.y - size.y / 2, center.y + size.y / 2);
return new Vector2(spawnPosX, spawnPosY);
}
// method to get a visual referece in the scene view of the spawn bounds
// tip: On the game tab, click on the right top corner the button gizmos
// and you will have the visual reference in the game view too.
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawWireCube(transform.position, _SpawnBounds);
}
}
(2) The Spawned Object that checks for collision when starting. When an object starts, it immediately check for collisions using Physics2D.OverlapCircle on a while loop. When it finds a collision, a new point is calculated and a new check is made, this last until no collision is found and the object breaks the loop and enables its collider. Make sure that your object has a collider 2D and its layerMask WhatShouldIAvoid set to the same layer as your object.
Object code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectThatChecksSpawnPoint : MonoBehaviour
{
public float checkRadius;
public LayerMask WhatShouldIAvoid;
private BoxCollider2D _Collider;
private void Awake()
{
TryGetComponent(out _Collider);
}
private void Start()
{
StartCoroutine(Initialize());
}
private IEnumerator Initialize()
{
// disable collider to avoid hitting itself when checking for collisions
_Collider.enabled = false;
while (true)
{
// check for collisions
if (Physics2D.OverlapCircle(transform.position, checkRadius, WhatShouldIAvoid))
{
// if found, use RandomPointOnBox and Factory static variables to look for a new position
transform.position = ObjectFactory.RandomPointOnBox(ObjectFactory._SpawnCenter, ObjectFactory._SpawnBounds);
}
else
{
// else enable collider and break the loop
_Collider.enabled = true;
yield break;
}
yield return new WaitForEndOfFrame();
}
}
}