From 9f9beecdf3812e6a594d487ce7daebaa2a4138cc Mon Sep 17 00:00:00 2001 From: wasdennnoch <leiter04@gmail.com> Date: Fri, 2 Apr 2021 23:17:47 +0200 Subject: [PATCH] Use Viewport coords for edge detection --- Assets/Scenes/Forest.unity | 2 +- Assets/Scripts/BaseCameraController.cs | 96 ++++++++++++++++---------- Assets/Scripts/Interpolator.cs | 4 +- 3 files changed, 62 insertions(+), 40 deletions(-) diff --git a/Assets/Scenes/Forest.unity b/Assets/Scenes/Forest.unity index cf5f6f6..52721d6 100644 --- a/Assets/Scenes/Forest.unity +++ b/Assets/Scenes/Forest.unity @@ -441,7 +441,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: moveSpeed: 10 - mouseEdgeDetectionBoxSize: 1.5 + edgeDetectionBoxInsets: {x: 0.1, y: 0.1} maxZoom: 5 minZoom: 1.5 zoomStepSize: 1 diff --git a/Assets/Scripts/BaseCameraController.cs b/Assets/Scripts/BaseCameraController.cs index b92cb36..b27dc0d 100644 --- a/Assets/Scripts/BaseCameraController.cs +++ b/Assets/Scripts/BaseCameraController.cs @@ -1,5 +1,4 @@ -using System.Collections; -using System.Collections.Generic; +using System; using UnityEngine; public class BaseCameraController : MonoBehaviour @@ -7,7 +6,7 @@ public class BaseCameraController : MonoBehaviour [Header("Movement")] [SerializeField] float moveSpeed = 10f; - [SerializeField] float mouseEdgeDetectionBoxSize = 1f; + [SerializeField] Vector2 edgeDetectionBoxInsets = new Vector2(0.1f, 0.1f); [Header("Zoom")] [SerializeField] float maxZoom = 5f; @@ -42,7 +41,7 @@ public class BaseCameraController : MonoBehaviour collider = GetComponent<BoxCollider2D>(); rigidbody = GetComponent<Rigidbody2D>(); - mouseMovementEdges = new InsetCameraEdges(camera); + mouseMovementEdges = new InsetCameraEdges(camera, edgeDetectionBoxInsets); zoomInterpolator = new Interpolator(1 / zoomSpeed, camera.orthographicSize, camera.orthographicSize, minZoom, maxZoom); moveXInterpolator = new Interpolator(1 / moveSpeed); moveYInterpolator = new Interpolator(1 / moveSpeed); @@ -66,8 +65,7 @@ public class BaseCameraController : MonoBehaviour inputVector.y = Input.GetAxisRaw("Vertical"); if (inputVector.magnitude == 0) { - var mouseViewportPos = camera.ScreenToWorldPoint(Input.mousePosition); - mouseMovementEdges.RecalculateBounds(mouseEdgeDetectionBoxSize * zoomRatio); + var mouseViewportPos = camera.ScreenToViewportPoint(Input.mousePosition); mouseMovementEdges.DrawDebug(); inputVector = mouseMovementEdges.GetOutOfBoundsDirection(mouseViewportPos); } @@ -101,82 +99,106 @@ public class BaseCameraController : MonoBehaviour camera = GetComponent<Camera>(); mouseMovementEdges = new InsetCameraEdges(camera); } - mouseMovementEdges.RecalculateBounds(mouseEdgeDetectionBoxSize * zoomRatio); + mouseMovementEdges.RecalculateBounds(edgeDetectionBoxInsets); mouseMovementEdges.DrawGizmos(); } + [Serializable] private class InsetCameraEdges { private Camera camera; private Vector3 insetVector; - public Vector3 bottomLeft; - public Vector3 topRight; - private Vector3 bottomRight; - private Vector3 topLeft; + private Box edges; public InsetCameraEdges(Camera camera) : this(camera, 0) { } - public InsetCameraEdges(Camera camera, float inset) : this(camera, inset, inset) { } + public InsetCameraEdges(Camera camera, float inset) : this(camera, new Vector2(inset, inset)) { } - public InsetCameraEdges(Camera camera, float insetX, float insetY) + public InsetCameraEdges(Camera camera, Vector2 insets) { this.camera = camera; - RecalculateBounds(insetX, insetY); + RecalculateBounds(insets); } public void RecalculateBounds(float newInset) { - RecalculateBounds(newInset, newInset); + RecalculateBounds(new Vector2(newInset, newInset)); } - public void RecalculateBounds(float newInsetX, float newInsetY) + public void RecalculateBounds(Vector2 newInsets) { - insetVector = new Vector3(newInsetX, newInsetY); + insetVector = newInsets; RecalculateBounds(); } public void RecalculateBounds() { - // TODO this would be way better if it would just use viewport positions - bottomLeft = camera.ViewportToWorldPoint(Vector3.zero) + insetVector; - topRight = camera.ViewportToWorldPoint(Vector3.one) - insetVector; - bottomLeft.z = 0; - topRight.z = 0; + edges = new Box(insetVector, Vector3.one - insetVector); } public Vector2 GetOutOfBoundsDirection(Vector2 point) { return new Vector2( - point.x < bottomLeft.x ? -1 : point.x > topRight.x ? 1 : 0, - point.y < bottomLeft.y ? -1 : point.y > topRight.y ? 1 : 0 + point.x < edges.bottomLeft.x ? -1 : point.x > edges.topRight.x ? 1 : 0, + point.y < edges.bottomLeft.y ? -1 : point.y > edges.topRight.y ? 1 : 0 ); } public void DrawGizmos() { - CalculateRemainingVectors(); + var worldEdges = edges.ToWorldBox(camera, 0); Gizmos.color = Color.red; - Gizmos.DrawLine(bottomLeft, bottomRight); - Gizmos.DrawLine(bottomRight, topRight); - Gizmos.DrawLine(topRight, topLeft); - Gizmos.DrawLine(topLeft, bottomLeft); + Gizmos.DrawLine(worldEdges.bottomLeft, worldEdges.bottomRight); + Gizmos.DrawLine(worldEdges.bottomRight, worldEdges.topRight); + Gizmos.DrawLine(worldEdges.topRight, worldEdges.topLeft); + Gizmos.DrawLine(worldEdges.topLeft, worldEdges.bottomLeft); } public void DrawDebug() { - CalculateRemainingVectors(); + var worldEdges = edges.ToWorldBox(camera, 0); var color = Color.magenta; - Debug.DrawLine(bottomLeft, bottomRight, color); - Debug.DrawLine(bottomRight, topRight, color); - Debug.DrawLine(topRight, topLeft, color); - Debug.DrawLine(topLeft, bottomLeft, color); + Debug.DrawLine(worldEdges.bottomLeft, worldEdges.bottomRight, color); + Debug.DrawLine(worldEdges.bottomRight, worldEdges.topRight, color); + Debug.DrawLine(worldEdges.topRight, worldEdges.topLeft, color); + Debug.DrawLine(worldEdges.topLeft, worldEdges.bottomLeft, color); } - private void CalculateRemainingVectors() + private readonly struct Box { - bottomRight = new Vector3(topRight.x, bottomLeft.y, bottomLeft.z); - topLeft = new Vector3(bottomLeft.x, topRight.y, topRight.z); + public readonly Vector3 bottomLeft; + public readonly Vector3 topRight; + public readonly Vector3 bottomRight; + public readonly Vector3 topLeft; + + public Box(Vector3 bottomLeft, Vector3 topRight) : this(bottomLeft, topRight, new Vector3(topRight.x, bottomLeft.y, bottomLeft.z), new Vector3(bottomLeft.x, topRight.y, topRight.z)) { } + + public Box(Vector3 bottomLeft, Vector3 topRight, Vector3 bottomRight, Vector3 topLeft) + { + this.bottomLeft = bottomLeft; + this.topRight = topRight; + this.bottomRight = bottomRight; + this.topLeft = topLeft; + } + + public Box ToWorldBox(Camera camera, float? zOverride = null) + { + var worldBottomLeft = camera.ViewportToWorldPoint(bottomLeft); + var worldTopRight = camera.ViewportToWorldPoint(topRight); + var worldBottomRight = camera.ViewportToWorldPoint(bottomRight); + var worldTopLeft = camera.ViewportToWorldPoint(topLeft); + if (zOverride != null) + { + worldBottomLeft.z = (float)zOverride; + worldTopRight.z = (float)zOverride; + worldBottomRight.z = (float)zOverride; + worldTopLeft.z = (float)zOverride; + } + return new Box(worldBottomLeft, worldTopRight, worldBottomRight, worldTopLeft); + } + + public override string ToString() => $"Box{{ Bottom Left: {bottomLeft} Bottom Right: {bottomRight} Top Right: {topRight} Top Left: {topLeft} }}"; } } diff --git a/Assets/Scripts/Interpolator.cs b/Assets/Scripts/Interpolator.cs index 7ba9a0f..4fe29f2 100644 --- a/Assets/Scripts/Interpolator.cs +++ b/Assets/Scripts/Interpolator.cs @@ -1,7 +1,7 @@ -using System.Collections; -using System.Collections.Generic; +using System; using UnityEngine; +[Serializable] public class Interpolator { -- GitLab