317 lines
9.4 KiB
C#
317 lines
9.4 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 = 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;
|
||
}
|
||
}
|
||
}
|
||
} |