© 2025 魔力結構 未經授權,請勿任意轉載、改作或商業使用,僅供個人學習參考用途

using UnityEngine;
public class GarageOrbitCamera : MonoBehaviour
{
public Transform target;
public float distance = 15f;
public float zoomSpeed = 2f;
public float minDistance = 5f;
public float maxDistance = 25f;
public float rotationSpeed = 5f;
public float verticalLimit = 80f;
[Header("自動旋轉設定")]
public float idleTimeThreshold = 5f;
public float autoYawSpeed = 10f;
public float autoPitchAmplitude = 5f;
public float autoPitchMin = 10f;
public float autoPitchMax = 25f;
public float autoPitchSpeed = 0.5f; // sin 波速度
private float yaw = 90f;
private float pitch = 20f;
private float targetPitch;
private float targetDistance;
private float idleTimer = 0f;
private float autoPitchTimer = 0f;
private Vector3 currentPos;
private Vector2 lastMousePos;
private bool isDragging = false;
void Start()
{
targetPitch = pitch;
targetDistance = distance;
currentPos = transform.position;
}
void LateUpdate()
{
if (target == null) return;
bool isUserInput = false;
// 玩家控制:滑鼠左鍵旋轉
if (Input.GetMouseButton(0))
{
if (Input.GetMouseButtonDown(0))
{
targetPitch = pitch;
idleTimer = 0f;
autoPitchTimer = 0f;
// 記錄滑鼠起點
lastMousePos = Input.mousePosition;
isDragging = true;
}
else if (Input.GetMouseButtonUp(0))
{
isDragging = false;
}
if (isDragging)
{
Vector2 currentMousePos = Input.mousePosition;
Vector2 delta = currentMousePos - lastMousePos;
lastMousePos = currentMousePos;
yaw += delta.x * 0.2f; // 可以調整旋轉速度
targetPitch -= delta.y * 0.2f;
targetPitch = Mathf.Clamp(targetPitch, 5f, verticalLimit);
isUserInput = true;
}
}
// 玩家控制:滾輪縮放
float scroll = Input.GetAxis("Mouse ScrollWheel");
if (Mathf.Abs(scroll) > 0.001f)
{
targetDistance -= scroll * zoomSpeed;
targetDistance = Mathf.Clamp(targetDistance, minDistance, maxDistance);
isUserInput = true;
}
// 使用者操作 → 重置 idle timer
if (isUserInput)
{
idleTimer = 0f;
autoPitchTimer = 0f;
}
else
{
idleTimer += Time.deltaTime;
// 閒置一段時間 → 啟動自轉
if (idleTimer > idleTimeThreshold)
{
yaw += autoYawSpeed * Time.deltaTime;
// 使用 sin 波進行 pitch 起伏
autoPitchTimer += Time.deltaTime * autoPitchSpeed;
float sinOffset = Mathf.Sin(autoPitchTimer) * autoPitchAmplitude;
if (!Input.GetMouseButton(0)) // 如果滑鼠沒按下才自動改 pitch
{
float autoPitch = Mathf.Clamp(17.5f + sinOffset, autoPitchMin, autoPitchMax);
targetPitch = autoPitch;
}
}
}
// 平滑 pitch & zoom
pitch = Mathf.Lerp(pitch, targetPitch, Time.deltaTime * 4f);
distance = Mathf.Lerp(distance, targetDistance, Time.deltaTime * 6f);
// 平滑移動攝影機位置
Quaternion rotation = Quaternion.Euler(pitch, yaw, 0);
Vector3 desiredPos = rotation * new Vector3(0, 0, -distance) + target.position;
currentPos = Vector3.Lerp(currentPos, desiredPos, Time.deltaTime * 6f);
transform.position = currentPos;
// 保持 yaw 在 0~360 區間(避免無限增長)
if (yaw < 0f) yaw += 360f;
yaw %= 360f;
// 永遠鎖定展示中心
transform.LookAt(target.position);
}
}