using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Moonlit.FootstepPro { [AddComponentMenu("FootprintSystem/Foot")] public class Foot : MonoBehaviour { private class FootState { public bool Over; public bool Under; } [SerializeField] [Header("Foot type")] private FootstepDataType _Type; [SerializeField] [Header("Settings")] private float _TriggerHeight; [SerializeField] private List _Detectors; [Header("Controller")] public IFootstepController Controller; public Vector3 EulerRotation; private FootState _FootState = new FootState(); [SerializeField] private List _Triggers = new List(); private List _OrDetectors = new List(); private List _AndDetectors = new List(); public FootstepDataType Type { get { return _Type; } set { _Type = value; } } public List Triggers { get { return _Triggers; } } public float TriggerHeight { get { return _TriggerHeight; } set { _TriggerHeight = value; } } public List Detectors { get { return _Detectors; } } private void Awake() { ValidateTriggers(); _FootState.Under = true; _FootState.Over = false; _Detectors = GetComponents().ToList(); _OrDetectors = _Detectors.Where((IStepDetector x) => x.Type == IStepDetector.CombineType.Optional).ToList(); _AndDetectors = _Detectors.Where((IStepDetector x) => x.Type == IStepDetector.CombineType.Required).ToList(); } private void Update() { if (!(Controller == null)) { if (CheckStep() && _FootState.Over) { _FootState.Over = false; Place(); } if (!IsTriggered()) { _FootState.Over = true; } } } private void Reset() { } private void OnDrawGizmos() { if (!(Controller == null)) { Vector3 up = Controller.Up; Vector3 triggerPlanePosition = GetTriggerPlanePosition(); Gizmos.matrix = Matrix4x4.TRS(triggerPlanePosition, Controller.transform.rotation, Vector3.one); Gizmos.color = new Color(1f, 1f, 1f, 0.1f + ((!_FootState.Over) ? 0.5f : 0f)) * Color.magenta; Gizmos.DrawCube(new Vector3(0f, 0f, 0f), new Vector3(0.3f, 0.001f, 0.3f)); } } public void Place() { if (Controller == null) { return; } FootInfo footInfo = new FootInfo(); footInfo.Position = base.transform.position; footInfo.Rotation = base.transform.rotation; footInfo.Data = Type; List list = Physics.RaycastAll(base.transform.position + Controller.Up, -Controller.Up).ToList(); if (list.Count == 0) { return; } List list2 = list.Where(delegate(RaycastHit x) { Surface component = x.collider.GetComponent(); return component != null && component.Type != null; }).ToList(); if (list2.Count != 0) { RaycastHit[] array = list2.OrderBy((RaycastHit x) => x.distance).ToArray(); Controller.Callback(array[0], footInfo); } } public void ResetRotation(Vector3 euler) { EulerRotation = euler; base.transform.rotation = Quaternion.Euler(EulerRotation); foreach (FootTrigger trigger in _Triggers) { trigger.transform.rotation = Quaternion.identity; } } public void ValidateTriggers() { _Triggers.Where((FootTrigger x) => x == null).ToList().ForEach(delegate(FootTrigger x) { _Triggers.Remove(x); }); } private bool CheckStep() { bool flag = IsTriggered(); foreach (IStepDetector orDetector in _OrDetectors) { if (orDetector.enabled) { flag |= orDetector.Detect(this); } } foreach (IStepDetector andDetector in _AndDetectors) { if (andDetector.enabled) { flag &= andDetector.Detect(this); } } foreach (IStepDetector detector in _Detectors) { detector.Callback(flag); } return flag; } private bool IsTriggered() { foreach (FootTrigger trigger in _Triggers) { Vector3 normalized = (trigger.transform.position - GetTriggerPlanePosition()).normalized; float num = Vector3.Dot(normalized, -Controller.Up.normalized); if (num < 0f) { trigger.IsTriggered = true; } else { trigger.IsTriggered = false; } } foreach (FootTrigger trigger2 in _Triggers) { if (!trigger2.IsTriggered) { return false; } } return true; } private Vector3 GetTriggerPlanePosition() { if (Controller == null) { return Vector3.zero; } return CalculateTriggerPosition(base.transform.position, -Controller.Up, Controller.transform.position, 0f - _TriggerHeight); } private Vector3 CalculateTriggerPosition(Vector3 footPosition, Vector3 bodyNormal, Vector3 bodyPosition, float triggerDistance) { Vector3 vector = footPosition + bodyNormal; Vector3 lhs = bodyPosition - footPosition; Vector3 vector2 = vector - footPosition; Vector3 vector3 = footPosition + Vector3.Dot(lhs, vector2) / Vector3.Dot(vector2, vector2) * vector2; return vector3 + bodyNormal * triggerDistance; } } }