// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) VRMADA, All rights reserved.
//
// --------------------------------------------------------------------------------------------------------------------
using UltimateXR.Audio;
using UltimateXR.Avatar;
using UltimateXR.Core;
using UltimateXR.Core.Components;
using UltimateXR.Haptics;
using UltimateXR.Manipulation;
using UnityEngine;
namespace UltimateXR.Mechanics.Weapons
{
///
/// Component that, added to a GameObject with a component, allows to communicate
/// whenever the shotgun is reloaded using a pump action using a . The shot cycle in
/// the firearm should be set to .
///
[RequireComponent(typeof(UxrFirearmWeapon))]
public partial class UxrShotgunPump : UxrComponent
{
#region Inspector Properties/Serialized Fields
[SerializeField] private int _triggerIndex;
[SerializeField] private UxrGrabbableObject _pump;
[SerializeField] private Vector3 _localPumpDirection = Vector3.forward;
[SerializeField] private Vector3 _localPumpOffset = Vector3.forward * 0.2f;
[SerializeField] [Range(0, 1)] private float _slideThreshold = 0.7f;
[SerializeField] private UxrAudioSample _audioSlide = new UxrAudioSample();
[SerializeField] private UxrAudioSample _audioSlideBack = new UxrAudioSample();
[SerializeField] private UxrAudioSample _audioSlideAlreadyLoaded = new UxrAudioSample();
[SerializeField] private UxrAudioSample _audioSlideBackAlreadyLoaded = new UxrAudioSample();
[SerializeField] private UxrHapticClip _hapticClipSlide = new UxrHapticClip(null, UxrHapticClipType.Click);
[SerializeField] private UxrHapticClip _hapticClipSlideBack = new UxrHapticClip(null, UxrHapticClipType.Click);
[SerializeField] private UxrHapticClip _hapticClipSlideAlreadyLoaded = new UxrHapticClip(null, UxrHapticClipType.Slide);
[SerializeField] private UxrHapticClip _hapticClipSlideBackAlreadyLoaded = new UxrHapticClip(null, UxrHapticClipType.Slide);
#endregion
#region Unity
///
/// Initializes the component.
///
protected override void Awake()
{
base.Awake();
_state = State.WaitPump;
_localStart = _pump != null ? _pump.transform.localPosition : Vector3.zero;
_firearm = GetComponent();
}
///
/// Updates the component, looking for the pump action if necessary.
///
private void Update()
{
if (_pump == null)
{
return;
}
float currentSlide = Vector3.Scale(_pump.transform.localPosition - _localStart, _localPumpDirection).magnitude / _localPumpOffset.magnitude;
if (_state == State.WaitPump && currentSlide > _slideThreshold)
{
_state = State.WaitPumpBack;
if (_firearm.IsLoaded(_triggerIndex))
{
_audioSlideAlreadyLoaded.Play(_pump.transform.position);
}
else
{
_audioSlide.Play(_pump.transform.position);
}
if (UxrGrabManager.Instance.GetGrabbingHand(_pump, 0, out UxrGrabber grabber) && grabber.Avatar.AvatarMode == UxrAvatarMode.Local)
{
UxrAvatar.LocalAvatarInput.SendHapticFeedback(grabber.Side, _firearm.IsLoaded(_triggerIndex) ? _hapticClipSlideAlreadyLoaded : _hapticClipSlide);
}
}
else if (_state == State.WaitPumpBack && currentSlide < _slideThreshold * 0.9f)
{
if (_firearm.IsLoaded(_triggerIndex))
{
_audioSlideBackAlreadyLoaded.Play(_pump.transform.position);
}
else
{
_audioSlideBack.Play(_pump.transform.position);
}
if (UxrGrabManager.Instance.GetGrabbingHand(_pump, 0, out UxrGrabber grabber) && grabber.Avatar.AvatarMode == UxrAvatarMode.Local)
{
UxrAvatar.LocalAvatarInput.SendHapticFeedback(grabber.Side, _firearm.IsLoaded(_triggerIndex) ? _hapticClipSlideBackAlreadyLoaded : _hapticClipSlideBack);
}
_firearm.Reload(_triggerIndex);
_state = State.WaitPump;
}
}
#endregion
#region Private Types & Data
private UxrFirearmWeapon _firearm;
private Vector3 _localStart;
private State _state;
#endregion
}
}