Forum begins after the advertisement:


[General] Smooth camera effect

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #16363
    Geoffrey
    Level 5
    Participant
    Helpful?
    Up
    1
    ::

    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.

    
    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;
                }
            }
        }
    }
    
    has upvoted this post.
    #16373
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    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.

    #16391
    Geoffrey
    Level 5
    Participant
    Helpful?
    Up
    1
    ::

    I can’t edit but here is the link:

    has upvoted this post.
    #16404
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Thank you Geoffrey. I really love the way your birthday suit hero runs around.

    I’ve also fixed the Imgur issue, so your images should be embedding correctly now.

Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: