using System.Collections.Generic; using UnityEngine; using Game; using Music; using Player; namespace Player { /// /// This class controls the movement of the camera to follow players during the game. /// It also handles special behavior for the camera in the win scene. /// public class PlayerCameraMovement : MonoBehaviour { /// /// The starting position of the camera. /// private Vector3 start; /// /// The target position the camera should move toward. /// private Vector3 target; /// /// The weight used to blend between the camera's starting position and the players' average position. /// public float weight; /// /// The speed at which the camera moves toward the target position. /// public float speed; /// /// The player who won the game, used to focus the camera in the win scene. /// private GameObject playerThatWon; /// /// The lowest vertical position the camera can move to. /// public float lowerBound; /// /// Indicates whether the camera is in the win scene mode. /// public bool winScene = false; /// /// Indicates whether the camera should remain static and not follow players. /// public bool staticCamera = false; /// /// Initializes the camera's starting position. /// private void Start() { start = transform.position; } /// /// Updates the camera's position every frame to follow players or focus on the winner. /// private void Update() { // If the game is over, focus the camera on the player that won if (winScene) { if (playerThatWon == null || !playerThatWon.activeInHierarchy) { playerThatWon = FindWinner(); } if (playerThatWon != null) { // Move the camera toward the winning player's position target = playerThatWon.transform.position; transform.position = Vector3.Lerp( transform.position, new Vector3(target.x, target.y, target.z - 10), speed * 12 * Time.deltaTime ); // Ensure the camera does not go below the lower bound if (transform.position.y < lowerBound) { transform.position = new Vector3(transform.position.x, lowerBound, transform.position.z); } } return; } // Follow the players during the game List players = GameManager.players; if (players.Count == 0) return; Vector3 playerAverage = Vector3.zero; int activePlayers = 0; // Calculate the average position of all active players foreach (GameObject player in players) { if (player == null || !player.activeInHierarchy) continue; Damageable damageable = player.GetComponent(); if (damageable != null && damageable.dying) continue; playerAverage += player.transform.position; activePlayers++; } if (activePlayers == 0 || staticCamera) return; playerAverage /= activePlayers; // Blend between the starting position and the players' average position target = start * weight + playerAverage * (1 - weight); transform.position = Vector3.Lerp( transform.position, new Vector3(target.x, target.y, transform.position.z), speed * Time.deltaTime ); // Ensure the camera does not go below the lower bound if (transform.position.y < lowerBound) { transform.position = new Vector3(transform.position.x, lowerBound, transform.position.z); } } /// /// Activates the win scene mode and focuses the camera on the winning player. /// /// The player who won the game. public void WinScene(GameObject player) { winScene = true; playerThatWon = player; } /// /// Finds the first active player in the game, used to determine the winner. /// /// The first active player GameObject, or null if no players are active. private GameObject FindWinner() { foreach (GameObject player in GameManager.players) { if (player != null && player.activeInHierarchy) { return player; } } return null; } } }