577 lines
17 KiB
C#
577 lines
17 KiB
C#
using UnityEngine;
|
|
using Thousandto.Core.Asset;
|
|
using EventManager = UnityEngine.Gonbest.MagicCube.EventManager;
|
|
using CoreEventDefine = UnityEngine.Gonbest.MagicCube.CoreEventDefine;
|
|
|
|
namespace Thousandto.Plugins.Common.UniScene
|
|
{
|
|
//摄像机控制器
|
|
public class CameraControl : MonoBehaviour
|
|
{
|
|
#region//私有变量
|
|
//锁定的目标
|
|
private Transform _targetTrans = null;
|
|
//当前pitch
|
|
[SerializeField]
|
|
private float _curPitch = 0f;
|
|
//当前yaw
|
|
[SerializeField]
|
|
private float _curYaw = 0f;
|
|
//当前跟随距离
|
|
private float _curDis = 0f;
|
|
//当前Y轴偏移量
|
|
[SerializeField]
|
|
private float _curOffsetY = 1.5f;
|
|
//当前X轴偏移量
|
|
[SerializeField]
|
|
private float _curOffsetX = 0f;
|
|
//当前fov
|
|
[SerializeField]
|
|
private float _curFov = 0f;
|
|
//是否锁定
|
|
private bool _isLock = false;
|
|
//
|
|
private Transform _transFormInst = null;
|
|
|
|
RayCheckModel _rayCheckModel = null;
|
|
private Camera _curCamera = null;
|
|
#endregion
|
|
|
|
#region//动画变量
|
|
//是否正在播放动画
|
|
private bool _isPlayAnim = false;
|
|
//动画曲线
|
|
private AnimationCurve _animCurve = null;
|
|
//动画时间
|
|
private float _animMaxTime = 0.001f;
|
|
//动画计时器
|
|
private float _animTimer = 0f;
|
|
//原pitch
|
|
private float _oriPitch = 0f;
|
|
//目标picth
|
|
private float _tarPitch = 0f;
|
|
//原yaw
|
|
private float _oriYaw = 0f;
|
|
//目标yaw
|
|
private float _tarYaw = 0f;
|
|
//原dis
|
|
private float _oriDis = 0f;
|
|
//原fov
|
|
private float _oriFov = 0f;
|
|
//目标dis
|
|
[SerializeField]
|
|
private float _tarDis = 0f;
|
|
//原y轴偏移量
|
|
private float _oriOffsetY = 0f;
|
|
//目标y轴偏移量
|
|
private float _tarOffsetY = 0f;
|
|
//原x轴偏移量
|
|
private float _oriOffsetX = 0f;
|
|
//目标x轴偏移量
|
|
private float _tarOffsetX = 0f;
|
|
//目标fov
|
|
private float _tarFov = 0f;
|
|
#endregion
|
|
|
|
#region//属性
|
|
public Transform TargetTrans
|
|
{
|
|
get
|
|
{
|
|
return _targetTrans;
|
|
}
|
|
}
|
|
|
|
//当前摄像机
|
|
public Camera CurCamera
|
|
{
|
|
get {
|
|
return _curCamera;
|
|
}
|
|
set
|
|
{
|
|
_curCamera = value;
|
|
|
|
}
|
|
}
|
|
|
|
//当前pitch
|
|
public float CurPitch
|
|
{
|
|
get
|
|
{
|
|
return _curPitch;
|
|
}
|
|
set
|
|
{
|
|
_curPitch = value;
|
|
}
|
|
}
|
|
//当前yaw
|
|
public float CurYaw
|
|
{
|
|
get
|
|
{
|
|
return _curYaw;
|
|
}
|
|
set
|
|
{
|
|
_curYaw = value;
|
|
}
|
|
}
|
|
//当前跟随距离
|
|
public float CurDis
|
|
{
|
|
get
|
|
{
|
|
return _curDis;
|
|
}
|
|
set
|
|
{
|
|
_curDis = value;
|
|
_tarDis = value;
|
|
//Debug.Log("fix yy CurDis 333 " + value.ToString());
|
|
}
|
|
}
|
|
//当前Y轴偏移量
|
|
public float CurOffsetY
|
|
{
|
|
get
|
|
{
|
|
return _curOffsetY;
|
|
}
|
|
set
|
|
{
|
|
_curOffsetY = value;
|
|
_tarOffsetY = value;
|
|
_oriOffsetY = value;
|
|
}
|
|
}
|
|
|
|
//当前X轴偏移量
|
|
public float CurOffsetX
|
|
{
|
|
get
|
|
{
|
|
return _curOffsetX;
|
|
}
|
|
set
|
|
{
|
|
_curOffsetX = value;
|
|
}
|
|
}
|
|
|
|
//当前fov
|
|
public float CurFov
|
|
{
|
|
get
|
|
{
|
|
return _curFov;
|
|
}
|
|
set
|
|
{
|
|
_curFov = value;
|
|
}
|
|
}
|
|
//是否锁定
|
|
public bool IsLock
|
|
{
|
|
get
|
|
{
|
|
return _isLock;
|
|
}
|
|
}
|
|
public Transform TransFormInst
|
|
{
|
|
get
|
|
{
|
|
if (_transFormInst == null)
|
|
{
|
|
_transFormInst = transform;
|
|
}
|
|
return _transFormInst;
|
|
}
|
|
}
|
|
|
|
public float TarDis
|
|
{
|
|
get
|
|
{
|
|
return _tarDis;
|
|
}
|
|
set
|
|
{
|
|
_tarDis = value;
|
|
//Debug.Log("fix yy TarDis " + value.ToString());
|
|
}
|
|
}
|
|
|
|
private RayCheckModel RayCheckModel
|
|
{
|
|
get
|
|
{
|
|
if(_rayCheckModel == null)
|
|
{
|
|
_rayCheckModel = new RayCheckModel();
|
|
}
|
|
return _rayCheckModel;
|
|
}
|
|
}
|
|
//自由操控模式,进入此模式后摄像机不会做任何限制
|
|
public bool FreeMode { get; set; }
|
|
//是否正在播放动画
|
|
public bool IsPlayAnim
|
|
{
|
|
get
|
|
{
|
|
return _isPlayAnim;
|
|
}
|
|
}
|
|
//特写高度
|
|
public float FeatureHeight { get; set; }
|
|
#endregion
|
|
|
|
#region//私有函数
|
|
|
|
private void UpdateAnim(float dt)
|
|
{
|
|
if (_isPlayAnim)
|
|
{
|
|
_animTimer += dt;
|
|
float lerpValue = 0f;
|
|
if (_animMaxTime <= 0f)
|
|
{
|
|
lerpValue = 1f;
|
|
_isPlayAnim = false;
|
|
}
|
|
else if (_animTimer <= _animMaxTime)
|
|
{
|
|
lerpValue = _animTimer / _animMaxTime;
|
|
if (_animCurve != null)
|
|
{
|
|
lerpValue = _animCurve.Evaluate(lerpValue);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lerpValue = 1f;
|
|
_isPlayAnim = false;
|
|
}
|
|
|
|
if(_isPlayAnim)
|
|
{
|
|
_curPitch = Mathf.Lerp(_oriPitch, _tarPitch, lerpValue);
|
|
_curYaw = Mathf.Lerp(_oriYaw, _tarYaw, lerpValue);
|
|
_curDis = Mathf.Lerp(_oriDis, _tarDis, lerpValue);
|
|
_curOffsetY = Mathf.Lerp(_oriOffsetY, _tarOffsetY, lerpValue);
|
|
_curOffsetX = Mathf.Lerp(_oriOffsetX, _tarOffsetX, lerpValue);
|
|
_curFov = Mathf.Lerp(_oriFov, _tarFov, lerpValue);
|
|
}
|
|
else
|
|
{
|
|
_curPitch = _tarPitch;
|
|
_curYaw = _tarYaw;
|
|
_curDis = _tarDis;
|
|
_curOffsetY = _tarOffsetY;
|
|
_curOffsetX = _tarOffsetX;
|
|
_curFov = _tarFov;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
//屏蔽掉射线处理
|
|
//RayCheckModel.UpdateRay(TransFormInst);
|
|
if (_targetTrans == null)
|
|
return;
|
|
if (FreeMode)
|
|
{
|
|
var targetPos = _targetTrans.position + Vector3.up * _curOffsetY;
|
|
Quaternion rot = Quaternion.Euler(CurPitch, CurYaw, 0f);
|
|
var selfPos = targetPos - rot * Vector3.forward * _curDis;
|
|
if (_curOffsetX != 0)
|
|
{
|
|
var dir = (_targetTrans.position - selfPos);
|
|
dir.y = 0;
|
|
dir = Quaternion.AngleAxis(90, Vector3.up) * dir;
|
|
dir = dir.normalized;
|
|
|
|
targetPos = targetPos + dir * _curOffsetX;
|
|
selfPos = targetPos - rot * Vector3.forward * _curDis;
|
|
}
|
|
|
|
if (CurCamera != null && CurCamera.fieldOfView != _curFov)
|
|
{
|
|
CurCamera.fieldOfView = _curFov;
|
|
}
|
|
|
|
TransFormInst.position = selfPos;
|
|
TransFormInst.rotation = rot;
|
|
}
|
|
else
|
|
{
|
|
var useOffsetY = _curOffsetY;
|
|
if (_isPlayAnim)
|
|
{
|
|
UpdateAnim(Time.deltaTime);
|
|
}
|
|
else
|
|
{
|
|
//规范yaw值
|
|
if (_curYaw > 0)
|
|
{
|
|
_curYaw = _curYaw % 360f;
|
|
if (_curYaw > 180f)
|
|
{
|
|
_curYaw = _curYaw - 360f;
|
|
}
|
|
}
|
|
else if (_curYaw < 0f)
|
|
{
|
|
_curYaw = _curYaw % 360;
|
|
if (_curYaw < -180f)
|
|
{
|
|
_curYaw = _curYaw + 360f;
|
|
}
|
|
}
|
|
|
|
if (_isLock)
|
|
{
|
|
_curYaw = Mathf.Clamp(_curYaw, CameraControlDefine.MinYaw, CameraControlDefine.MaxYaw);
|
|
|
|
//规范跟随距离
|
|
_tarDis = Mathf.Clamp(_tarDis, CameraControlDefine.CurMinDis, CameraControlDefine.CurMaxDis);
|
|
|
|
var halfMaxDis = (CameraControlDefine.CurMaxDis - CameraControlDefine.CurMinDis) / 2f;
|
|
if (_curDis >= halfMaxDis)
|
|
{
|
|
_curPitch = CameraControlDefine.LockPitch;
|
|
useOffsetY = _curOffsetY;
|
|
}
|
|
else
|
|
{
|
|
_curPitch = Mathf.Lerp(6f, CameraControlDefine.LockPitch, (_curDis - CameraControlDefine.CurMinDis) / halfMaxDis);
|
|
useOffsetY = Mathf.Lerp(FeatureHeight, _curOffsetY, (_curDis - CameraControlDefine.CurMinDis) / halfMaxDis);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//规范picth值
|
|
_curPitch = Mathf.Clamp(_curPitch, CameraControlDefine.ConstMinPitch, CameraControlDefine.ConstMaxPitch);
|
|
_tarDis = Mathf.Clamp(_tarDis, CameraControlDefine.CurMinDis, CameraControlDefine.ConstMaxFlowDis-3);
|
|
//fix yy:新增 拉近视角相机跟随到上半身
|
|
useOffsetY = Mathf.Lerp(FeatureHeight, _curOffsetY, (_curDis - CameraControlDefine.CurMinDis) / CameraControlDefine.CurMaxDis);
|
|
}
|
|
}
|
|
|
|
float oldDis = _curDis;
|
|
if (_curDis != _tarDis)
|
|
{
|
|
if (_curDis > _tarDis)
|
|
{
|
|
_curDis -= Time.deltaTime * CameraControlDefine.DisChangeSpeed;
|
|
if (_curDis <= _tarDis)
|
|
{
|
|
_curDis = _tarDis;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_curDis += Time.deltaTime * CameraControlDefine.DisChangeSpeed;
|
|
if (_curDis >= _tarDis)
|
|
{
|
|
_curDis = _tarDis;
|
|
}
|
|
}
|
|
}
|
|
|
|
var targetPos = _targetTrans.position + Vector3.up * useOffsetY;
|
|
Quaternion rot = Quaternion.Euler(CurPitch, CurYaw, 0f);
|
|
var selfPos = targetPos - rot * Vector3.forward * _curDis;
|
|
if (_curOffsetX != 0)
|
|
{
|
|
var dir = (_targetTrans.position - selfPos);
|
|
dir.y = 0;
|
|
dir = Quaternion.AngleAxis(90, Vector3.up) * dir;
|
|
dir = dir.normalized;
|
|
|
|
targetPos = targetPos + dir * _curOffsetX;
|
|
selfPos = targetPos - rot * Vector3.forward * _curDis;
|
|
}
|
|
|
|
|
|
//锁定模式下不做摄像机碰撞
|
|
if (!_isLock)
|
|
{
|
|
if (Physics.CheckSphere(targetPos, 0.1f, LayerUtils.Terrain_Mask))
|
|
{
|
|
selfPos = targetPos;
|
|
_curDis = 0f;
|
|
}
|
|
else
|
|
{
|
|
RaycastHit hit;
|
|
Ray ray = new Ray(targetPos, selfPos - targetPos);
|
|
if (Physics.SphereCast(ray, 0.5f, out hit, _curDis, LayerUtils.Terrain_Mask))
|
|
{
|
|
selfPos = targetPos - rot * Vector3.forward * hit.distance;
|
|
_curDis = hit.distance;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(CurCamera != null && CurCamera.fieldOfView != _curFov)
|
|
{
|
|
CurCamera.fieldOfView = _curFov;
|
|
}
|
|
|
|
TransFormInst.position = selfPos;
|
|
TransFormInst.rotation = rot;
|
|
|
|
if (oldDis != _curDis)
|
|
{
|
|
EventManager.SharedInstance.PushFixEvent(CoreEventDefine.EID_EVENT_CAMERAFOLLOWDIS_CHANGED, _curDis);
|
|
}
|
|
}
|
|
|
|
if (AudioPlayer.ChannelManager.RootGo != null)
|
|
{
|
|
Transform trans = AudioPlayer.ChannelManager.RootGo.transform;
|
|
trans.position = TransFormInst.position;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region//公有函数
|
|
|
|
//设置射线检测
|
|
public void SetRayCheckModel(bool isenable)
|
|
{
|
|
RayCheckModel.IsEnable = isenable;
|
|
}
|
|
|
|
//设置射线检测Alpha变化值
|
|
public void SetRayAlpha(float alpha)
|
|
{
|
|
RayCheckModel.Alpha = alpha;
|
|
}
|
|
|
|
//设置射线检测变化时间
|
|
public void SetRayTime(float offsettime)
|
|
{
|
|
RayCheckModel.ChangeTime = offsettime;
|
|
}
|
|
|
|
//设置跟随目标
|
|
public void SetTarget(Transform target)
|
|
{
|
|
if (target != null)
|
|
{
|
|
_targetTrans = target;
|
|
}
|
|
}
|
|
//改变锁定状态
|
|
public void ChangeLockState(bool state)
|
|
{
|
|
_isLock = state;
|
|
if (_isLock)
|
|
{
|
|
SetFarViewState(CameraControlDefine.IsFarView);
|
|
}
|
|
else
|
|
{
|
|
PlayAnim(CameraControlDefine.ConstDefaultPitch, CameraControlDefine.ConstDefaultYaw, CameraControlDefine.ConstDefaultFlowDis, _curOffsetX, _curOffsetY, CameraControlDefine.CurFov, 0.5f);
|
|
}
|
|
EventManager.SharedInstance.PushFixEvent(CoreEventDefine.EID_EVENT_CAMERALOCKSTATE_CHANGED, _isLock);
|
|
}
|
|
|
|
public void SetFarViewState(bool state)
|
|
{
|
|
CameraControlDefine.IsFarView = state;
|
|
_curYaw = CameraControlDefine.LockYaw;
|
|
_curPitch = CameraControlDefine.LockPitch;
|
|
_curDis = CameraControlDefine.CurMaxDis - 1f;
|
|
PlayAnim(CameraControlDefine.LockPitch, CameraControlDefine.LockYaw, CameraControlDefine.CurMaxDis, _curOffsetX, _curOffsetY, CameraControlDefine.CurFov, 0.5f);
|
|
|
|
}
|
|
//播放运动动画
|
|
public void PlayAnim(float tarPitch, float tarYaw, float tarDis, float tarOffsetX, float tarOffsetY, float tarFov, float animTime, AnimationCurve curve = null)
|
|
{
|
|
//规范yaw值 -180到180
|
|
if (_curYaw > 0)
|
|
{
|
|
_curYaw = _curYaw % 360f;
|
|
if (_curYaw > 180f)
|
|
{
|
|
_curYaw = _curYaw - 360f;
|
|
}
|
|
}
|
|
else if (_curYaw < 0f)
|
|
{
|
|
_curYaw = _curYaw % 360;
|
|
if (_curYaw < -180f)
|
|
{
|
|
_curYaw = _curYaw + 360f;
|
|
}
|
|
}
|
|
|
|
//规范yaw值 -180到180
|
|
if (tarYaw > 0)
|
|
{
|
|
tarYaw = tarYaw % 360f;
|
|
if (tarYaw > 180f)
|
|
{
|
|
tarYaw = tarYaw - 360f;
|
|
}
|
|
}
|
|
else if (tarYaw < 0f)
|
|
{
|
|
tarYaw = tarYaw % 360;
|
|
if (tarYaw < -180f)
|
|
{
|
|
tarYaw = tarYaw + 360f;
|
|
}
|
|
}
|
|
|
|
var moveAbs = Mathf.Abs(tarYaw - CurYaw);
|
|
var moveAbs2 = 360f - moveAbs;
|
|
if (moveAbs2 < moveAbs)
|
|
{
|
|
if (tarYaw > CurYaw)
|
|
{
|
|
tarYaw = CurYaw - moveAbs2;
|
|
}
|
|
else
|
|
{
|
|
tarYaw = CurYaw + moveAbs2;
|
|
}
|
|
}
|
|
|
|
_oriPitch = _curPitch;
|
|
_oriYaw = _curYaw;
|
|
_oriDis = _curDis;
|
|
_oriOffsetX = _curOffsetX;
|
|
_oriOffsetY = _curOffsetY;
|
|
_oriFov = _curFov;
|
|
if(_oriFov <= 0)
|
|
{
|
|
_oriFov = _tarFov;
|
|
}
|
|
|
|
_tarPitch = tarPitch;
|
|
_tarYaw = tarYaw;
|
|
_tarDis = tarDis;
|
|
_tarOffsetX = tarOffsetX;
|
|
_tarOffsetY = tarOffsetY;
|
|
_tarFov = tarFov;
|
|
_animMaxTime = animTime;
|
|
_animCurve = curve;
|
|
_isPlayAnim = true;
|
|
_animTimer = 0f;
|
|
UpdateAnim(0f);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|