253 lines
7.3 KiB
C#
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
|
|
}
|