using System; using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; using UnityEngine; 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; } public void RemovePlayer(int id) { players.Remove(id); } /// /// Rotates the camera to point at the center between the players. /// private void LateUpdate() { CenterBetweenPlayers(); AdjustZoom(); } private void CenterBetweenPlayers() { if (players.Count < 1) { return; } float x = transform.localPosition.x; float y = transform.localPosition.y; float z = transform.localPosition.z; foreach (GameObject p in players.Values) { if (p.IsDestroyed()) continue; Vector3 position = p.transform.localPosition; z = position.z; x += position.x; y += position.y; } x /= players.Count(); y /= players.Count(); 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), Rad2Deg * Acos(a / cXAxis) * Math.Sign(x), 0); if (transform.localEulerAngles != xyRotation / 2) { 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); } }