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.GameManagers;
|
||||
using Intrepid.Utilities;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
@ -9,14 +10,39 @@ using UnityEditor;
|
||||
|
||||
namespace Intrepid.Core.Camera
|
||||
{
|
||||
[ExecuteAlways]
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(BoxCollider))]
|
||||
public sealed class CameraBoundary : MonoBehaviour
|
||||
{
|
||||
[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;
|
||||
|
||||
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)
|
||||
{
|
||||
Proxy.Instance.EventBus.Raise(new CameraBoundaryEnterEvent
|
||||
@ -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
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
if (boxCollider.IsNull()) return;
|
||||
|
||||
DrawBoxFill();
|
||||
DrawHatchedBoxXZ();
|
||||
DrawBoxWire();
|
||||
@ -46,7 +210,7 @@ namespace Intrepid.Core.Camera
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -62,7 +226,7 @@ namespace Intrepid.Core.Camera
|
||||
{
|
||||
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 center = boxCollider.center;
|
||||
@ -113,27 +277,19 @@ namespace Intrepid.Core.Camera
|
||||
|
||||
var xAtMinZ = c + minZ;
|
||||
if (xAtMinZ >= minX && xAtMinZ <= maxX)
|
||||
{
|
||||
points[count++] = new Vector3(xAtMinZ, y, minZ);
|
||||
}
|
||||
|
||||
var xAtMaxZ = c + maxZ;
|
||||
if (xAtMaxZ >= minX && xAtMaxZ <= maxX)
|
||||
{
|
||||
points[count++] = new Vector3(xAtMaxZ, y, maxZ);
|
||||
}
|
||||
|
||||
var zAtMinX = minX - c;
|
||||
if (zAtMinX >= minZ && zAtMinX <= maxZ)
|
||||
{
|
||||
points[count++] = new Vector3(minX, y, zAtMinX);
|
||||
}
|
||||
|
||||
var zAtMaxX = maxX - c;
|
||||
if (zAtMaxX >= minZ && zAtMaxX <= maxZ)
|
||||
{
|
||||
points[count++] = new Vector3(maxX, y, zAtMaxX);
|
||||
}
|
||||
|
||||
if (count < 2)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user