Cached Camera Reference
Accessing Camera.main repeatedly incurs a performance cost because Unity perfomrs a scene-wide search by tag each time. To avoid this, maintain a single cached reference initialized on first access:
private static Camera _cachedMainCamera;
public static Camera MainCamera
{
get
{
if (_cachedMainCamera == null)
_cachedMainCamera = Camera.main;
return _cachedMainCamera;
}
}
Reusable WaitForSeconds Instances
Creating WaitForSeconds objects frequently triggers unnecessary heap allocations. A dictionary-based cache returns pre-allocated instances for common time values:
private static readonly Dictionary<float, WaitForSeconds> _waitCache = new Dictionary<float, WaitForSeconds>();
public static WaitForSeconds GetWait(float seconds)
{
if (_waitCache.TryGetValue(seconds, out WaitForSeconds cached))
return cached;
cached = new WaitForSeconds(seconds);
_waitCache[seconds] = cached;
return cached;
}
UI Interaction Detection
Determine whether the current input position overlaps any UI element using Unity’s event system without allocating new collections per call:
private static readonly PointerEventData _pointerData = new PointerEventData(EventSystem.current);
private static readonly List<RaycastResult> _raycastResults = new List<RaycastResult>();
public static bool IsInputOverUI()
{
_pointerData.position = Input.mousePosition;
_raycastResults.Clear();
EventSystem.current.RaycastAll(_pointerData, _raycastResults);
return _raycastResults.Count > 0;
}
Canvas Element World Position Conversion
Convert a RectTransform from canvas space to world coordinates using RectTransformUtility:
public static Vector3 WorldPositionFromCanvasElement(RectTransform element)
{
RectTransformUtility.ScreenPointToWorldPointInRectangle(
element,
element.position,
MainCamera,
out Vector3 worldPos);
return worldPos;
}
Efficient Child GameObject Cleanup
Extend Transform with a method that safely destroys all immediate child game objects in one operation:
public static void ClearChildren(this Transform parent)
{
for (int i = parent.childCount - 1; i >= 0; i--)
{
Object.Destroy(parent.GetChild(i).gameObject);
}
}