Skip to content

Instantly share code, notes, and snippets.

@mandarinx
Created June 15, 2022 10:04
Show Gist options
  • Save mandarinx/bf5618b9421e9ae8c13d1178d4748b30 to your computer and use it in GitHub Desktop.
Save mandarinx/bf5618b9421e9ae8c13d1178d4748b30 to your computer and use it in GitHub Desktop.
Spawning despawning

In Unity:

  1. Create a new scene
  2. Add a GameObject called Manager
  3. Add a GameObject called Spawner
  4. Add a GameObject called Despawner
  5. Add a Camera, set to main
  6. Add a Quad, rotate it 90 deg around X so that it forms a ground plane
  7. Create a new script called Manager.cs
  8. Create a new script called Spawner.cs
  9. Create a new script called Despawner.cs
  10. Create a new script called Entity.cs
  11. Create a default cube. Make sure it has a collider.
  12. Add the Entity.cs to the cube
  13. Create a prefab of the cube
  14. Remove the cube from the scene

Fill in the contents of the scripts with the scripts attached to this gist. Recompile, and add the scripts to their respective GameObject and add the references as necessary.

Finally, press Play.

Click the left mouse button to spawn, and right mouse button to despawn.

using UnityEngine;
using System.Collections;
using UnityEngine.UIElements;
public class Despawner : MonoBehaviour {
public Manager manager;
private void Update() {
if (!Input.GetMouseButtonUp(1)) {
return;
}
Camera cam = Camera.main;
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
bool didHit = Physics.Raycast(ray, out var hit, Mathf.Infinity);
if (!didHit) {
return;
}
Debug.DrawLine(cam.transform.position, cam.ScreenToWorldPoint(Input.mousePosition));
Entity e = hit.transform.GetComponent<Entity>();
if (e == null) {
return;
}
manager.Despawn(e);
}
}
using System;
using UnityEngine;
using System.Collections;
public class Entity : MonoBehaviour {
public int index;
private float time;
private void OnEnable() {
transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
}
public void DoUpdate(float dt) {
time += dt;
float scale = (Mathf.Cos(time) + 1f) / 4f;
transform.localScale = new Vector3(0.5f + scale, 0.5f, 0.5f + scale);
}
}
using System;
using UnityEngine;
using System.Collections;
public class Manager : MonoBehaviour {
public GameObject prefab;
private const int MAX = 16;
private Entity[] entities = new Entity[MAX];
private int spawnCount;
private int willDespawn = -1;
private void Start() {
for (int i = 0; i < MAX; ++i) {
entities[i] = Instantiate(prefab).GetComponent<Entity>();
entities[i].gameObject.SetActive(false);
entities[i].name = $"Entity_{i:00}";
entities[i].index = i;
}
}
private void Update() {
float dt = Time.deltaTime;
if (willDespawn >= 0) {
entities[willDespawn].gameObject.SetActive(false);
SwapWithLastActive(willDespawn);
willDespawn = -1;
spawnCount -= 1;
}
for (int i = 0; i < spawnCount; ++i) {
entities[i].DoUpdate(dt);
}
}
public void Spawn(Vector3 pos) {
if (spawnCount == MAX) {
return;
}
Entity nextEntity = entities[spawnCount];
nextEntity.gameObject.SetActive(true);
nextEntity.transform.localPosition = pos;
spawnCount += 1;
}
public void Despawn(Entity entity) {
willDespawn = entity.index;
}
private void SwapWithLastActive(int current) {
int last = spawnCount - 1;
Entity toSwap = entities[current];
Entity lastActive = entities[last];
entities[last] = toSwap;
entities[current] = lastActive;
toSwap.index = last;
lastActive.index = current;
toSwap.name = $"Entity_{toSwap.index:00}";
lastActive.name = $"Entity_{lastActive.index:00}";
}
}
using System;
using UnityEngine;
using System.Collections;
public class Spawner : MonoBehaviour {
public Manager manager;
private Vector3 hitPos;
private void Update() {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
bool didHit = Physics.Raycast(ray, out var hit, Mathf.Infinity);
if (!didHit) {
return;
}
hitPos = hit.point;
if (!Input.GetMouseButtonUp(0)) {
return;
}
manager.Spawn(hit.point);
}
private void OnDrawGizmos() {
Gizmos.DrawSphere(hitPos, 0.5f);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment