Files
2024-11-20 15:21:28 +01:00

490 lines
16 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Invector.vShooter
{
public static class IKLocomotionOptionsHelper
{
public static vShooterWeapon.IKLocomotionOptions Copy(this vShooterWeapon.IKLocomotionOptions options)
{
vShooterWeapon.IKLocomotionOptions copy = new vShooterWeapon.IKLocomotionOptions()
{
use = options.use,
useOnIdle = options.useOnIdle,
useOnWalk = options.useOnWalk,
useOnRun = options.useOnRun,
useOnSprint = options.useOnSprint,
};
return copy;
}
}
[vClassHeader("Shooter Weapon", openClose = false)]
public class vShooterWeapon : vShooterWeaponBase
{
#region variables
[System.Serializable]
public class IKLocomotionOptions
{
public bool use = true;
[vHideInInspector("use")]
public bool useOnIdle = true;
[vHideInInspector("use")]
public bool useOnWalk = true;
[vHideInInspector("use")]
public bool useOnRun = true;
[vHideInInspector("use")]
public bool useOnSprint = true;
public IKLocomotionOptions()
{
use = true;
useOnIdle = true;
useOnWalk = true;
useOnRun = true;
useOnSprint = true;
}
}
[vEditorToolbar("Weapon Settings")]
public bool isLeftWeapon = false;
[Tooltip("Hold Charge Input to charge")]
public bool chargeWeapon = false;
[vHideInInspector("chargeWeapon")]
public bool autoShotOnFinishCharge = false;
[vHideInInspector("chargeWeapon")]
public float chargeSpeed = 0.1f;
[vHideInInspector("chargeWeapon")]
public float chargeDamageMultiplier = 2;
[vHideInInspector("chargeWeapon")]
public bool changeVelocityByCharge = true;
[vHideInInspector("chargeWeapon")]
public float chargeVelocityMultiplier = 2;
[Tooltip("Change between automatic weapon or shot once")]
[vHideInInspector("chargeWeapon", true)]
public bool automaticWeapon;
[vEditorToolbar("Ammo")]
public float reloadTime = 1f;
public bool reloadOneByOne;
[Tooltip("Max clip size of your weapon")]
public int clipSize;
[Tooltip("Check this to combine extra ammo with the current ammo, the Reload will not be used")]
public bool dontUseReload;
[vHideInInspector("dontUseReload", true)]
[Tooltip("Automatically reload the weapon when it's empty")]
public bool autoReload;
[Tooltip("Ammo ID - make sure your AmmoManager and ItemListData use the same ID"), vHideInInspector("isInfinityAmmo", true)]
public int ammoID;
[vEditorToolbar("Weapon ID")]
[Tooltip("What moveset the underbody will play")]
public float moveSetID;
[Tooltip("What moveset the uperbody will play")]
public float upperBodyID;
[Tooltip("What shot animation will trigger")]
public float shotID;
[Tooltip("What reload animation will play")]
public int reloadID;
[Tooltip("What equip animation will play")]
public int equipID;
[vEditorToolbar("IK Options")]
[Tooltip("IK will help the right hand to align where you actually is aiming")]
public bool alignRightHandToAim = true;
[Tooltip("IK will help the right hand to align where you actually is aiming")]
public bool alignRightUpperArmToAim = true;
public bool raycastAimTarget = true;
[Tooltip("Left IK on free locomotion")]
public IKLocomotionOptions freeIKOptions = new IKLocomotionOptions();
[Tooltip("Left IK on strafe locomotion")]
public IKLocomotionOptions strafeIKOptions = new IKLocomotionOptions();
[Tooltip("Left IK while attacking")]
public bool useIkAttacking = false;
[Tooltip("Left IK while Shot")]
public bool disableIkOnShot = false;
[Tooltip("Left IK while Aming")]
public bool useIKOnAiming = true;
[Tooltip("Left IK Hand Target")]
public Transform handIKTarget;
[vEditorToolbar("Projectile")]
[Tooltip("Assign the aimReference of your weapon")]
public Transform aimReference;
[vHelpBox("Only affects the camera from player, when player is aiming")]
[Tooltip("how much the camera will sway when aiming, 1 means no cameraSway and means maxCameraSway from the ShooterManager")]
[Range(0, 1)]
[UnityEngine.Serialization.FormerlySerializedAs("precision")]
public float cameraStability = 0.5f;
[Tooltip("Creates a right recoil on the camera")]
public float recoilRight = 1;
[Tooltip("Creates a left recoil on the camera")]
public float recoilLeft = -1;
[Tooltip("Creates a up recoil on the camera")]
public float recoilUp = 1;
[vEditorToolbar("Audio & VFX")]
public AudioSource reloadSource;
public AudioClip reloadClip;
public AudioClip finishReloadClip;
[vEditorToolbar("Scope View")]
[vHelpBox("Third Person Controller Only", vHelpBoxAttribute.MessageType.Info)]
public bool onlyUseScopeUIView;
[Tooltip("Check this bool to use an UI image for the scope, ex: snipers")]
public bool useUI;
[Tooltip("You can create different Aim sprites and use for different weapons")]
public int scopeID;
[Tooltip("The weight of shoot animation when using scope"),Range(0,1f)]
public float scopeShootAnimationWeight = .5f;
[Tooltip("change the FOV of the scope view\n **The calc is default value (60)-scopeZoom**"), Range(-118, 60)]
public float scopeZoom = 60;
[Tooltip("Change the FOV of the scope view Background\n **The calc is default value (60)-scopeZoom**"), Range(-118, 60)]
public float backGroundScopeZoom = 0;
[Tooltip("Used with the TPCamera to use a custom CameraState while aiming, if it's empty it will use the 'Aiming' CameraState.")]
public string customAimCameraState;
[Tooltip("Used with the TPCamera to use a custom CameraState while using scope view mode, if it's empty it will use the 'Aiming' CameraState.")]
public string customScopeCameraState;
[Tooltip("assign an empty transform with the pos/rot of your scope view")]
public Transform scopeTarget;
public Camera zoomScopeCamera;
[vHelpBox("Keep Scope Camera Z is used to align z rotation of the zoomScopeCamera to z rotation of the weapon muzzle<color=red> (Projectile toolbar)</color>. if you want to align camera with Vector3.up in z rotation enable this.")]
public bool keepScopeCameraRotationZ = true;
[System.Serializable]
public class OnChangePowerCharger : UnityEvent<float> { }
[HideInInspector]
public bool isAiming, usingScope;
[vEditorToolbar("Events")]
public UnityEvent onReload, onCancelReload, onFinishReload, onFinishAmmo, onEnableAim, onDisableAim, onEnableScope, onDisableScope, onFullPower;
[HideInInspector]
public UnityEvent onDisable;
public OnChangePowerCharger onPowerChargerChanged;
[HideInInspector]
public Transform root;
[HideInInspector]
public bool isSecundaryWeapon;
private float _charge;
public delegate bool CheckAmmoHandle(ref bool isValid, ref int totalAmmo);
public delegate void ChangeAmmoHandle(int value);
public CheckAmmoHandle checkAmmoHandle;
public ChangeAmmoHandle changeAmmoHandle;
protected Transform _handIKTargetOffset;
public Transform handIKTargetOffset
{
get
{
if(_handIKTargetOffset==null && handIKTarget!=null)
{
_handIKTargetOffset = new GameObject("Offset").transform;
_handIKTargetOffset.SetParent(handIKTarget);
_handIKTargetOffset.localPosition = Vector3.zero;
_handIKTargetOffset.localEulerAngles = Vector3.zero;
}
return _handIKTargetOffset;
}
}
#endregion
[System.NonSerialized] private float testTime;
protected virtual void OnDrawGizmos()
{
if (!Application.isPlaying && testShootEffect)
{
if (testTime <= 0)
{
Shootest();
}
else
{
testTime -= Time.deltaTime;
}
}
}
protected virtual void OnDisable()
{
onDisable.Invoke();
}
protected virtual void Start()
{
if (!reloadSource)
{
reloadSource = source;
}
SetScopeZoom(scopeZoom);
}
public virtual void Shootest()
{
testTime = shootFrequency;
StartEmitters();
lightOnShot.enabled = true;
source.PlayOneShot(fireClip);
Invoke("StopShootTest", .037f);
}
protected virtual void StopShootTest()
{
StopEmitters();
lightOnShot.enabled = false;
}
public virtual float powerCharge
{
get
{
return _charge;
}
set
{
if (value != _charge)
{
_charge = value;
onPowerChargerChanged.Invoke(_charge);
if (_charge >= 1)
{
onFullPower.Invoke();
}
}
}
}
public virtual void SetPrecision(float value)
{
cameraStability = Mathf.Clamp(value, 0, 1);
}
public override bool HasAmmo()
{
if (checkAmmoHandle != null)
{
bool isValidAmmo = false;
int totalAmmo = 0;
var hasAmmo = checkAmmoHandle.Invoke(ref isValidAmmo, ref totalAmmo);
if (isValidAmmo)
{
return hasAmmo;
}
else
{
return ammo > 0;
}
}
else
{
return ammo > 0;
}
}
public virtual bool inHolder
{
get; set;
}
public virtual int ammoCount
{
get
{
if (checkAmmoHandle != null)
{
bool isValidAmmo = false;
int totalAmmo = 0;
checkAmmoHandle.Invoke(ref isValidAmmo, ref totalAmmo);
if (isValidAmmo)
{
return totalAmmo;
}
else
{
return ammo;
}
}
return ammo;
}
}
public virtual void AddAmmo(int value)
{
if (checkAmmoHandle != null && changeAmmoHandle != null)
{
bool isValidAmmo = false;
int totalAmmo = 0;
checkAmmoHandle.Invoke(ref isValidAmmo, ref totalAmmo);
if (isValidAmmo)
{
changeAmmoHandle(value);
}
else
{
ammo += value;
}
}
else
{
ammo += value;
}
}
public override void UseAmmo(int count = 1)
{
if (checkAmmoHandle != null && changeAmmoHandle != null)
{
bool isValidAmmo = false;
int totalAmmo = 0;
checkAmmoHandle.Invoke(ref isValidAmmo, ref totalAmmo);
if (isValidAmmo)
{
changeAmmoHandle(-count);
}
else
{
ammo -= count;
}
}
else
{
ammo -= count;
}
}
public virtual void ReloadEffect()
{
if (reloadSource && reloadClip)
{
reloadSource.Stop();
reloadSource.PlayOneShot(reloadClip);
}
onReload.Invoke();
}
public virtual void FinishReloadEffect()
{
if (reloadSource && finishReloadClip)
{
reloadSource.Stop();
reloadSource.PlayOneShot(finishReloadClip);
}
onFinishReload.Invoke();
}
protected override float damageMultiplier
{
get
{
if (!chargeWeapon)
{
return base.damageMultiplier;
}
return (float)System.Math.Round((1 + Mathf.Lerp(0, chargeDamageMultiplier, _charge)) + damageMultiplierMod, 1);
}
}
protected override float velocityMultiplier
{
get
{
if (!chargeWeapon || !changeVelocityByCharge)
{
return base.velocityMultiplier;
}
return (1 + Mathf.Lerp(0, chargeVelocityMultiplier, _charge)) + velocityMultiplierMod;
}
}
public virtual void SetScopeZoom(float value)
{
if (zoomScopeCamera)
{
var zoom = Mathf.Clamp(61 - value, 1, 179);
zoomScopeCamera.fieldOfView = zoom;
}
}
public virtual void SetActiveAim(bool value)
{
if (isAiming != value)
{
isAiming = value;
if (isAiming)
{
onEnableAim.Invoke();
}
else
{
onDisableAim.Invoke();
}
}
}
/// <summary>
/// Set if Weapon is using scope
/// </summary>
/// <param name="value"></param>
public virtual void SetActiveScope(bool value)
{
if (usingScope != value)
{
usingScope = value;
if (usingScope)
{
onEnableScope.Invoke();
}
else
{
onDisableScope.Invoke();
}
}
}
/// <summary>
/// Set look target point to Zoom scope camera
/// </summary>
/// <param name="point"></param>
public virtual void SetScopeLookTarget(Vector3 point)
{
if (zoomScopeCamera)
{
var euler = Quaternion.LookRotation(point - zoomScopeCamera.transform.position, Vector3.up).eulerAngles;
if (keepScopeCameraRotationZ)
{
euler.z = muzzle.transform.eulerAngles.z;
}
zoomScopeCamera.transform.eulerAngles = euler;
}
}
public virtual void CancelReload()
{
if (reloadSource && reloadSource.isPlaying)
{
reloadSource.Stop();
}
onCancelReload.Invoke();
}
}
}