mmorpg2d/Assets/Script/cameraRPG.cs
2025-08-19 14:19:44 +05:30

199 lines
5.3 KiB
C#

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<Camera>();
}
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<Rigidbody2D>();
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));
}
}
}