From 1815d51d680fa521eb41d0884e6512840cc90aa2 Mon Sep 17 00:00:00 2001 From: Jakob Feldmann Date: Mon, 22 Apr 2024 15:03:56 +0200 Subject: [PATCH] feat: camera dynamically zooms to keep players on screen --- Assets/Scenes/Arena.unity | 7 ++- Assets/Scenes/GameManagement.unity | 2 +- Assets/Scripts/CameraOperator.cs | 77 +++++++++++++++++++++++++++--- Assets/Scripts/UI/MatchEndMenu.cs | 2 + Assets/Scripts/UI/PauseMenu.cs | 2 + 5 files changed, 81 insertions(+), 9 deletions(-) diff --git a/Assets/Scenes/Arena.unity b/Assets/Scenes/Arena.unity index 1049758..703d88e 100644 --- a/Assets/Scenes/Arena.unity +++ b/Assets/Scenes/Arena.unity @@ -328,7 +328,7 @@ Camera: m_Enabled: 1 serializedVersion: 2 m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_BackGroundColor: {r: 0, g: 0, b: 0, a: 1} m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 @@ -396,6 +396,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 20df0926ff00f0e4dab5fd8ea03a31d2, type: 3} m_Name: m_EditorClassIdentifier: + MaxAdditionalDistance: 15 --- !u!114 &963194230 MonoBehaviour: m_ObjectHideFlags: 0 @@ -543,6 +544,10 @@ PrefabInstance: propertyPath: m_Layer value: 3 objectReference: {fileID: 0} + - target: {fileID: -8098169881513260187, guid: 303177f7648454b4fb8179c1378dd1ec, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} - target: {fileID: -8098169881513260187, guid: 303177f7648454b4fb8179c1378dd1ec, type: 3} propertyPath: m_TagString value: Untagged diff --git a/Assets/Scenes/GameManagement.unity b/Assets/Scenes/GameManagement.unity index 3d761d8..9597ced 100644 --- a/Assets/Scenes/GameManagement.unity +++ b/Assets/Scenes/GameManagement.unity @@ -587,7 +587,7 @@ MonoBehaviour: PlayerManager: {fileID: 4324267968298468629, guid: bf1ba420952f8cd4e8e6e02554c13bac, type: 3} AudioManager: {fileID: 4421901766771881742, guid: d2fa91ae61bbe6644b3847b83f0f21fb, type: 3} startCamera: {fileID: 1164443743} - IsTestRun: 0 + IsTestRun: 1 TestScene: 3 --- !u!1660057539 &9223372036854775807 SceneRoots: diff --git a/Assets/Scripts/CameraOperator.cs b/Assets/Scripts/CameraOperator.cs index 58bd32a..194296d 100644 --- a/Assets/Scripts/CameraOperator.cs +++ b/Assets/Scripts/CameraOperator.cs @@ -3,13 +3,30 @@ using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; using UnityEngine; -using static System.Math; +using UnityEngine.Rendering.Universal; using static UnityEngine.Mathf; public class CameraOperator : MonoBehaviour { private Dictionary players = new Dictionary(); + [SerializeField] + private int MaxAdditionalDistance = 15; + + + private float InitialDistance = 0; + private float MaxDistance; + + private Camera cam; + + private void Awake() + { + cam = gameObject.GetComponent(); + // Distance here is in the negative direction on the z axis + InitialDistance = transform.localPosition.z; + MaxDistance = InitialDistance - MaxAdditionalDistance; + } + public void AddPlayer(GameObject player) { players[player.GetInstanceID()] = player; @@ -23,15 +40,21 @@ public class CameraOperator : MonoBehaviour /// /// Rotates the camera to point at the center between the players. /// - void LateUpdate() + private void LateUpdate() + { + CenterBetweenPlayers(); + AdjustZoom(); + } + + private void CenterBetweenPlayers() { if (players.Count < 1) { return; } - float x = 0; - float y = 0; - float z = 30; + float x = transform.localPosition.x; + float y = transform.localPosition.y; + float z = transform.localPosition.z; foreach (GameObject p in players.Values) { if (p.IsDestroyed()) @@ -43,7 +66,7 @@ public class CameraOperator : MonoBehaviour } x /= players.Count(); y /= players.Count(); - float a = z - transform.localPosition.z; + float a = z - InitialDistance; float cXAxis = (float)Sqrt(Pow(a, 2) + Pow(x, 2)); float cYAxis = (float)Sqrt(Pow(a, 2) + Pow(y, 2)); Vector3 xyRotation = new Vector3(Rad2Deg * Acos(a / cYAxis) * -Math.Sign(y), @@ -53,4 +76,44 @@ public class CameraOperator : MonoBehaviour transform.localEulerAngles = xyRotation / 2; } } -} + private void AdjustZoom() + { + if (players.Count < 2) + { + return; + } + float Margin = Screen.height / 2; + + float maxXDistance = 0; + float maxYDistance = 0; + + foreach (GameObject player in players.Values) + { + var screenPos1 = cam.WorldToScreenPoint(player.transform.position); + foreach (GameObject p in players.Values) + { + if (p == player) + continue; + var screenPos2 = cam.WorldToScreenPoint(p.transform.position); + var distance = screenPos2 - screenPos1; + float xDistance = Abs(distance.x); + if (maxXDistance < xDistance) + maxXDistance = xDistance; + float yDistance = Abs(distance.y); + if (maxYDistance < yDistance) + maxYDistance = Abs(distance.y); + } + } + if (maxXDistance < Screen.width - Margin + && maxYDistance < Screen.height - Margin) + { + if (transform.localPosition.z < InitialDistance + 0.1f) + transform.localPosition += new Vector3(0, 0, 0.1f); + return; + } + + if (transform.localPosition.z > MaxDistance - 0.1f) + transform.localPosition -= new Vector3(0, 0, 0.1f); + + } +} \ No newline at end of file diff --git a/Assets/Scripts/UI/MatchEndMenu.cs b/Assets/Scripts/UI/MatchEndMenu.cs index 6844375..a41798a 100644 --- a/Assets/Scripts/UI/MatchEndMenu.cs +++ b/Assets/Scripts/UI/MatchEndMenu.cs @@ -32,6 +32,8 @@ public class MatchEndMenu : MonoBehaviour gameObject.transform.position = transform.position; gameObject.transform.rotation = transform.rotation; Canvas.enabled = true; + Camera.transform.position = MatchManager.G.MatchCamera.transform.position; + Camera.transform.rotation = MatchManager.G.MatchCamera.transform.rotation; Camera.SetActive(true); UIEventSystem.SetActive(true); MenuButtons.SetActive(true); diff --git a/Assets/Scripts/UI/PauseMenu.cs b/Assets/Scripts/UI/PauseMenu.cs index bef2ba5..38dfc48 100644 --- a/Assets/Scripts/UI/PauseMenu.cs +++ b/Assets/Scripts/UI/PauseMenu.cs @@ -34,6 +34,8 @@ public class PauseMenu : MonoBehaviour gameObject.transform.position = transform.position; gameObject.transform.rotation = transform.rotation; Canvas.enabled = true; + Camera.transform.position = MatchManager.G.MatchCamera.transform.position; + Camera.transform.rotation = MatchManager.G.MatchCamera.transform.rotation; Camera.SetActive(true); UIEventSystem.SetActive(true); PauseMenuButtons.SetActive(true);