using UnityEngine;
namespace SK.Framework
{
///
/// 瞄准系统
///
public class AimSystem : MonoBehaviour
{
#region NonPublic Variables
private static AimSystem instance;
//开关
[SerializeField] private bool toggle = true;
//瞄准相机
[SerializeField] private Camera mainCamera;
//瞄准检测层级
[SerializeField] private LayerMask aimLayer;
//瞄准最大检测距离
[SerializeField] private float aimMaxDistance = 10f;
//瞄准方式
[SerializeField] private AimMode aimMode = AimMode.Mouse;
#endregion
#region Public Properties
public static AimSystem Instance
{
get
{
if (instance == null)
{
instance = FindObjectOfType() ?? new GameObject("[SKFramework.Aim]").AddComponent();
}
return instance;
}
}
///
/// 开关
///
public bool Toggle
{
get
{
return toggle;
}
set
{
if (toggle != value)
{
toggle = value;
if (CurrentAimableObject != null)
{
CurrentAimableObject.Exit();
CurrentAimableObject = null;
}
}
}
}
///
/// 当前瞄准的物体
///
public IAimableObject CurrentAimableObject { get; private set; }
#endregion
#region NonPublic Methods
private void Start()
{
if (mainCamera == null)
{
mainCamera = Camera.main ?? FindObjectOfType();
}
//如果使用鼠标方式瞄准 则不使用最大瞄准距离进行限制
aimMaxDistance = aimMode == AimMode.Mouse ? float.MaxValue : aimMaxDistance;
}
private void Update()
{
if (!toggle) return;
Ray ray = aimMode == AimMode.Mouse
? mainCamera.ScreenPointToRay(Input.mousePosition)
: mainCamera.ViewportPointToRay(Vector2.one * .5f);
if (Physics.Raycast(ray, out RaycastHit hit, aimMaxDistance, aimLayer))
{
IAimableObject obj = hit.collider.GetComponent();
if (obj != CurrentAimableObject)
{
CurrentAimableObject?.Exit();
CurrentAimableObject = obj;
CurrentAimableObject?.Enter();
}
}
else
{
if (CurrentAimableObject != null)
{
CurrentAimableObject.Exit();
CurrentAimableObject = null;
}
}
CurrentAimableObject?.Stay();
}
private void OnDestroy()
{
if (CurrentAimableObject != null)
{
CurrentAimableObject.Exit();
CurrentAimableObject = null;
}
instance = null;
}
#endregion
}
}