Files
AZTECH_WB/Assets/Scripts/Camera/OrbitalController.cs
정영민 6f1c335c73 [정영민] 설비 겹침 정렬 기능 수정
26.03.11
설비 겹침 기능 수정
2026-03-11 16:52:24 +09:00

307 lines
9.0 KiB
C#

using System;
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections.Generic;
namespace AZTECHWB
{
public enum ViewMode
{
PerspectiveView,
TopView
}
public struct OrbitState
{
public float elevation;
public float distance;
public float azimuth;
public Vector3 pivotPosition;
public Quaternion pivotRotation;
}
//TODO::Something... Util Functions
public class OrbitalController : MonoBehaviour
{
public ViewMode viewMode;
private Vector3 originValue;
private Vector3 originTargetPos;
private OrbitState perspectiveState;
private OrbitState orthoState;
private new Camera camera;
public Camera Camera { get { return camera; } }
public float moveSpeed;
public float rotateSpeed;
public float zoomSpeed;
public float maxElevation;
public float minElevation;
public float minDistance;
public float maxDistance;
public float currentElevation;
public float currentDistance;
public float currentAzimuth;
private Vector3 cameraPosition;
private Vector3 nextPosition;
private Quaternion originRotation;
public OrbitalControllerTarget cameraPivot;
private UserInput input;
private BoxCollider boundery;
public bool IsClickUI
{
get
{
bool result = false;
if (Input.GetMouseButtonDown(0))
{
result = EventSystem.current.IsPointerOverGameObject();
}
return result;
}
}
public bool IsOnTheUI
{
get
{
if (IsPointerOverExcludedUI())
{
return false;
}
else
{
var result = EventSystem.current.IsPointerOverGameObject();
return result;
}
}
}
bool IsPointerOverExcludedUI()
{
PointerEventData pointerData = new PointerEventData(EventSystem.current);
pointerData.position = Input.mousePosition;
List<RaycastResult> raycastResults = new List<RaycastResult>();
EventSystem.current.RaycastAll(pointerData, raycastResults);
if (raycastResults.Count > 0)
{
if ((LayerMask.GetMask("Default") & (1 << raycastResults[0].gameObject.layer)) != 0)
{
return true;
}
}
return false;
}
public void Awake()
{
camera = Camera.main;
cameraPivot = transform.GetComponentInChildren<OrbitalControllerTarget>();
boundery = transform.GetComponentInChildren<BoxCollider>();
originValue.x = currentElevation;
originValue.y = currentDistance;
originValue.z = currentAzimuth;
nextPosition = cameraPivot.transform.position;
originTargetPos = cameraPivot.transform.position;
originRotation = cameraPivot.transform.rotation;
perspectiveState.elevation = originValue.x;
perspectiveState.distance = originValue.y;
perspectiveState.azimuth = originValue.z;
perspectiveState.pivotPosition = originTargetPos;
perspectiveState.pivotRotation = originRotation;
orthoState.elevation = 90f;
orthoState.distance = originValue.y;
orthoState.azimuth = 0f;
orthoState.pivotPosition = Vector3.zero;
orthoState.pivotRotation = originRotation;
SetViewMode(ViewMode.PerspectiveView);
}
private void LateUpdate()
{
//UI 占쏙옙占쏙옙占쏙옙 카占쌨띰옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
if (IsClickUI || IsOnTheUI)
return;
input.GetInput();
Movement();
}
public void Movement()
{
Zoom();
Rotate();
Move();
if (BounderyCheck())
{
LastPositioning();
}
}
bool BounderyCheck()
{
if (boundery == null)
return true;
return boundery.bounds.Contains(nextPosition);
}
private void Move()
{
if (!input.leftClick)
{
return;
}
var delta = new Vector2(input.mouseX, input.mouseY);
var x = delta.x;
var y = delta.y * ((maxElevation - minElevation) / currentElevation);
var z = delta.y * ((minElevation - currentElevation) / maxElevation);
var moveVector = camera.transform.TransformDirection(x, y, -z);
moveVector.y = 0;
//0.5 媛믪?? 移대찓?씪 ?냽?룄 蹂댁젙媛?
moveVector *= (moveSpeed * 0.5f) * (currentDistance / maxDistance);
nextPosition = cameraPivot.transform.position - moveVector;
}
private void Zoom()
{
var nextDistance = currentDistance - input.mouseWheel * zoomSpeed;
currentDistance = Mathf.Lerp(currentDistance, nextDistance, zoomSpeed * Time.deltaTime);
currentDistance = Mathf.Clamp(currentDistance, minDistance, maxDistance);
camera.orthographicSize = currentDistance;
}
protected void Rotate()
{
if (!input.rightClick)
{
return;
}
currentAzimuth += input.mouseX * rotateSpeed;
currentAzimuth %= 360;
if(viewMode == ViewMode.PerspectiveView)
{
currentElevation -= input.mouseY * rotateSpeed;
currentElevation = Mathf.Clamp(currentElevation, minElevation, maxElevation);
}
}
public void LastPositioning()
{
cameraPivot.transform.position = nextPosition;
var dist = new Vector3(0, 0, -currentDistance);
var distPos = Quaternion.Euler(currentElevation, currentAzimuth, 0f) * dist;
cameraPosition = nextPosition + distPos;
camera.transform.position = cameraPosition;
if (currentElevation <= 90f)
{
camera.transform.rotation = Quaternion.Euler(currentElevation, currentAzimuth, 0f);
}
else
{
camera.transform.LookAt(cameraPivot.transform);
}
}
public void Rewind()
{
SetViewMode(ViewMode.PerspectiveView);
nextPosition = originTargetPos;
currentElevation = originValue.x;
currentDistance = originValue.y;
currentAzimuth = originValue.z;
LastPositioning();
}
public void SetViewMode(ViewMode mode)
{
if (viewMode == mode)
return;
SaveViewMode(viewMode);
viewMode = mode;
switch (mode)
{
case ViewMode.PerspectiveView:
SetPerspectiveView();
break;
case ViewMode.TopView:
SetOrthographicView();
break;
}
LastPositioning();
}
private void SetPerspectiveView()
{
camera.orthographic = false;
currentElevation = perspectiveState.elevation; //90 占쏙옙 占쏙옙占쏙옙
currentDistance = perspectiveState.distance;
currentAzimuth = perspectiveState.azimuth;
nextPosition = perspectiveState.pivotPosition;
}
private void SetOrthographicView()
{
camera.orthographic = true;
currentElevation = orthoState.elevation;
currentDistance = orthoState.distance;
currentAzimuth = orthoState.azimuth;
camera.orthographicSize = orthoState.distance;
nextPosition = orthoState.pivotPosition;
}
public void SetTargetPos(Vector3 pos)
{
nextPosition = pos;
LastPositioning();
}
private void SaveViewMode(ViewMode mode)
{
switch (mode)
{
case ViewMode.PerspectiveView:
perspectiveState.elevation = currentElevation;
perspectiveState.distance = currentDistance;
perspectiveState.azimuth = currentAzimuth;
perspectiveState.pivotPosition = cameraPivot.transform.position;
break;
case ViewMode.TopView:
orthoState.elevation = 90f; // 90 or 占쏙옙占쏙옙占쏙옙
orthoState.distance = 60f;
orthoState.azimuth = 0f;
orthoState.pivotPosition = Vector3.zero;
break;
}
}
}
}