Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add realistic reloading #285

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using CenturionCC.System.Gun.DataStore;
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;

namespace CenturionCC.System.Gun.Behaviour
{
Expand All @@ -16,6 +15,12 @@ public class CockingGunBehaviour : GunBehaviourBase

[SerializeField] private bool isDoubleAction;

[SerializeField] private bool doHoldOpen = true;

[SerializeField] private bool pullOnHoldOpen;

[SerializeField] private bool holdOpenOnEmptyShoot = true;

[SerializeField] private Transform cockingPosition;

[SerializeField] private float cockingLength;
Expand Down Expand Up @@ -116,7 +121,13 @@ private void UpdateCustomHandlePosition(GunBase instance)
{
Vector3 targetPos;
Quaternion targetRot;
switch (instance.State)
var gunState = instance.State;
if (gunState == GunState.InHoldOpen)
{
gunState = pullOnHoldOpen ? GunState.InCockingPull : GunState.Idle;
}

switch (gunState)
{
default:
case GunState.Idle:
Expand Down Expand Up @@ -155,7 +166,7 @@ private bool CanShoot(GunBase target)
{
return target.Trigger == TriggerState.Firing &&
target.State == GunState.Idle &&
(target.HasBulletInChamber || isDoubleAction);
(target.HasBulletInChamber && (target.HasCocked || isDoubleAction));
}

#endregion
Expand Down Expand Up @@ -208,11 +219,14 @@ private void DrawTwistGizmos()

public override void OnTriggerDown(GunBase instance)
{
if (!CanShoot(instance))
{
instance.EmptyShoot();
instance.Trigger = TriggerState.Armed;
}
// if (instance.Trigger == TriggerState.Firing &&
// instance.State == GunState.Idle &&
// (instance.CanShootWithoutMagazine || instance.HasMagazine) &&
// (instance.HasCocked || isDoubleAction))
// {
// instance.EmptyShoot();
// instance.Trigger = TriggerState.Fired;
// }
}

public override void OnGunPickup(GunBase instance)
Expand All @@ -232,17 +246,35 @@ public override void OnGunUpdate(GunBase instance)
float progressNormalized, twistNormalized;

// Shoot a gun whenever it's able to shoot. load new bullet if it's blow back variant
if (CanShoot(instance))

if (instance.Trigger == TriggerState.Firing)
{
var shotResult = instance.TryToShoot();
var hasSucceeded = shotResult == ShotResult.Succeeded || shotResult == ShotResult.SucceededContinuously;
if (hasSucceeded && isBlowBack)
if (instance.State == GunState.Idle &&
(instance.CanShootWithoutMagazine || instance.HasMagazine) &&
(instance.HasCocked || isDoubleAction))
{
var shotResult = instance.TryToShoot();
var hasPlayedShoot = shotResult == ShotResult.Succeeded ||
shotResult == ShotResult.SucceededContinuously ||
shotResult == ShotResult.Failed;
if (hasPlayedShoot && isBlowBack)
{
if (!instance.LoadBullet() && instance.HasMagazine && doHoldOpen)
{
instance.State = GunState.InHoldOpen;
UpdateCustomHandlePosition(instance);
}

instance.HasCocked = true;
}
}
else
{
instance.HasCocked = true;
instance.LoadBullet();
instance.Trigger = TriggerState.Fired;
}
}

if (instance.State == GunState.InHoldOpen && !instance.CustomHandle.IsPickedUp) return;

// Calculate cocking/twist progress
if (instance.IsVR)
Expand Down Expand Up @@ -326,6 +358,38 @@ public override void OnGunUpdate(GunBase instance)
);
}

public override void OnGunStateChanged(GunBase instance, GunState previousState)
{
if (instance.CustomHandle.IsPickedUp) return;

UpdateCustomHandlePosition(instance);

if (previousState == GunState.InHoldOpen && instance.State == GunState.Idle && !instance.HasBulletInChamber)
{
instance.LoadBullet();
// TODO: may not be realistic
instance.HasCocked = true;
}
}

public override void OnGunEmptyShoot(GunBase instance)
{
if (holdOpenOnEmptyShoot && instance.HasMagazine)
{
if (instance.MagazineRoundsRemaining <= 0) instance.State = GunState.InHoldOpen;
else instance.LoadBullet();
instance.HasCocked = true;
UpdateCustomHandlePosition(instance);
return;
}

if (isBlowBack && !doHoldOpen)
{
instance.LoadBullet();
instance.HasCocked = true;
}
}

public override void Setup(GunBase instance)
{
Debug.Log($"[CockingGunBehaviour] setup called for {instance.name}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ public class DefaultGunBehaviour : GunBehaviourBase

public override void OnGunPickup(GunBase instance)
{
if (!instance.HasBulletInChamber)
instance.LoadBullet();
instance.HasCocked = true;
}

public override void OnGunDrop(GunBase instance)
Expand All @@ -22,23 +19,20 @@ public override void OnGunUpdate(GunBase instance)
{
if (instance.Trigger == TriggerState.Firing)
{
var shotResult = instance.TryToShoot();
var hasSucceeded = shotResult == ShotResult.Succeeded || shotResult == ShotResult.SucceededContinuously;
if (hasSucceeded)
{
if (!instance.HasBulletInChamber)
instance.LoadBullet();
if (!instance.HasCocked)
instance.HasCocked = true;
}

var shotResult = instance.TryToShoot();
var hasShot = shotResult == ShotResult.Succeeded || shotResult == ShotResult.SucceededContinuously ||
shotResult == ShotResult.Failed;
if (hasShot && !instance.HasBulletInChamber)
instance.LoadBullet();
}
}

public override void Setup(GunBase instance)
{
instance.State = GunState.Idle;
if (!instance.HasBulletInChamber)
instance.LoadBullet();
instance.HasCocked = true;
}

public override void Dispose(GunBase instance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,27 @@ public virtual void OnGunUpdate(GunBase instance)
{
}

/// <summary>
/// Gets called when state was changed.
/// </summary>
/// <param name="instance"></param>
/// <param name="previousState"></param>
public virtual void OnGunStateChanged(GunBase instance, GunState previousState)
{
}

public virtual void OnGunShoot(GunBase instance)
{
}

public virtual void OnGunEmptyShoot(GunBase instance)
{
}

public virtual void OnGunCancelShoot(GunBase instance)
{
}

/// <summary>
/// Gets called when assigned to a <see cref="Gun" />.
/// </summary>
Expand Down
Loading