using UnityEngine; using DG.Tweening; public class cameraRPG : MonoBehaviour { [Header("Core Settings")] public static cameraRPG instance; public Transform focus; public Vector3 offset = new Vector3(0, 0, -10); [Header("Movement")] public float followSpeed = 2f; public bool useSmoothing = true; [Header("Deadzone (Optional)")] public bool useDeadzone = false; public Vector2 deadzoneSize = new Vector2(2f, 1f); [Header("Look Ahead")] public bool useLookAhead = false; public float lookAheadDistance = 2f; public float lookAheadSpeed = 1f; [Header("Shake")] public float shakeDuration = 0.5f; public float shakeStrength = 1f; // Private variables private Vector3 targetPosition; private Vector3 lookAheadOffset; private bool isPaused = false; private Tween currentMoveTween; private Camera cam; void Awake() { if (instance == null) { instance = this; } else { Destroy(gameObject); return; } cam = GetComponent(); } void Start() { if (focus != null) { transform.position = focus.position + offset; } } public void SetTarget(Transform target) { focus = target; } public void SetPaused(bool paused) { isPaused = paused; } void LateUpdate() { if (focus == null || isPaused) return; CalculateTargetPosition(); MoveCamera(); } void CalculateTargetPosition() { targetPosition = focus.position + offset; // Look ahead based on movement if (useLookAhead) { Vector3 targetLookAhead = Vector3.zero; // You might want to get velocity from your player controller instead Rigidbody2D focusRb = focus.GetComponent(); if (focusRb != null) { Vector3 velocity = focusRb.velocity; targetLookAhead = velocity.normalized * lookAheadDistance; } lookAheadOffset = Vector3.Lerp(lookAheadOffset, targetLookAhead, Time.deltaTime * lookAheadSpeed); targetPosition += lookAheadOffset; } // Apply deadzone if (useDeadzone) { Vector3 currentPos = transform.position; Vector3 difference = targetPosition - currentPos; // Only move if outside deadzone if (Mathf.Abs(difference.x) > deadzoneSize.x / 2f) { targetPosition.x = currentPos.x + (difference.x - Mathf.Sign(difference.x) * deadzoneSize.x / 2f); } else { targetPosition.x = currentPos.x; } if (Mathf.Abs(difference.y) > deadzoneSize.y / 2f) { targetPosition.y = currentPos.y + (difference.y - Mathf.Sign(difference.y) * deadzoneSize.y / 2f); } else { targetPosition.y = currentPos.y; } } } void MoveCamera() { if (useSmoothing) { transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * followSpeed); } else { transform.position = targetPosition; } } // DOTween enhanced methods public void TeleportTo(Vector3 newPosition) { currentMoveTween?.Kill(); transform.position = newPosition + offset; } public void SmoothTeleportTo(Vector3 newPosition, float duration = 1f, Ease easeType = Ease.OutCubic) { currentMoveTween?.Kill(); Vector3 targetPos = newPosition + offset; currentMoveTween = transform.DOMove(targetPos, duration).SetEase(easeType); } public void Shake(float duration = -1, float strength = -1) { if (duration < 0) duration = shakeDuration; if (strength < 0) strength = shakeStrength; transform.DOShakePosition(duration, strength); } public void ZoomTo(float targetSize, float duration = 1f, Ease easeType = Ease.OutCubic) { if (cam != null) { cam.DOOrthoSize(targetSize, duration).SetEase(easeType); } } public void PunchScale(float strength = 0.1f, float duration = 0.3f) { transform.DOPunchScale(Vector3.one * strength, duration); } // Utility methods public Vector3 GetTargetPosition() { return targetPosition; } public bool IsMoving() { return Vector3.Distance(transform.position, targetPosition) > 0.01f; } void OnDrawGizmosSelected() { // Draw deadzone if (useDeadzone) { Gizmos.color = Color.yellow; Gizmos.DrawWireCube(transform.position, new Vector3(deadzoneSize.x, deadzoneSize.y, 0)); } } }