ZeroVR/ZeroPacientVR/Assets/Scripts/VR/ShotgunReload.cs

253 lines
7.3 KiB
C#

using System;
using System.Collections;
using HurricaneVR.Framework.ControllerInput;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Bags;
using HurricaneVR.Framework.Core.Grabbers;
using HurricaneVR.Framework.Core.Utils;
using HurricaneVR.Framework.Shared;
using HurricaneVR.Framework.Weapons;
using HurricaneVR.Framework.Weapons.Guns;
using UnityEngine;
using Zero;
public class ShotgunReload : MonoBehaviour
{
[SerializeField] private HVRGrabbable masterGrabbable;
[SerializeField] private Rigidbody rig;
[SerializeField] private ConfigurableJoint joint;
[SerializeField] private StateReloadShotgun prevState;
[SerializeField] private StateReloadShotgun state;
[SerializeField] private StateLogicShotgun logicState;
[SerializeField] private float maxAngle;
[SerializeField] private GameObject stab;
[SerializeField] private HVRGunSounds sounds;
[SerializeField] private float actualAngle;
[SerializeField] private float timeToActionFromAngle = 0.2f;
[SerializeField] private HVRGrabbable magazineGrabbable;
[SerializeField] private HVRMagazineSocket magazineSocket;
[SerializeField] private HVRGrabbableBag magazineBag;
[SerializeField] private Transform ejectTransform;
[SerializeField] private float impulseEject = 50;
[SerializeField] private float delayToActivateGrab;
[SerializeField] private HVRGrabbable reloadGrabbable;
private bool isPrepareToShoot;
public bool IsPrepareToShoot => isPrepareToShoot;
private float currentTime;
private void Start()
{
joint = GetComponent<ConfigurableJoint>();
Closed();
}
public void Grab()
{
isPrepareToShoot = false;
prevState = state;
state = StateReloadShotgun.InHand;
joint.SetAngularXHighLimit(maxAngle);
joint.SetAngularXLowLimit(0);
if(prevState == StateReloadShotgun.Closed)
{
sounds.PlaySlideBack();
logicState = StateLogicShotgun.ToOpen;
}
if(prevState == StateReloadShotgun.Opened)
{
logicState = StateLogicShotgun.ToClose;
}
stab.SetActive(false);
currentTime = Time.time;
}
public void Release()
{
prevState = state;
state = StateReloadShotgun.Free;
if(prevState is not (StateReloadShotgun.Closed or StateReloadShotgun.Opened))
{
joint.SetAngularXHighLimit(maxAngle);
joint.SetAngularXLowLimit(0);
stab.SetActive(false);
}
else
{
if(prevState == StateReloadShotgun.Closed)
{
Closed();
}
if(prevState == StateReloadShotgun.Opened)
{
Opened();
}
}
currentTime = Time.time;
}
public void Closed()
{
prevState = state;
state = StateReloadShotgun.Closed;
joint.SetAngularXLowLimit(0);
joint.SetAngularXHighLimit(0);
stab.SetActive(true);
isPrepareToShoot = true;
SetEnableMagazineSlot(false);
StartCoroutine(Enabled());
IEnumerator Enabled()
{
reloadGrabbable.enabled = false;
yield return new WaitForSeconds(delayToActivateGrab);
reloadGrabbable.enabled = true;
}
logicState = StateLogicShotgun.None;
}
public void Opened(bool forceEject = false)
{
isPrepareToShoot = false;
prevState = state;
state = StateReloadShotgun.Opened;
joint.SetAngularXHighLimit(maxAngle);
joint.SetAngularXLowLimit(maxAngle - 0.1f);
stab.SetActive(false);
SetEnableMagazineSlot(true);
if(magazineSocket.GrabbedTarget)
{
var magazine = magazineSocket.GrabbedTarget.GetComponent<WeaponAmmo>();
if(magazine)
{
if(magazine.IsEmpty || forceEject)
{
magazineSocket.ForceRelease();
var magRig = magazine.GetComponent<Rigidbody>();
if(magRig)
{
magRig.AddForce(ejectTransform.forward * impulseEject);
}
}
}
}
logicState = StateLogicShotgun.None;
}
public void ChangeAngle(float angle, float b)
{
if (currentTime + timeToActionFromAngle > Time.time) return;
angle = 360 - angle;
if(angle >= 360) angle -= 360;
actualAngle = angle;
if(angle < 10 && logicState == StateLogicShotgun.ToClose)
{
if(state is StateReloadShotgun.InHand or StateReloadShotgun.Free)
{
sounds.PlaySlideForward();
Closed();
}
}
else
if(angle > 80 && logicState == StateLogicShotgun.ToOpen)
{
if(state is StateReloadShotgun.InHand or StateReloadShotgun.Free)
{
sounds.PlaySlideBack();
Opened();
}
}
}
public void SetEnableMagazineSlot(bool isEnable, HVRGrabbable unload = default)
{
magazineSocket.enabled = isEnable;
magazineBag.enabled = isEnable;
magazineGrabbable.enabled = isEnable;
if(unload)
{
unload.enabled = isEnable;
}
}
public void LoadMagazine()
{
SetEnableMagazineSlot(false);
if (state == StateReloadShotgun.Closed) return;
prevState = state;
state = StateReloadShotgun.Free;
logicState = StateLogicShotgun.ToClose;
joint.SetAngularXHighLimit(maxAngle);
joint.SetAngularXLowLimit(0);
stab.SetActive(false);
sounds.PlayLoadMagazine();
}
public void UnloadMagazine(HVRGrabberBase grabbableBase, HVRGrabbable unload)
{
SetEnableMagazineSlot(true, unload);
sounds.PlayUnloadMagazine();
}
private void Update()
{
foreach(var hand in masterGrabbable.HandGrabbers)
{
var controller = HVRInputManager.Instance.GetController(hand.HandSide);
var release = false;
if (controller.ControllerType == HVRControllerType.WMR)
{
release = controller.Side == HVRHandSide.Right ? controller.TrackPadLeft.JustActivated : controller.TrackPadRight.JustActivated;
}
else if (controller.ControllerType == HVRControllerType.Vive)
{
release = HVRInputManager.Instance.RightController.TrackPadDown.JustActivated;
}
else
{
release = controller.PrimaryButtonState.JustActivated;
}
if(release)
{
if(state == StateReloadShotgun.Closed)
{
sounds.PlaySlideBack();
Opened();
}
else if(state is StateReloadShotgun.Free or StateReloadShotgun.Opened)
{
sounds.PlaySlideForward();
Closed();
}
}
}
}
}
public enum StateReloadShotgun
{
Closed = 0,
Opened = 1,
InHand = 2,
Free = 3
}
public enum StateLogicShotgun
{
None,
ToOpen,
ToClose
}