using UnityEngine; public class SwerveXInputHandler : MonoBehaviour, IInputsListener { public float sensibility = 20f; public float trackWidth = 5f; private bool _canMove; private Vector3 _downScreenPos; private float _xWorldPosOnDown; private Vector3 _lastDownScreenPos; private Vector3 lastPos; private Vector3 _lastScreenPosTmp; private int wallLayer; public float lastMoveX; private const float X_TO_ADD = 0.3f; private float r; private float _l; private Vector3 _hitPosLeft; private Vector3 _hitPosRight; private Vector3 _hitPosForward; private bool _hitR; private bool _hitL; private bool _hitF; public float TargetWorldX { get; private set; } public float deltaX { get; private set; } public void Awake() { wallLayer = LayerMask.GetMask("Wall"); } public void InputDown(Vector3 screenPosition) { _lastScreenPosTmp = screenPosition; if (!_canMove) { return; } _downScreenPos = screenPosition; _lastDownScreenPos = screenPosition; _xWorldPosOnDown = base.transform.localPosition.x; deltaX = 0f; lastMoveX = 0f; } private void FixedUpdate() { if (!_canMove) { return; } CheckCharacterRaycast(); float right = base.transform.parent.InverseTransformPoint(_hitPosRight).x; float left = base.transform.parent.InverseTransformPoint(_hitPosLeft).x; if (_hitF) { float forward = base.transform.parent.InverseTransformPoint(_hitPosForward).x; if (forward > base.transform.localPosition.x) { right = forward - X_TO_ADD; } else { left = forward + X_TO_ADD; } } r = right; _l = left; float clamped = Mathf.Clamp(TargetWorldX, _l, r); if (clamped != TargetWorldX) { TargetWorldX = clamped; } } public void InputMove(Vector3 screenPosition) { _lastScreenPosTmp = screenPosition; if (!_canMove) { return; } deltaX = screenPosition.x - _lastDownScreenPos.x; TargetWorldX = _xWorldPosOnDown + (screenPosition.x - _downScreenPos.x) * (sensibility / (float)Screen.height); float clamped = Mathf.Clamp(TargetWorldX, _l, r); if (clamped != TargetWorldX) { _xWorldPosOnDown -= TargetWorldX - clamped; } _lastDownScreenPos = screenPosition; lastPos = base.transform.position; } public void InputUp() { deltaX = 0f; } public void InputCancel() { deltaX = 0f; } private void CheckCharacterRaycast() { Vector3 origin = base.transform.position + base.transform.forward * 0.1f; RaycastHit hit; if (Physics.Raycast(origin, base.transform.right, out hit, trackWidth, wallLayer)) { _hitR = true; _hitPosRight = hit.point - base.transform.right * X_TO_ADD; } else { _hitR = false; _hitPosRight = base.transform.parent.position + base.transform.right * (trackWidth * 0.5f); } if (Physics.Raycast(base.transform.position, -base.transform.right, out hit, trackWidth, wallLayer)) { _hitL = true; _hitPosLeft = hit.point + base.transform.right * X_TO_ADD; } else { _hitL = false; _hitPosLeft = base.transform.parent.position - base.transform.right * (trackWidth * 0.5f); } if (Physics.Raycast(base.transform.position, base.transform.forward, out hit, 2f, wallLayer)) { _hitF = true; _hitPosForward = hit.transform.position; } else { _hitF = false; } } public void activeControl(bool active) { if (_canMove == active) { return; } _canMove = active; deltaX = 0f; if (active) { InputDown(_lastScreenPosTmp); InputMove(_lastScreenPosTmp); } } private void OnDrawGizmos() { Gizmos.color = (_hitR ? Color.green : Color.red); Gizmos.DrawLine(base.transform.position, base.transform.position + base.transform.right * trackWidth); Gizmos.color = (_hitL ? Color.green : Color.red); Gizmos.DrawLine(base.transform.position, base.transform.position - base.transform.right * trackWidth); } }