Files
AZTECH_WB/Assets/Scripts/Camera/OrbitalController.cs
정영민 81ba9de085 [정영민] 층 조절 기능 추가 및 아이콘 오류 수정
26.03.18
- 층 자동 조절 기능 및 수동 조절 기능 추가
- 설비명 아이콘 안 보이는 오류 수정
- 카메라 2D/3D 위치 조정
2026-03-20 12:47:10 +09:00

317 lines
9.4 KiB
C#
Raw Blame History

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 = 55f;
orthoState.azimuth = 180f;
orthoState.pivotPosition = new Vector3(-37.5f, cameraPivot.transform.position.y, 32f);
orthoState.pivotRotation = originRotation;
SetViewMode(ViewMode.PerspectiveView);
}
private void LateUpdate()
{
//UI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ī<>޶<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if (IsClickUI || IsOnTheUI)
return;
input.GetInput();
Movement();
}
public void Movement()
{
Zoom();
Rotate();
Move();
if (IsCameraPivotInsideBoundary())
{
LastPositioning();
}
}
private bool IsCameraPivotInsideBoundary()
{
if (boundery == null)
return true;
return boundery.bounds.Contains(nextPosition);
}
public bool IsCameraInsideBoundary()
{
if (boundery == null)
return true;
var checkingBounds = boundery.bounds;
checkingBounds.size = checkingBounds.size + new Vector3(10,10,10);
return checkingBounds.Contains(camera.transform.position);
}
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 값<>?? 카메?<3F><> ?<3F><>?<3F><> 보정<EBB3B4>?
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 <20><> <20><><EFBFBD><EFBFBD>
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;
orthoState.distance = 55f;
orthoState.azimuth = 180f;
orthoState.pivotPosition = new Vector3(-37.5f, cameraPivot.transform.position.y, 32f);
break;
}
}
}
}