307 lines
9.0 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
} |