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