using System;
using System.Linq;
using UnityEngine;
using UnityEngine.PlayerLoop;
public class CameraRotate : MonoBehaviour
{
private CameraController cameraController;
private class ZoomData
{
public float xAngle;
public float yAngle;
//public float distance;
public ZoomData()
{
}
public ZoomData(float xAngle, float yAngle)
{
//this.distance = distance;
this.xAngle = xAngle;
this.yAngle = yAngle;
}
}
private void Start()
{
cameraController = UITools.GetOrCreateComponent<CameraController>(this.gameObject);
}
public void UpdateDo()
{
CheckOpenCameraRotate();
RotateCamera();
if (hadInitZoom)
{
UpdateZoom();
UpdataCameraFollow();
}
}
ZoomData curZoomData = new ZoomData();
private float followDistance;
private float xAngle;
private float yAngle;
private float tmp1;
private float tmp2;
public float zoomAngleSmoothing=0.5f;
public float zoomParam = 2f;
public float yAngleRightLimit = 30;
public float yAngleLeftLimit=10;
public float xAngleLimitUp=30;
public float xAngleLimitDown=10;
private void HandleInput(float offsetX,float offsetY)
{
curZoomData.xAngle += offsetY*zoomParam;
if (curZoomData.xAngle > xAngleLimitUp)
{
curZoomData.xAngle = xAngleLimitUp;
}
else if (curZoomData.xAngle < xAngleLimitDown)
{
curZoomData.xAngle = xAngleLimitDown;
}
curZoomData.yAngle += offsetX*zoomParam;
if (curZoomData.yAngle > yAngleLeftLimit)
{
curZoomData.yAngle = yAngleLeftLimit;
}
else if (curZoomData.yAngle < yAngleRightLimit)
{
curZoomData.yAngle = yAngleRightLimit;
}
Debug.Log("HandleInput:"+curZoomData.yAngle);
}
private bool hadInitZoom = false;
private void InitZoom()
{
this.followDistance = Vector3.Distance(this.transform.position, sceneCenterPoint);
this.xAngle = this.transform.eulerAngles.x;
this.yAngle = this.transform.eulerAngles.y;
this.curZoomData.xAngle = this.xAngle;
this.curZoomData.yAngle = this.yAngle;
yAngleRightLimit = this.curZoomData.yAngle - yAngleRightLimit;
yAngleLeftLimit = this.curZoomData.yAngle + yAngleLeftLimit;
xAngleLimitDown = this.curZoomData.xAngle - xAngleLimitDown;
xAngleLimitUp = this.curZoomData.xAngle + xAngleLimitUp;
hadInitZoom = true;
}
private void UpdateZoom()
{
ZoomData data = this.curZoomData;
if (Mathf.Abs(data.yAngle - this.yAngle) > 0.01f||Mathf.Abs(data.xAngle - this.xAngle) > 0.01f)
{
this.xAngle = Mathf.SmoothDampAngle(this.xAngle, data.xAngle, ref tmp1, zoomAngleSmoothing);
this.yAngle = Mathf.SmoothDampAngle(this.yAngle, data.yAngle, ref tmp2, zoomAngleSmoothing);
Debug.Log("UpdateZoom:"+yAngle);
}
}
private void UpdataCameraFollow()
{
Quaternion quaternion = Quaternion.Euler(this.xAngle, this.yAngle, 0);
Vector3 dPos = sceneCenterPoint + (quaternion * Vector3.back).normalized * followDistance;
this.transform.rotation = quaternion;//固定旋转,否则由于缓动,摄像机旋转会变化
this.transform.position = dPos;
//Debug.Log("UpdataCameraFollow:"+this.transform.rotation);
}
//------------------------检测是否开启相机旋转---------------------------------
public string cameraFightAnimName
{
get
{
return "Fight";
}
}
private int cameraFightAnimHash;
private Animator cameraAnimator;
private bool checkCameraRotate;
public void SetCheckCameraRotate(bool check)
{
checkCameraRotate = check;
if (checkCameraRotate)
{
GameObject sceneRoot = GameObject.Find("SceneRoot");
if (sceneRoot != null)
{
cameraAnimator = sceneRoot.transform.GetComponent<Animator>();
cameraFightAnimHash = Animator.StringToHash(this.cameraFightAnimName);
}
}
else
{
cameraAnimator = null;
}
}
void CheckOpenCameraRotate()
{
if (!checkCameraRotate) return;
if (cameraAnimator!=null && this.cameraAnimator.GetCurrentAnimatorStateInfo(0).shortNameHash==cameraFightAnimHash)
{
checkCameraRotate = false;
originCameraPos = this.transform.position;
originCameraAngles.x = this.transform.eulerAngles.x;
originCameraAngles.y = this.transform.eulerAngles.y;
lastCameraPos = this.transform.position;
lastCameraAngles = this.transform.eulerAngles;
OpenRotateCamera(true);
}
}
//-----------------------------------------------------
//------用户滑动屏幕,相机围绕中心点旋转----------
public Transform centerTrs;
private bool canRotateCamera;
[SerializeField]
private float rotateSpeed;//旋转速度
[SerializeField]
private float limitAnglesX;//上下旋转角度限制
[SerializeField]
private float limitAnglesYLeft;//左旋转角度限制
[SerializeField]
private float limitAnglesYRight;//右旋转角度限制
public Vector3 sceneCenterPoint;
private float maxEulerAnglesX;
private float minEulerAnglesX;
private float maxEulerAnglesY;
private float minEulerAnglesY;
private Vector3 originCameraPos;
private Vector3 originCameraAngles;
public Vector3 lastCameraPos;
public Vector3 lastCameraAngles;
private bool hadInitCfg;
void InitCfg()
{
if (hadInitCfg) return;
hadInitCfg = true;
int rotateSpeedId = 1000101;
int rotateAngleXId = 1000102;
int limitAnglesYLeftId = 1000103;
int limitAnglesYRightId = 1000104;
ConfigData.ClientParams info = ConfigManager.GetConfigData_ItemById<ConfigData.ClientParams>(rotateSpeedId);
if (info==null || !float.TryParse(info.value, out rotateSpeed))
{
rotateSpeed = 1;
}
info = ConfigManager.GetConfigData_ItemById<ConfigData.ClientParams>(rotateAngleXId);
if (info==null || !float.TryParse(info.value, out limitAnglesX))
{
limitAnglesX = 15;
}
info = ConfigManager.GetConfigData_ItemById<ConfigData.ClientParams>(limitAnglesYLeftId);
if (info==null || !float.TryParse(info.value, out limitAnglesYLeft))
{
limitAnglesYLeft = 15;
}
info = ConfigManager.GetConfigData_ItemById<ConfigData.ClientParams>(limitAnglesYRightId);
if (info==null || !float.TryParse(info.value, out limitAnglesYRight))
{
limitAnglesYRight = 15;
}
}
void InitRecordCamera()
{
InitCfg();
}
public void OpenRotateCamera(bool open)
{
InitRecordCamera();
cameraController.IsUpdateCameraInBindTrans = !open;
CanRotateCamera(open);
AngleLimit();
GameObject go = GameObject.Find("Cam_Pos");
if (go != null)
{
sceneCenterPoint = go.transform.position;
}
else
{
sceneCenterPoint = new Vector3(8.93f,0,5.11f);
}
InitZoom();
}
public void CanRotateCamera(bool can)
{
canRotateCamera = can;
}
private Vector3 oldMousePos;
private Vector3 newMousePos;
private bool isPressFirst=false;
[SerializeField]
private float pressParams=0.02f;
void RotateCamera()
{
if (!canRotateCamera || cameraController.IsUpdateCameraInBindTrans)
{
return;
}
if (Input.GetMouseButton(0))
{
if (!isPressFirst)
{
oldMousePos = Input.mousePosition;
isPressFirst = true;
return;
}
else
{
newMousePos = Input.mousePosition;
isPressFirst = false;
}
float mouseX = 0;
float mouseY = 0;
mouseX = newMousePos.x - oldMousePos.x;
mouseY = newMousePos.y - oldMousePos.y;
mouseX *= pressParams;
mouseY *= pressParams;
if (Mathf.Abs(mouseX) > 0.01f || Mathf.Abs(mouseY) > 0.01f)
{
Debug.Log("测试:mouseX:"+mouseX+",mouseY:"+mouseY+",XX:"+Input.GetAxis("Mouse X")+",YY:"+Input.GetAxis("Mouse Y"));
//HandleInput( Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
HandleInput(mouseX, mouseY);
//RotateAround(mouseX,mouseY);
}
}
else
{
if(isPressFirst)
isPressFirst = false;
}
}
void RotateAround(float mouseX,float mouseY)
{
// float mouseX = Input.GetAxis("Mouse X");
// float mouseY = Input.GetAxis("Mouse Y");
Vector3 rotateDir = Vector3.up;
float rotateValue = 0;
//左右旋转
float rotateAngleY = mouseX * rotateSpeed;
rotateValue = rotateAngleY;
transform.RotateAround(sceneCenterPoint, rotateDir, rotateValue);
float hadRotateAngleY = transform.eulerAngles.y + rotateAngleY;
if (rotateAngleY>0 &&
hadRotateAngleY<180 &&
hadRotateAngleY > maxEulerAnglesY)
{
rotateValue = rotateAngleY-(hadRotateAngleY-maxEulerAnglesY);
}
else if(rotateAngleY<0 &&
hadRotateAngleY>180 &&
hadRotateAngleY< minEulerAnglesY)
{
rotateValue = rotateAngleY+(minEulerAnglesY-hadRotateAngleY);
}
transform.RotateAround(sceneCenterPoint, rotateDir, rotateValue);
//垂直旋转
rotateDir = transform.right;
float rotateAngleX = -mouseY * rotateSpeed;
rotateValue = rotateAngleX;
transform.RotateAround(sceneCenterPoint, rotateDir, rotateValue);
float hadRotateAngleX = transform.eulerAngles.x + rotateAngleX;
if (rotateAngleX > 0 &&
maxEulerAnglesX <= 90 &&
hadRotateAngleX < 180 &&
hadRotateAngleX >= maxEulerAnglesX)
{
rotateValue = rotateAngleX-(hadRotateAngleX - maxEulerAnglesX);
}
else if (rotateAngleX > 0 &&
maxEulerAnglesX <= 90 &&
transform.eulerAngles.z>=179 &&
hadRotateAngleX <= maxEulerAnglesX)
{
rotateValue = rotateAngleX-(maxEulerAnglesX - hadRotateAngleX);
}
else if (rotateAngleX > 0 &&
maxEulerAnglesX > 90 &&
transform.eulerAngles.z>=179 &&
hadRotateAngleX < 180-maxEulerAnglesX)
{
rotateValue = rotateAngleX-( (180-maxEulerAnglesX)-hadRotateAngleX);
}
else if (rotateAngleX < 0 &&
hadRotateAngleX < 180 &&
minEulerAnglesX < 180 &&
hadRotateAngleX < minEulerAnglesX)
{
rotateValue = rotateAngleX+(minEulerAnglesX-hadRotateAngleX);
}
else if (rotateAngleX < 0 &&
hadRotateAngleX>180 &&
hadRotateAngleX <360- minEulerAnglesX)
{
rotateValue = rotateAngleX+((360-minEulerAnglesX)-hadRotateAngleX);
}
else if (rotateAngleX < 0 &&
hadRotateAngleX > 180 &&
hadRotateAngleX < minEulerAnglesX)
{
rotateValue = rotateAngleX-(hadRotateAngleX-minEulerAnglesX);
}
transform.RotateAround(sceneCenterPoint, rotateDir, rotateValue);
lastCameraPos = this.transform.position;
lastCameraAngles = this.transform.eulerAngles;
}
void AngleLimit()
{
maxEulerAnglesY = originCameraAngles.y + limitAnglesYLeft;
if (maxEulerAnglesY >= 360)
{
maxEulerAnglesY = maxEulerAnglesY- 360;
}
else if (maxEulerAnglesY<0)
{
maxEulerAnglesY = 360 + maxEulerAnglesY;
}
minEulerAnglesY = originCameraAngles.y - limitAnglesYRight;
if (minEulerAnglesY >= 360)
{
minEulerAnglesY = minEulerAnglesY- 360;
}
else if (minEulerAnglesY<0)
{
minEulerAnglesY = 360 + minEulerAnglesY;
}
maxEulerAnglesX = originCameraAngles.x+ limitAnglesX;
if (maxEulerAnglesX >= 360)
{
maxEulerAnglesX = maxEulerAnglesX- 360;
}
else if (maxEulerAnglesX<0)
{
maxEulerAnglesX = 360 + maxEulerAnglesX;
}
minEulerAnglesX = originCameraAngles.x - limitAnglesX;
if (minEulerAnglesX >= 360)
{
minEulerAnglesX = minEulerAnglesX- 360;
}
else if (minEulerAnglesX<0)
{
minEulerAnglesX = 360 + minEulerAnglesX;
}
}
//----------------------------------------------------------------------------------------
TweenRotation tr;
public void TweenRotation(Vector3 to,float duration,float delay=0)
{
tr = UITools.GetOrCreateComponent<TweenRotation>(this.gameObject);
//tr.delay = delay;
tr.method = UITweener.Method.Linear;
tr.@from = transform.eulerAngles;
tr.to = to;
tr.duration = duration;
}
}