using UnityEngine;
|
using System.Collections;
|
|
public class CameraController : MonoBehaviour
|
{
|
public static CameraController Instance;
|
|
[HideInInspector]
|
public bool AcceptInput = true;
|
|
public Transform Node;
|
public Camera CameraObject;
|
public Transform LookAtTarget;
|
|
public Camera MaskCamera;
|
public GameObject Mask;
|
private Animation m_Animation;
|
|
public float lookHeight = 0;
|
|
public float Distance = 10.0f;
|
public float MinDistance = 2.0f;
|
public float MaxDistance = 10.0f;
|
|
public float rotationX = 0.0f;
|
public float rotationY = 35.0f;
|
public float rotationSpeed = 5.0f;
|
|
public float MinRotationY = 35.0f;
|
public float MaxRotationY = 50.0f;
|
|
public float MoveDamping = 0.1f;
|
public float RotationDamping = 0.1f;
|
public float ZoomDamping = 0.3f;
|
|
private float m_CurrentRotationY;
|
private float m_CurrentRotationX;
|
private Vector3 m_MoveVelocity = Vector3.zero;
|
private float m_ZoomVelocity = 0;
|
|
[HideInInspector]
|
public float originalDistance = 0;
|
[HideInInspector]
|
public float originalRotX = 0;
|
[HideInInspector]
|
public float originalRotY = 0;
|
[HideInInspector]
|
public float sceneDistance = 0;
|
public bool IsInGame = false;
|
public bool IsPlayingAnim
|
{
|
get; private set;
|
}
|
|
private GameObject camerePrefab; // 登出的时候需要卸载场景摄像头
|
|
void Awake()
|
{
|
Instance = this;
|
CameraManager.sceneCamera = CameraObject;
|
m_Animation = GetComponent<Animation>();
|
sceneDistance = originalDistance = Distance;
|
originalRotX = rotationX;
|
originalRotY = rotationY;
|
DontDestroyOnLoad(this);
|
|
SystemSetting.Instance.qualityLevelChangeEvent += QualityLevelChanged;
|
}
|
|
public void SetInGame(bool _active)
|
{
|
IsInGame = _active;
|
StartCoroutine(WaitForSeconds(_active));
|
}
|
|
public void SetcamerePrefab(GameObject prefab)
|
{
|
camerePrefab = prefab;
|
}
|
|
|
IEnumerator WaitForSeconds(bool _active)
|
{
|
yield return WaitingForSecondConst.WaitMS200;
|
Node.SetActive(_active);
|
if (!_active && camerePrefab != null)
|
{
|
Destroy(camerePrefab);
|
camerePrefab = null;
|
Instance = null;
|
}
|
}
|
public void QualityLevelChanged()
|
{
|
if (CameraObject == null)
|
{
|
return;
|
}
|
|
if (SystemSetting.Instance.GetCurrentQualityLevel() == GameQuality.Low)
|
{
|
CameraObject.cullingMask |= LayerUtility.BattleEffectLowMask;
|
CameraObject.cullingMask &= ~LayerUtility.BattleEffectMidMask;
|
CameraObject.cullingMask &= ~LayerUtility.BattleEffectHighMask;
|
}
|
else if (SystemSetting.Instance.GetCurrentQualityLevel() == GameQuality.Medium)
|
{
|
CameraObject.cullingMask |= LayerUtility.BattleEffectLowMask;
|
CameraObject.cullingMask |= LayerUtility.BattleEffectMidMask;
|
CameraObject.cullingMask &= ~LayerUtility.BattleEffectHighMask;
|
}
|
else if (SystemSetting.Instance.GetCurrentQualityLevel() == GameQuality.High)
|
{
|
CameraObject.cullingMask |= LayerUtility.BattleEffectLowMask;
|
CameraObject.cullingMask |= LayerUtility.BattleEffectMidMask;
|
CameraObject.cullingMask |= LayerUtility.BattleEffectHighMask;
|
}
|
}
|
|
public void PlayAnimationClip(string name)
|
{
|
AnimationClip _clip = BuiltInLoader.LoadAnimationClip(name);
|
if (_clip != null)
|
{
|
IsPlayingAnim = true;
|
m_Animation.AddClip(_clip, "start_show");
|
m_Animation.Play("start_show");
|
}
|
}
|
|
public void PlayAnimationClipUnLimit(string name)
|
{
|
AnimationClip _clip = BuiltInLoader.LoadAnimationClip(name);
|
if (_clip != null)
|
{
|
m_Animation.AddClip(_clip, "start_show");
|
m_Animation.Play("start_show");
|
}
|
}
|
|
private void OnAnimationOver()
|
{
|
IsPlayingAnim = false;
|
}
|
|
public void ResetOriginal()
|
{
|
SnxxzGame.Instance.StopAllCameraCo();
|
StopAllCoroutines();
|
RotationDamping = 0.02f;
|
ZoomDamping = 0.02f;
|
sceneDistance = Distance = originalDistance;
|
rotationX = originalRotX;
|
rotationY = originalRotY;
|
}
|
|
public void SetLookTarget(Transform _target)
|
{
|
LookAtTarget = _target;
|
}
|
|
public void SetRotationX(float _angle)
|
{
|
rotationX = _angle;
|
}
|
|
public void ChangeRotationX(float _change_value)
|
{
|
rotationX += _change_value;
|
}
|
|
public struct LookAtData
|
{
|
public Vector3 position;
|
public float rotX;
|
public float rotY;
|
public float lastTime;
|
}
|
|
public void StartLookAtTarget(LookAtData data)
|
{
|
StopCoroutine("_CoLookAtTarget");
|
StartCoroutine("_CoLookAtTarget", data);
|
}
|
|
IEnumerator _CoLookAtTarget(LookAtData data)
|
{
|
yield return WaitingForSecondConst.WaitMS1000;
|
GA_Hero.s_MapSwitching = true;
|
SetLookTarget(null);
|
transform.position = data.position;
|
float _cacheRotX = rotationX;
|
float _cacheRotY = rotationY;
|
rotationX = data.rotX;
|
rotationY = data.rotY;
|
yield return new WaitForSeconds(data.lastTime);
|
SetLookTarget(PlayerDatas.Instance.hero.Root);
|
rotationX = _cacheRotX;
|
rotationY = _cacheRotY;
|
GA_Hero.s_MapSwitching = false;
|
}
|
|
IEnumerator CameraRotationX(float _angle)
|
{
|
while (rotationX != _angle)
|
{
|
rotationX = Mathf.SmoothDampAngle(rotationX, _angle, ref m_CurrentRotationX, RotationDamping);
|
if (Mathf.Abs(rotationX - _angle) <= 0.01f)
|
{
|
rotationX = _angle;
|
}
|
yield return null;
|
}
|
}
|
|
// Update is called once per frame
|
void Update()
|
{
|
// 是否正在播放摄像机动画
|
if (IsPlayingAnim)
|
{
|
return;
|
}
|
//#if UNITY_EDITOR
|
|
//if (AcceptInput)
|
//{
|
// if (Input.GetMouseButtonDown(0))
|
// {
|
// Ray _ray = CameraObject.ScreenPointToRay(Input.mousePosition);
|
// RaycastHit _hit;
|
// if (Physics.Raycast(_ray, out _hit, 100, LayerUtility.WalkbleMask))
|
// {
|
// if (LookAtTarget != null)
|
// {
|
// LookAtTarget.transform.position = _hit.point;
|
// }
|
// }
|
// }
|
//}
|
|
//#endif
|
|
Vector3 eulerAngles = transform.eulerAngles;
|
|
float newCameraRotUp = Mathf.SmoothDampAngle(eulerAngles.x, rotationY, ref m_CurrentRotationY, RotationDamping);
|
float newCameraRotSide = Mathf.SmoothDampAngle(eulerAngles.y, rotationX, ref m_CurrentRotationX, RotationDamping);
|
|
Vector3 _dir = new Vector3(newCameraRotUp, newCameraRotSide, 0);
|
if (_dir.magnitude > 0.01f)
|
{
|
transform.rotation = Quaternion.Euler(_dir);
|
}
|
|
if (LookAtTarget != null)
|
{
|
transform.position = Vector3.SmoothDamp(transform.position, LookAtTarget.position + new Vector3(0, lookHeight, 0), ref m_MoveVelocity, MoveDamping);
|
}
|
|
float dist = Mathf.SmoothDamp(-CameraObject.transform.localPosition.z, Distance, ref m_ZoomVelocity, ZoomDamping);
|
var _p = -Vector3.forward * dist;
|
if (float.IsNaN(_p.x) || float.IsNaN(_p.y) || float.IsNaN(_p.z))
|
{
|
return;
|
}
|
CameraObject.transform.localPosition = _p;
|
}
|
|
public void Apply()
|
{
|
if (LookAtTarget == null)
|
{
|
return;
|
}
|
transform.position = LookAtTarget.position + new Vector3(0, lookHeight, 0);
|
transform.eulerAngles = new Vector3(rotationY, rotationX, 0);
|
CameraObject.transform.localPosition = -Vector3.forward * Distance;
|
}
|
|
#if UNITY_EDITOR
|
void OnDrawGizmos()
|
{
|
if (CameraObject != null)
|
{
|
Gizmos.color = new Color(1.0f, 1.0f, 0.0f, 0.8f); // Color.yellow;
|
Gizmos.DrawSphere(CameraObject.transform.position, 0.2f);
|
|
Gizmos.color = new Color(1.0f, 0.0f, 0.0f, 0.8f); // Color.yellow;
|
Gizmos.DrawSphere(transform.position, 0.2f);
|
|
Gizmos.color = Color.yellow;
|
Gizmos.DrawLine(CameraObject.transform.position, transform.position);
|
}
|
}
|
#endif
|
|
private void OnDestroy()
|
{
|
LookAtTarget = null;
|
Instance = null;
|
|
if (CameraManager.sceneCamera == CameraObject)
|
{
|
CameraManager.sceneCamera = null;
|
}
|
|
}
|
|
private struct ZoomVo
|
{
|
public float scale;
|
public float time;
|
}
|
|
public void StartZoom(float scale, float zoomTime)
|
{
|
|
if (zoomTime == 0)
|
{
|
return;
|
}
|
|
StopZoom();
|
|
ZoomVo _vo = new ZoomVo
|
{
|
scale = scale,
|
time = zoomTime
|
};
|
|
StartCoroutine("Zoom", _vo);
|
}
|
|
public void StopZoom()
|
{
|
StopCoroutine("Zoom");
|
}
|
|
IEnumerator Zoom(ZoomVo vo)
|
{
|
float _cacheDistance = Distance;
|
float _time = 0;
|
float _percent;
|
float _zoomDistance = sceneDistance * vo.scale - Distance;
|
while (_time < vo.time)
|
{
|
_percent = _time / vo.time;
|
_percent = Constants.zoomAniCurve.animationCurve.Evaluate(_percent);
|
Distance = _cacheDistance + _percent * _zoomDistance;
|
_time += Time.deltaTime;
|
yield return null;
|
}
|
Distance = _cacheDistance + _zoomDistance;
|
//_cacheDistance = Distance;
|
//_zoomDistance = m_OriginalDistance - Distance;
|
//while (_time < vo.recoverTime)
|
//{
|
// _percent = _time / vo.recoverTime;
|
// _percent = Constants.zoomAniCurve.animationCurve.Evaluate(_percent);
|
// Distance = _cacheDistance + _percent * _zoomDistance;
|
// _time += Time.deltaTime;
|
// yield return null;
|
//}
|
//Distance = m_OriginalDistance;
|
}
|
|
private struct ShakeVo
|
{
|
public Vector3 shakeDir;
|
public float power;
|
public float interval;
|
public float duration;
|
}
|
|
public void DoShake(Vector3 dir, float power, float interval, float duration)
|
{
|
ShakeVo _vo = new ShakeVo
|
{
|
shakeDir = dir.normalized,
|
power = power,
|
interval = interval,
|
duration = duration
|
};
|
|
Node.transform.localPosition = Vector3.zero;
|
StopCoroutine("Shake");
|
StartCoroutine("Shake", _vo);
|
}
|
|
public void StopShake()
|
{
|
Node.transform.localPosition = Vector3.zero;
|
StopCoroutine("Shake");
|
}
|
|
IEnumerator Shake(ShakeVo vo)
|
{
|
float _percent = 0;
|
float _interval = 0;
|
float _duration = vo.duration;
|
Vector3 _localPos = Vector3.zero;
|
Vector3 _direction = vo.shakeDir;
|
|
float _distance = Vector3.Distance(vo.power * _direction, Vector3.zero);
|
|
while (_duration > 0)
|
{
|
_interval += Time.deltaTime;
|
_percent = _interval / vo.interval;
|
_percent = Constants.shakeAniCurve.animationCurve.Evaluate(_percent);
|
Node.transform.localPosition = _localPos + _direction * _distance * _percent;
|
if (_interval > vo.interval)
|
{
|
_localPos = Node.transform.localPosition;
|
_direction = -_direction;
|
_distance = Vector3.Distance(vo.power * _direction, _localPos);
|
_interval = 0;
|
}
|
_duration -= Time.deltaTime;
|
yield return null;
|
}
|
|
_interval = 0;
|
_localPos = Node.transform.localPosition;
|
_direction = (Vector3.zero - Node.transform.localPosition).normalized;
|
_distance = Vector3.Distance(Vector3.zero, _localPos);
|
while (_interval < vo.interval)
|
{
|
_interval += Time.deltaTime;
|
_percent = _interval / vo.interval;
|
_percent = Constants.shakeAniCurve.animationCurve.Evaluate(_percent);
|
Node.transform.localPosition = _localPos + _direction * _distance * _percent;
|
yield return null;
|
}
|
|
Node.transform.localPosition = Vector3.zero;
|
}
|
}
|