add helpers on camera boundary
This commit is contained in:
parent
775dfd8ad2
commit
052f88c46d
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@ using System;
|
|||||||
using Intrepid.Core.Camera.Events;
|
using Intrepid.Core.Camera.Events;
|
||||||
using Intrepid.GameManagers;
|
using Intrepid.GameManagers;
|
||||||
using Intrepid.Utilities;
|
using Intrepid.Utilities;
|
||||||
|
using Sirenix.OdinInspector;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
@ -9,13 +10,38 @@ using UnityEditor;
|
|||||||
|
|
||||||
namespace Intrepid.Core.Camera
|
namespace Intrepid.Core.Camera
|
||||||
{
|
{
|
||||||
|
[ExecuteAlways]
|
||||||
[DisallowMultipleComponent]
|
[DisallowMultipleComponent]
|
||||||
[RequireComponent(typeof(BoxCollider))]
|
[RequireComponent(typeof(BoxCollider))]
|
||||||
public sealed class CameraBoundary : MonoBehaviour
|
public sealed class CameraBoundary : MonoBehaviour
|
||||||
{
|
{
|
||||||
[GroupInjections, SerializeField] private BoxCollider boxCollider;
|
[GroupInjections, SerializeField] private BoxCollider boxCollider;
|
||||||
|
[GroupConfigurations, SerializeField, Min(0f)] private float cameraPadding = 0.5f;
|
||||||
|
[GroupConfigurations, SerializeField, Min(0.1f)] private float triggerHeight = 5f;
|
||||||
|
|
||||||
public Bounds WorldBounds => boxCollider.bounds;
|
public Bounds WorldBounds => boxCollider.bounds;
|
||||||
|
|
||||||
|
private void Reset()
|
||||||
|
{
|
||||||
|
boxCollider = GetComponent<BoxCollider>();
|
||||||
|
ConfigureAsTrigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnValidate()
|
||||||
|
{
|
||||||
|
if (boxCollider.IsNull())
|
||||||
|
boxCollider = GetComponent<BoxCollider>();
|
||||||
|
|
||||||
|
ConfigureAsTrigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureAsTrigger()
|
||||||
|
{
|
||||||
|
if (boxCollider.IsNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
boxCollider.isTrigger = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnTriggerEnter(Collider other)
|
private void OnTriggerEnter(Collider other)
|
||||||
{
|
{
|
||||||
@ -33,10 +59,148 @@ namespace Intrepid.Core.Camera
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GroupDebug, Button(ButtonSizes.Medium)]
|
||||||
|
private void SetToCameraMinimumSize()
|
||||||
|
{
|
||||||
|
if (!TryGetCameraFootprintLocalBounds(out var localBounds))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var size = boxCollider.size;
|
||||||
|
|
||||||
|
size.x = localBounds.size.x + cameraPadding * 2f;
|
||||||
|
size.y = triggerHeight;
|
||||||
|
size.z = localBounds.size.z + cameraPadding * 2f;
|
||||||
|
|
||||||
|
boxCollider.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
[GroupDebug, Button(ButtonSizes.Medium)]
|
||||||
|
private void ClampToCameraMinimumSize()
|
||||||
|
{
|
||||||
|
if (!TryGetCameraFootprintLocalBounds(out var localBounds))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var size = boxCollider.size;
|
||||||
|
|
||||||
|
size.x = Mathf.Max(size.x, localBounds.size.x + cameraPadding * 2f);
|
||||||
|
size.y = triggerHeight;
|
||||||
|
size.z = Mathf.Max(size.z, localBounds.size.z + cameraPadding * 2f);
|
||||||
|
|
||||||
|
boxCollider.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
[GroupDebug, Button(ButtonSizes.Medium)]
|
||||||
|
private void FitToCurrentCameraView()
|
||||||
|
{
|
||||||
|
if (!TryGetCameraFootprintLocalBounds(out var localBounds))
|
||||||
|
return;
|
||||||
|
|
||||||
|
boxCollider.center = new Vector3(
|
||||||
|
localBounds.center.x,
|
||||||
|
0f,
|
||||||
|
localBounds.center.z
|
||||||
|
);
|
||||||
|
|
||||||
|
boxCollider.size = new Vector3(
|
||||||
|
localBounds.size.x + cameraPadding * 2f,
|
||||||
|
triggerHeight,
|
||||||
|
localBounds.size.z + cameraPadding * 2f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[GroupDebug, Button(ButtonSizes.Medium)]
|
||||||
|
private void ApplyTriggerHeight()
|
||||||
|
{
|
||||||
|
var size = boxCollider.size;
|
||||||
|
size.y = triggerHeight;
|
||||||
|
boxCollider.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
[GroupDebug, Button(ButtonSizes.Medium)]
|
||||||
|
private void ResetColliderCenter()
|
||||||
|
{
|
||||||
|
boxCollider.center = Vector3.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetCameraFootprintLocalBounds(out Bounds localBounds)
|
||||||
|
{
|
||||||
|
localBounds = default;
|
||||||
|
|
||||||
|
if (!TryGetReferenceCamera(out var cam))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!cam.orthographic)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"{nameof(CameraBoundary)} only supports orthographic cameras for boundary utilities.", this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var planeY = boxCollider.transform.TransformPoint(boxCollider.center).y;
|
||||||
|
var groundPlane = new Plane(Vector3.up, new Vector3(0f, planeY, 0f));
|
||||||
|
|
||||||
|
var viewportCorners = new[]
|
||||||
|
{
|
||||||
|
new Vector3(0f, 0f, 0f),
|
||||||
|
new Vector3(0f, 1f, 0f),
|
||||||
|
new Vector3(1f, 1f, 0f),
|
||||||
|
new Vector3(1f, 0f, 0f),
|
||||||
|
};
|
||||||
|
|
||||||
|
var hasPoint = false;
|
||||||
|
|
||||||
|
foreach (var viewportCorner in viewportCorners)
|
||||||
|
{
|
||||||
|
var ray = cam.ViewportPointToRay(viewportCorner);
|
||||||
|
|
||||||
|
if (!groundPlane.Raycast(ray, out var distance))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var worldPoint = ray.GetPoint(distance);
|
||||||
|
var localPoint = boxCollider.transform.InverseTransformPoint(worldPoint);
|
||||||
|
|
||||||
|
if (!hasPoint)
|
||||||
|
{
|
||||||
|
localBounds = new Bounds(localPoint, Vector3.zero);
|
||||||
|
hasPoint = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
localBounds.Encapsulate(localPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetReferenceCamera(out UnityEngine.Camera cam)
|
||||||
|
{
|
||||||
|
cam = CameraSystem.Instance?.MainCamera;
|
||||||
|
|
||||||
|
if (cam.IsNotNull())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
cam = UnityEngine.Camera.main;
|
||||||
|
|
||||||
|
if (cam.IsNotNull())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (SceneView.lastActiveSceneView.IsNotNull())
|
||||||
|
{
|
||||||
|
cam = SceneView.lastActiveSceneView.camera;
|
||||||
|
return cam.IsNotNull();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Debug.LogWarning($"{nameof(CameraBoundary)} could not find a reference camera.", this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
private void OnDrawGizmosSelected()
|
private void OnDrawGizmosSelected()
|
||||||
{
|
{
|
||||||
if (boxCollider.IsNull()) return;
|
if (boxCollider.IsNull()) return;
|
||||||
|
|
||||||
DrawBoxFill();
|
DrawBoxFill();
|
||||||
DrawHatchedBoxXZ();
|
DrawHatchedBoxXZ();
|
||||||
DrawBoxWire();
|
DrawBoxWire();
|
||||||
@ -46,7 +210,7 @@ namespace Intrepid.Core.Camera
|
|||||||
{
|
{
|
||||||
var b = boxCollider.bounds;
|
var b = boxCollider.bounds;
|
||||||
|
|
||||||
Gizmos.color = new Color(1f, 0f, 1f, 0.10f); // alpha
|
Gizmos.color = new Color(1f, 0f, 1f, 0.10f);
|
||||||
Gizmos.DrawCube(b.center, b.size);
|
Gizmos.DrawCube(b.center, b.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +226,7 @@ namespace Intrepid.Core.Camera
|
|||||||
{
|
{
|
||||||
const float hatchSpacing = .5f;
|
const float hatchSpacing = .5f;
|
||||||
|
|
||||||
Handles.color = new Color(1f, 0f, 1f, 0.65f); // alpha
|
Handles.color = new Color(1f, 0f, 1f, 0.65f);
|
||||||
|
|
||||||
var size = boxCollider.size;
|
var size = boxCollider.size;
|
||||||
var center = boxCollider.center;
|
var center = boxCollider.center;
|
||||||
@ -113,27 +277,19 @@ namespace Intrepid.Core.Camera
|
|||||||
|
|
||||||
var xAtMinZ = c + minZ;
|
var xAtMinZ = c + minZ;
|
||||||
if (xAtMinZ >= minX && xAtMinZ <= maxX)
|
if (xAtMinZ >= minX && xAtMinZ <= maxX)
|
||||||
{
|
|
||||||
points[count++] = new Vector3(xAtMinZ, y, minZ);
|
points[count++] = new Vector3(xAtMinZ, y, minZ);
|
||||||
}
|
|
||||||
|
|
||||||
var xAtMaxZ = c + maxZ;
|
var xAtMaxZ = c + maxZ;
|
||||||
if (xAtMaxZ >= minX && xAtMaxZ <= maxX)
|
if (xAtMaxZ >= minX && xAtMaxZ <= maxX)
|
||||||
{
|
|
||||||
points[count++] = new Vector3(xAtMaxZ, y, maxZ);
|
points[count++] = new Vector3(xAtMaxZ, y, maxZ);
|
||||||
}
|
|
||||||
|
|
||||||
var zAtMinX = minX - c;
|
var zAtMinX = minX - c;
|
||||||
if (zAtMinX >= minZ && zAtMinX <= maxZ)
|
if (zAtMinX >= minZ && zAtMinX <= maxZ)
|
||||||
{
|
|
||||||
points[count++] = new Vector3(minX, y, zAtMinX);
|
points[count++] = new Vector3(minX, y, zAtMinX);
|
||||||
}
|
|
||||||
|
|
||||||
var zAtMaxX = maxX - c;
|
var zAtMaxX = maxX - c;
|
||||||
if (zAtMaxX >= minZ && zAtMaxX <= maxZ)
|
if (zAtMaxX >= minZ && zAtMaxX <= maxZ)
|
||||||
{
|
|
||||||
points[count++] = new Vector3(maxX, y, zAtMaxX);
|
points[count++] = new Vector3(maxX, y, zAtMaxX);
|
||||||
}
|
|
||||||
|
|
||||||
if (count < 2)
|
if (count < 2)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user