Files
Main/Assets/Plugins/Code/UniScene/Camera/CameraControl.cs

577 lines
17 KiB
C#
Raw Permalink Normal View History

2025-01-25 04:38:09 +08:00
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
}
}