Forum begins after the advertisement:
[General] Smooth camera effect
Home › Forums › Video Game Tutorial Series › Creating a Rogue-like Shoot-em Up in Unity › [General] Smooth camera effect
- This topic has 3 replies, 2 voices, and was last updated 1 month ago by Terence.
-
AuthorPosts
-
November 16, 2024 at 3:05 pm #16363::
Hi everybody,
here is a smooth camera effect I use.
Step One : Add a camera xD Step Two : Create a script and paste this code Step Three : Drag and Drop the script into the camera in hierarchy (Select camera in Hierarchy) Step Four : in the inspector, drag the player you want to follow into “Target” Step Five : Do your Settings
My settings for a really tiny effect:
Smooth Speed: 10 (it’s not time to sleep) Look ahead Factor: 1.5 Edge Buffer: 0.5 Damping Factor: 0.5
Max zoom out distance: 0.2 Zoom out speed: 0.5 Zoom in speed: 0.5 Movement Treshold: 1 Sustained Movement Time: 1
Smooth Follow: The camera follows the player smoothly using SmoothDamp. Look Ahead: The camera slightly anticipates the player’s movement. Edge Buffer: Prevents the camera from moving too far away from the player. Damping: Adds an inertia effect to the camera’s movement.
maxZoomOutDistance: Maximum zoom-out distance. zoomOutSpeed: Speed at which the camera zooms out. zoomInSpeed: Speed at which the camera zooms in. movementThreshold: Minimum movement speed required to trigger zoom. sustainedMovementTime: Duration of movement needed before zooming starts.
<code> using UnityEngine; public class SmoothCameraController : MonoBehaviour { [Header("Target")] public Transform target; [Header("Follow Settings")] [Range(0.1f, 10f)] public float smoothSpeed = 3f; public Vector3 offset = new Vector3(0f, 0f, -10f); [Header("Advanced Settings")] [Range(0f, 5f)] public float lookAheadFactor = 1.5f; [Range(0f, 2f)] public float edgeBuffer = 0.5f; [Range(0f, 1f)] public float dampingFactor = 0.1f; [Header("Dynamic Zoom")] [Range(0f, 1f)] public float maxZoomOutDistance = 3f; [Range(0f, 5f)] public float zoomOutSpeed = 1f; [Range(0f, 5f)] public float zoomInSpeed = 2f; [Range(0f, 3f)] public float movementThreshold = 0.1f; [Range(0f, 5f)] public float sustainedMovementTime = 1f; private Vector3 velocity = Vector3.zero; private Vector3 lastTargetPosition; private Vector3 lookAheadPos; private float currentZoomLevel = 0f; private float sustainedMovementTimer = 0f; private float baseOrthographicSize; private Camera cam; private void Start() { if (target != null) { lastTargetPosition = target.position; transform.position = target.position + offset; } cam = GetComponent<Camera>(); if (cam != null) { baseOrthographicSize = cam.orthographicSize; } } private void LateUpdate() { if (target == null) return; UpdateZoom(); UpdateCameraPosition(); } private void UpdateZoom() { // Calculer la vitesse de déplacement du joueur Vector3 movementDelta = (target.position - lastTargetPosition); float movementSpeed = movementDelta.magnitude / Time.deltaTime; // Mettre à jour le timer de mouvement soutenu if (movementSpeed > movementThreshold) { sustainedMovementTimer += Time.deltaTime; } else { sustainedMovementTimer = Mathf.Max(0, sustainedMovementTimer - Time.deltaTime); } // Calculer le niveau de zoom cible float targetZoom = 0f; if (sustainedMovementTimer > sustainedMovementTime) { float zoomProgress = (sustainedMovementTimer - sustainedMovementTime) / sustainedMovementTime; targetZoom = Mathf.Min(maxZoomOutDistance, zoomProgress * maxZoomOutDistance); } // Appliquer le zoom progressivement float zoomSpeed = targetZoom > currentZoomLevel ? zoomOutSpeed : zoomInSpeed; currentZoomLevel = Mathf.Lerp(currentZoomLevel, targetZoom, Time.deltaTime * zoomSpeed); // Appliquer le zoom à la caméra if (cam != null) { cam.orthographicSize = baseOrthographicSize + currentZoomLevel; } else { // Pour une caméra en perspective, modifier la position Z offset.z = -10f - currentZoomLevel * 2f; } } private void UpdateCameraPosition() { // Calculer la direction du mouvement Vector3 moveDirection = (target.position - lastTargetPosition).normalized; lastTargetPosition = target.position; // Calculer la position anticipée (look ahead) Vector3 targetLookAheadPos = moveDirection * lookAheadFactor; lookAheadPos = Vector3.Lerp(lookAheadPos, targetLookAheadPos, Time.deltaTime * dampingFactor); // Position cible finale avec offset et look ahead Vector3 desiredPosition = target.position + offset + lookAheadPos; // Appliquer le smooth damp pour un mouvement fluide Vector3 smoothedPosition = Vector3.SmoothDamp( transform.position, desiredPosition, ref velocity, smoothSpeed * Time.deltaTime ); // Appliquer les limites de la caméra smoothedPosition = ApplyCameraBounds(smoothedPosition); // Mettre à jour la position de la caméra transform.position = smoothedPosition; } private Vector3 ApplyCameraBounds(Vector3 position) { if (target == null) return position; Vector3 targetPos = target.position; float maxDistance = lookAheadFactor + edgeBuffer + currentZoomLevel; float distanceX = Mathf.Abs(position.x - targetPos.x); float distanceY = Mathf.Abs(position.y - targetPos.y); if (distanceX > maxDistance) { float sign = Mathf.Sign(position.x - targetPos.x); position.x = targetPos.x + (maxDistance * sign); } if (distanceY > maxDistance) { float sign = Mathf.Sign(position.y - targetPos.y); position.y = targetPos.y + (maxDistance * sign); } return position; } public void ResetCamera() { if (target != null) { transform.position = target.position + offset; velocity = Vector3.zero; lookAheadPos = Vector3.zero; lastTargetPosition = target.position; currentZoomLevel = 0f; sustainedMovementTimer = 0f; if (cam != null) { cam.orthographicSize = baseOrthographicSize; } } } } </code>
has upvoted this post. November 17, 2024 at 3:03 pm #16373::Thanks Geoffrey, can you post a video of the smoothed camera effect? That will help people get an understanding of how the effect looks like, so they can decide if they want it in their project.
November 18, 2024 at 11:30 am #16391November 18, 2024 at 7:26 pm #16404 -
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: