Developedia
Developedia
A befoglaló téglatest: Bounds

A befoglaló téglatest: Bounds

Minden egyes Collider, Collider2D és Renderer komponensnek lekérdezhető hogy milyen térrészen belül helyezkedik el. Ezen térrész egy olyan téglatest, aminek minden éle párhuzamos a globális koordinátarendszer egyik tengelyével.

A Bound típus

Ezen befoglaló téglatestet egy Bounds típus írja le. Egy Bound példánynak van egy Vector3 középpontja (.center) és egy kiterjedése a tér három dimenziójában (.size), ami szintén Vector3 típusú.

Nézzük meg mit rajzol ki a fenti metódus!

Ezen befoglaló téglatestet használja fel a fizikai és a render-motor sok-sok optimalizálásra. Például azz Occlusion Culling folyamata eldob minden olyan objektumot a renderelésnél, aminek a befoglaló doboza nem érintkezik a kamera terével és ezt jóval gyorsabb kiszámolni, mint arra tesztelni, hogy a megjelenített mesh pontosan benne van-e a látótérben.

Occlusion Culling

Pár hasznos művelet Bound-okkal:

Saját magunk is létrehozhatunk egy Bound típust és használhatjuk bármire.

Például az alábbi kód egy beállítható [SerializeField] Bounds térrészen belül készít akárhány másolatot egy prototípusként megadott objektumból.

Beállítás
Beállítás

Ebből látható, hogy valójában a Bound típusú objektum az (egyes tengelyenkénti) fél-méretet (.extent) tárolja el, de lekérhető is a teljes méret (.size) is egy Property-n keresztül.

Eredmény
Eredmény

Hogy ez mire volt jó?… Hát azt én sem tudom. 🤷 Csak érzékeltetni akartam a Bounds típus működését.

A Rect típus

A Rect, azaz Rectangle/Téglalap egy típus, ami tekinthető a Bound megfelelőjének a 2D síkon, mivel a Rect objektum pozíciója és mérete is egyaránt Vector2 típusú. A Rect főleg a UI felületek kirajzolásához hasznos. Lásd később: Unity UI (Félkész…)Unity UI (Félkész…)

Logo

Főoldal

Blog

Elmélet

3D Studio

Adatvédelmi nyilatkozat

GY.I.K.

Házirend

Szerző: Marosi Csaba / marosi.csaba@3d-studio.hu

DiscordGitHubLinkedIn
void OnDrawGizmos()
{
	Renderer r = GetComponent<Renderer>();
	Collider2D c2 = GetComponent<Collider2D>();
	Collider c3 = GetComponent<Collider>();
	
	Bounds bounds;   // Téglatest térrészt leíró típus

	if (r != null)
		bounds = r.bounds;
	else if (c2 != null)
		bounds = c2.bounds;
	else if (c3 != null)
		bounds = c3.bounds;
	else
		return;
	
	Gizmos.color = Color.red;
	Gizmos.DrawWireCube(bounds.center, bounds.size); // A befoglaló téglatest kirajzolása
}
Vector3 c = bounds.center; // Középpont
Vector3 s = bounds.size; // Méret
Vector3 e = bounds.extents; // Félméret (tengeleynként)
Vector3 min = bounds.min; // Bal, alsó, hátsó sarok
Vector3 max = bounds.max; // Jobb, felső, elülső sarok

bool inside = bounds.Contains(p);          // Bound-on belül van-e a pont?
Vector3 closest = bounds.ClosestPoint(p);  // A legközelebbi pont a bound-on belül
bool intersect= bounds.IntersectRay(ray); // Metszi-e a bound a sugarat?
using UnityEngine;
using Random = UnityEngine.Random;

public class BoundInstantiater: MonoBehaviour
{
	[SerializeField] Bounds bounds;
	[SerializeField, Min(0)] float count = 5000;
	[SerializeField] GameObject prototype;
	
	void Start()
	{
		for (int i = 0; i < count; i++)
		InstantiateNew();
	}
	    
	void InstantiateNew()
	{
		float randomX = Random.Range(bounds.min.x, bounds.max.x);
		float randomY = Random.Range(bounds.min.y, bounds.max.y);
		float randomZ = Random.Range(bounds.min.z, bounds.max.z);
		Vector3 nextPosition = new Vector3(randomX, randomY, randomZ);
		
		GameObject newGO = Instantiate(prototype, transform); 
		newGO.transform.position = nextPosition;
	}
	
	void OnDrawGizmos()
	{
		Gizmos.color = Color.red;
		Gizmos.DrawWireCube(bounds.center, bounds.size);
	}
}