333 lines
12 KiB
C#
333 lines
12 KiB
C#
using asap.core;
|
|
using Cinemachine;
|
|
using System;
|
|
using UniRx;
|
|
using UnityEngine;
|
|
|
|
|
|
public class BuildingCameraController : MonoBehaviour
|
|
{
|
|
//public Transform mainCameraTr;
|
|
public CinemachineVirtualCamera cameraVirtual;
|
|
|
|
public CinemachineFreeLook[] cameraFreeLook;
|
|
public GameObject cameraMove;
|
|
string inputAxisXName = "Mouse X";
|
|
|
|
string inputAxisYName = "Mouse Y";
|
|
|
|
// public CinemachineVirtualCameraBase vcam;
|
|
private int index = 0;
|
|
bool photo;
|
|
private CinemachineVirtualCameraBase currentCamera;
|
|
float zoomSpeed = 0.2f;
|
|
private Vector2[] lastTouchPositions = new Vector2[2];
|
|
private Vector2[] currentTouchPositions = new Vector2[2];
|
|
private float lastTouchDistance;
|
|
|
|
private float currentTouchDistance;
|
|
//方向 圆心
|
|
private Vector2 circle;
|
|
private Vector2 touchDelta0;
|
|
private Vector2 touchDelta1;
|
|
private Vector2 currentDelta0;
|
|
private Vector2 currentDelta1;
|
|
float signedAngle0;
|
|
float signedAngle1;
|
|
float angle0;
|
|
float angle1;
|
|
public Transform lookAt;
|
|
public Transform boundary1;
|
|
public Transform boundary2;
|
|
private Vector3 minVec;
|
|
private Vector3 maxVec;
|
|
//是否双指
|
|
private bool isTouchTwo = false;
|
|
//双指拖动开始阈值
|
|
public float touchTwoThreshold = 50;
|
|
|
|
public CinemachineDollyCart cinemachineDollyCart;
|
|
public CinemachineVirtualCamera cameraPhotoVirtual;
|
|
|
|
bool isMove = false;
|
|
bool isTransfer = false;
|
|
Vector3 startPos;
|
|
IDisposable disposable;
|
|
bool isDrag = false;
|
|
void Start()
|
|
{
|
|
transform.Find("CameraMain").gameObject.SetActive(false);
|
|
startPos = lookAt.localPosition;
|
|
cameraMove.SetActive(false);
|
|
minVec = new Vector3(Mathf.Min(boundary1.localPosition.x, boundary2.localPosition.x), lookAt.localPosition.y, Mathf.Min(boundary1.localPosition.z, boundary2.localPosition.z));
|
|
maxVec = new Vector3(Mathf.Max(boundary1.localPosition.x, boundary2.localPosition.x), lookAt.localPosition.y, Mathf.Max(boundary1.localPosition.z, boundary2.localPosition.z));
|
|
//Zoom = cameraVirtual.m_Lens.FieldOfView;
|
|
currentCamera = cameraVirtual;
|
|
cameraVirtual.gameObject.SetActive(true);
|
|
for (int i = 0; i < cameraFreeLook.Length; i++)
|
|
{
|
|
cameraFreeLook[i].gameObject.SetActive(false);
|
|
}
|
|
//mainCameraTr.gameObject.SetActive(false);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
disposable = GContext.OnEvent<SwitchVirtualCameraEvent>().Subscribe(OnSwitchVirtualCamera);
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
disposable?.Dispose();
|
|
disposable = null;
|
|
}
|
|
//切换虚拟相机
|
|
void SwitchVirtualCamera(int _index)
|
|
{
|
|
if (index != _index)
|
|
{
|
|
CinemachineVirtualCameraBase nextCamera;
|
|
if (_index != 0)
|
|
{
|
|
nextCamera = cameraFreeLook[_index - 1];
|
|
nextCamera.transform.position = currentCamera.transform.position;
|
|
}
|
|
else
|
|
{
|
|
nextCamera = cameraVirtual;
|
|
lookAt.localPosition = startPos;
|
|
}
|
|
currentCamera.gameObject.SetActive(false);
|
|
currentCamera = nextCamera;
|
|
currentCamera.gameObject.SetActive(true);
|
|
if (isMove && _index == 0)
|
|
{
|
|
cameraMove.SetActive(false);
|
|
isMove = false;
|
|
}
|
|
}
|
|
index = _index;
|
|
}
|
|
void OnSwitchVirtualCamera(SwitchVirtualCameraEvent eventData)
|
|
{
|
|
isDrag = eventData.isDrag;
|
|
if (eventData.type > 10)
|
|
{
|
|
photo = true;
|
|
if (eventData.type == 11)
|
|
{
|
|
SetPhotoVirtual();
|
|
}
|
|
else if (eventData.type == 12)
|
|
{
|
|
SetCinemachineDollyCart();
|
|
}
|
|
index = eventData.type;
|
|
return;
|
|
}
|
|
if (isDrag || eventData.type == 0)
|
|
{
|
|
if (index > 10)
|
|
{
|
|
if (cameraPhotoVirtual != null)
|
|
{
|
|
cameraPhotoVirtual.gameObject.SetActive(false);
|
|
}
|
|
cinemachineDollyCart.transform.parent.gameObject.SetActive(false);
|
|
}
|
|
SwitchVirtualCamera(eventData.type);
|
|
}
|
|
}
|
|
|
|
void SetPhotoVirtual()
|
|
{
|
|
if (cameraPhotoVirtual == null)
|
|
{
|
|
Debug.LogError("cameraPhotoVirtual is null");
|
|
return;
|
|
}
|
|
currentCamera.gameObject.SetActive(false);
|
|
|
|
cameraPhotoVirtual.gameObject.SetActive(true);
|
|
}
|
|
|
|
void SetCinemachineDollyCart()
|
|
{
|
|
if (cameraPhotoVirtual != null)
|
|
{
|
|
cameraPhotoVirtual.gameObject.SetActive(false);
|
|
}
|
|
|
|
currentCamera.gameObject.SetActive(false);
|
|
cinemachineDollyCart.transform.parent.gameObject.SetActive(true);
|
|
cinemachineDollyCart.m_Speed = 0;
|
|
}
|
|
|
|
|
|
void Update()
|
|
{
|
|
if (!isDrag)
|
|
{
|
|
return;
|
|
}
|
|
if (photo)
|
|
{
|
|
if (Input.GetMouseButton(0) || Input.touchCount == 1)
|
|
{
|
|
if (cinemachineDollyCart.transform.parent.gameObject.activeSelf)
|
|
{
|
|
cinemachineDollyCart.m_Position -= Input.GetAxis(inputAxisXName);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
#if UNITY_EDITOR
|
|
if (Input.GetMouseButton(0) && index == 1)
|
|
#else
|
|
if (Input.touchCount==1&& index==1)
|
|
#endif
|
|
{
|
|
if (!isTouchTwo)
|
|
{
|
|
//SwitchVirtualCamera(1);
|
|
cameraFreeLook[index - 1].m_XAxis.m_InputAxisValue = Input.GetAxis(inputAxisXName);
|
|
cameraFreeLook[index - 1].m_YAxis.m_InputAxisValue = Input.GetAxis(inputAxisYName);
|
|
}
|
|
}
|
|
else if (Input.touchCount == 2)
|
|
{
|
|
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
|
|
{
|
|
|
|
currentTouchPositions[0] = Input.GetTouch(0).position;
|
|
currentTouchPositions[1] = Input.GetTouch(1).position;
|
|
if (!isTouchTwo)
|
|
{
|
|
isTouchTwo = true;
|
|
lastTouchPositions[0] = currentTouchPositions[0];
|
|
lastTouchPositions[1] = currentTouchPositions[1];
|
|
}
|
|
|
|
if (Vector2.Distance(currentTouchPositions[0], lastTouchPositions[0]) + Vector2.Distance(currentTouchPositions[1], lastTouchPositions[1]) > touchTwoThreshold && index != 2)
|
|
{
|
|
SwitchVirtualCamera(2);
|
|
}
|
|
if (!isTransfer && !isMove && (Vector2.Distance(currentTouchPositions[0], lastTouchPositions[0]) < touchTwoThreshold && Vector2.Distance(currentTouchPositions[1], lastTouchPositions[1]) < touchTwoThreshold))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (index == 2)
|
|
{
|
|
circle = (lastTouchPositions[0] + lastTouchPositions[1]) / 2;
|
|
touchDelta0 = lastTouchPositions[0] - circle;
|
|
touchDelta1 = lastTouchPositions[1] - circle;
|
|
currentDelta0 = (currentTouchPositions[0] - lastTouchPositions[0]);
|
|
currentDelta1 = (currentTouchPositions[1] - lastTouchPositions[1]);
|
|
signedAngle0 = Vector2.SignedAngle(touchDelta0, currentDelta0);
|
|
signedAngle1 = Vector2.SignedAngle(touchDelta1, currentDelta1);
|
|
angle0 = Vector2.Angle(touchDelta0, currentDelta0);
|
|
angle1 = Vector2.Angle(touchDelta1, currentDelta1);
|
|
if ((Vector2.Angle(currentDelta0, currentDelta1) > 30) && !isMove || isTransfer)
|
|
{
|
|
TransferPOrR();
|
|
}
|
|
else if ((!isTransfer && Vector2.Angle(currentDelta0, currentDelta1) < 20) || (isMove && (Vector2.Angle(currentDelta0, currentDelta1) < 50)))
|
|
{
|
|
Move();
|
|
}
|
|
else
|
|
{
|
|
cameraFreeLook[index - 1].m_YAxis.m_InputAxisValue = 0;
|
|
cameraFreeLook[index - 1].m_XAxis.m_InputAxisValue = 0;
|
|
}
|
|
|
|
lastTouchPositions[0] = currentTouchPositions[0];
|
|
lastTouchPositions[1] = currentTouchPositions[1];
|
|
}
|
|
}
|
|
else if (index != 0)
|
|
{
|
|
cameraFreeLook[index - 1].m_YAxis.m_InputAxisValue = 0;
|
|
cameraFreeLook[index - 1].m_XAxis.m_InputAxisValue = 0;
|
|
}
|
|
}
|
|
else if (Input.touchCount == 0 && index != 0)
|
|
{
|
|
isTouchTwo = false;
|
|
isTransfer = false;
|
|
if (isMove)
|
|
{
|
|
cameraFreeLook[1].transform.position = cameraMove.transform.position;
|
|
currentCamera.gameObject.SetActive(true);
|
|
cameraMove.SetActive(false);
|
|
isMove = false;
|
|
}
|
|
cameraFreeLook[index - 1].m_XAxis.m_InputAxisValue = 0;
|
|
cameraFreeLook[index - 1].m_YAxis.m_InputAxisValue = 0;
|
|
}
|
|
}
|
|
//旋转缩放
|
|
void TransferPOrR()
|
|
{
|
|
isTransfer = true;
|
|
if (signedAngle0 * signedAngle1 > 0 && ((angle0 > 60 && angle0 < 120) || (angle1 > 60 && angle1 < 120)))
|
|
{
|
|
float delta = currentDelta0.magnitude + currentDelta1.magnitude;
|
|
if (signedAngle0 > 0)
|
|
{
|
|
cameraFreeLook[index - 1].m_XAxis.m_InputAxisValue = delta * zoomSpeed;
|
|
}
|
|
else
|
|
{
|
|
cameraFreeLook[index - 1].m_XAxis.m_InputAxisValue = -delta * zoomSpeed;
|
|
}//旋转
|
|
|
|
}
|
|
else if ((angle0 > 150 && angle1 > 150) || (angle0 < 30 && angle1 < 30))
|
|
{
|
|
currentTouchDistance = Vector2.Distance(currentTouchPositions[0], currentTouchPositions[1]);
|
|
lastTouchDistance = Vector2.Distance(lastTouchPositions[0], lastTouchPositions[1]);//缩放
|
|
float delta = currentTouchDistance - lastTouchDistance;
|
|
if (delta < 0)
|
|
{
|
|
cameraFreeLook[index - 1].m_YAxis.m_InputAxisValue = delta * zoomSpeed;
|
|
}
|
|
else
|
|
{
|
|
cameraFreeLook[index - 1].m_YAxis.m_InputAxisValue = delta * zoomSpeed;
|
|
}
|
|
}
|
|
}
|
|
//移动
|
|
void Move()
|
|
{
|
|
if (!isMove)
|
|
{
|
|
isMove = true;
|
|
cameraMove.transform.position = cameraFreeLook[index - 1].transform.position;
|
|
cameraMove.SetActive(true);
|
|
currentCamera.gameObject.SetActive(false);
|
|
}
|
|
//方向
|
|
Vector2 offset;
|
|
if (currentDelta0.magnitude > currentDelta1.magnitude)
|
|
{
|
|
offset = currentDelta0;
|
|
}
|
|
else
|
|
{
|
|
offset = currentDelta1;
|
|
}
|
|
//同方向移动
|
|
//Vector2 offset = (currentDelta0 + currentDelta1).normalized;
|
|
//offst在相机坐标系下的向量
|
|
Vector3 vector = Camera.main.transform.TransformDirection(offset.x, 0, offset.y);
|
|
vector.y = 0;
|
|
lookAt.localPosition += vector.normalized * Time.deltaTime * 30;
|
|
lookAt.localPosition = new Vector3(Mathf.Clamp(lookAt.localPosition.x, minVec.x, maxVec.x), lookAt.localPosition.y, Mathf.Clamp(lookAt.localPosition.z, minVec.z, maxVec.z));
|
|
//cameraFreeLook[index - 1].m_Orbits[0].m_Radius += vector.magnitude;
|
|
//cameraFreeLook[index - 1].m_Orbits[1].m_Radius += vector.magnitude;
|
|
//cameraFreeLook[index - 1].m_Orbits[2].m_Radius += vector.magnitude;
|
|
}
|
|
} |