using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

//[Serializable] 由于class.struct不被Unity3d识别为可以Serialize的结构一般用于外部
//[SerializeField] 用于内部

[Serializable]
public struct CameraParameter
{
public bool limitXAngle;
public float minXAngle;
public float maxXAngle;

public bool limitYAngle;
public float minYAngle;
public float maxYAngle;

[Tooltip("敏感度")]
public float orbitSensitive;
[Tooltip("频率")]
public float mouseMoveRatio;

/// <summary>
///
/// </summary>
/// <param name="limitXAngle">是否是在限制x轴的范围</param>
/// <param name="minXAngle">最小x轴选择角度</param>
/// <param name="maxXAngle">最大x轴选择角度</param>
/// <param name="limitYAngle">是否是在限制y轴的范围</param>
/// <param name="minYAngle">最小x轴选择角度</param>
/// <param name="maxYAngle">最大x轴选择角度</param>
/// <param name="orbitSensitive">敏感度</param>
/// <param name="mouseMoveRatio">频率</param>
public CameraParameter(bool limitXAngle = true
, float minXAngle = 0f
, float maxXAngle = 80f
, bool limitYAngle = false
,float minYAngle=0f
,float maxYAngle=80f
,float orbitSensitive=10f
,float mouseMoveRatio = 0.3f)
{
this.limitXAngle = limitXAngle;
this.minXAngle = minXAngle;
this.maxXAngle = maxXAngle;
this.limitYAngle = limitYAngle;
this.minYAngle = minYAngle;
this.maxYAngle = maxYAngle;
this.orbitSensitive = orbitSensitive;
this.mouseMoveRatio = mouseMoveRatio;
}
}
public class RotateFinal : MonoBehaviour {

private Vector3 lastMousePos; //最近一次鼠标位置
private Vector3 targetEulerAngle; //目标角度
private Vector3 eulerAngle; //每次更新的角度

//public CameraParameter freeOrbitParameter; //自由轨道参数
public CameraParameter currentCameraParameter; //当前相机参数

public Transform cameraRootTf;
public Transform cameraTf;

private float cameraDistance;
private float targetCameraDistance;

private float lastTouchDistance;

public float minDistance = 5f;
public float maxDistance = 30f;
public float mouseScrollRadio = 1f;
public float zoomSensitive = 1f;

private Quaternion originalRotate;

//public float[] yMinAngles;
//public float[] yMaxAngles;
//public bool[] isAlreadyFire;

private void Start()
{
originalRotate = cameraRootTf.rotation;
cameraDistance = cameraTf.localPosition.z;
targetCameraDistance = cameraDistance;
//currentCameraParameter = freeOrbitParameter;
}

private void Update()
{
Oribit();
Zoom();
}

void Oribit()
{
if (Input.GetMouseButtonDown(0))
{
lastMousePos = Input.mousePosition;
}
if (Input.GetMouseButton(0))
{
targetEulerAngle.x += (-Input.mousePosition.y + lastMousePos.y) * currentCameraParameter.mouseMoveRatio;
targetEulerAngle.y += (Input.mousePosition.x - lastMousePos.x) * currentCameraParameter.mouseMoveRatio;
if (currentCameraParameter.limitXAngle)
{
targetEulerAngle.x = Mathf.Clamp(targetEulerAngle.x, currentCameraParameter.minXAngle, currentCameraParameter.maxXAngle);
}
if (currentCameraParameter.limitYAngle)
{
targetEulerAngle.y = Mathf.Clamp(targetEulerAngle.y, currentCameraParameter.minYAngle, currentCameraParameter.maxYAngle);
}
lastMousePos = Input.mousePosition;
}
if (Input.touchCount<2) //如果触碰的小于2时,可用在触摸屏上
{
eulerAngle = Vector3.Lerp(eulerAngle, targetEulerAngle, Time.fixedDeltaTime * currentCameraParameter.orbitSensitive);
cameraRootTf.rotation = originalRotate*Quaternion.Euler(eulerAngle);
}
}
/*
// 手指刚触摸到屏幕的时候
Input.GetTouch(0).phase == TouchPhase.Began;
// 手指在屏幕上移动
Input.GetTouch(0).phase == TouchPhase.Moved;
// 手指触摸屏幕,但并未移动
Input.GetTouch(0).phase == TouchPhase.Stationary;
// 手指从屏幕上移开,这是一个触控的最后状态
Input.GetTouch(0).phase == TouchPhase.Ended;
// 系统取消追踪触控。这常发生在用户把屏幕放到脸上或者同时触控超过了5根手指,同样也是触控的最后一个状态
Input.GetTouch(0).phase == TouchPhase.Canceled;
*/
private void Zoom()
{
if (Input.touchCount<2)
{
if (Input.GetAxis("Mouse ScrollWheel")!=0)
{
cameraDistance = -cameraTf.localPosition.z; //有滑动就减去得到滑动了距离
targetCameraDistance = cameraDistance - Input.GetAxis("Mouse ScrollWheel") * cameraDistance * mouseScrollRadio;
targetCameraDistance = Mathf.Clamp(targetCameraDistance, minDistance, maxDistance);
}
}
else
{
if (Input.GetTouch(1).phase==TouchPhase.Began)
{
lastTouchDistance = Vector2.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position);
}
if (Input.GetTouch(1).phase==TouchPhase.Moved||Input.GetTouch(0).phase==TouchPhase.Moved)
{
cameraDistance = -cameraTf.localPosition.z;
targetCameraDistance = cameraDistance - (Vector2.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position) - lastTouchDistance) * mouseScrollRadio;
lastMousePos = Input.mousePosition;
}
}
if (Mathf.Abs(targetCameraDistance-cameraDistance)>0.1f)
{
cameraDistance = Mathf.Lerp(cameraDistance, targetCameraDistance, Time.fixedDeltaTime * zoomSensitive);
cameraTf.localPosition = new Vector3(0, 0, -cameraDistance);
}
}
}