update
This commit is contained in:
@@ -0,0 +1,560 @@
|
||||
using System.Collections.Generic;
|
||||
using Unity.FPS.Game;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Unity.FPS.Gameplay
|
||||
{
|
||||
[RequireComponent(typeof(PlayerInputHandler))]
|
||||
public class PlayerWeaponsManager : MonoBehaviour
|
||||
{
|
||||
public enum WeaponSwitchState
|
||||
{
|
||||
Up,
|
||||
Down,
|
||||
PutDownPrevious,
|
||||
PutUpNew,
|
||||
}
|
||||
|
||||
[Tooltip("List of weapon the player will start with")]
|
||||
public List<WeaponController> StartingWeapons = new List<WeaponController>();
|
||||
|
||||
[Header("References")] [Tooltip("Secondary camera used to avoid seeing weapon go throw geometries")]
|
||||
public Camera WeaponCamera;
|
||||
|
||||
[Tooltip("Parent transform where all weapon will be added in the hierarchy")]
|
||||
public Transform WeaponParentSocket;
|
||||
|
||||
[Tooltip("Position for weapons when active but not actively aiming")]
|
||||
public Transform DefaultWeaponPosition;
|
||||
|
||||
[Tooltip("Position for weapons when aiming")]
|
||||
public Transform AimingWeaponPosition;
|
||||
|
||||
[Tooltip("Position for innactive weapons")]
|
||||
public Transform DownWeaponPosition;
|
||||
|
||||
[Header("Weapon Bob")]
|
||||
[Tooltip("Frequency at which the weapon will move around in the screen when the player is in movement")]
|
||||
public float BobFrequency = 10f;
|
||||
|
||||
[Tooltip("How fast the weapon bob is applied, the bigger value the fastest")]
|
||||
public float BobSharpness = 10f;
|
||||
|
||||
[Tooltip("Distance the weapon bobs when not aiming")]
|
||||
public float DefaultBobAmount = 0.05f;
|
||||
|
||||
[Tooltip("Distance the weapon bobs when aiming")]
|
||||
public float AimingBobAmount = 0.02f;
|
||||
|
||||
[Header("Weapon Recoil")]
|
||||
[Tooltip("This will affect how fast the recoil moves the weapon, the bigger the value, the fastest")]
|
||||
public float RecoilSharpness = 50f;
|
||||
|
||||
[Tooltip("Maximum distance the recoil can affect the weapon")]
|
||||
public float MaxRecoilDistance = 0.5f;
|
||||
|
||||
[Tooltip("How fast the weapon goes back to it's original position after the recoil is finished")]
|
||||
public float RecoilRestitutionSharpness = 10f;
|
||||
|
||||
[Header("Misc")] [Tooltip("Speed at which the aiming animatoin is played")]
|
||||
public float AimingAnimationSpeed = 10f;
|
||||
|
||||
[Tooltip("Field of view when not aiming")]
|
||||
public float DefaultFov = 60f;
|
||||
|
||||
[Tooltip("Portion of the regular FOV to apply to the weapon camera")]
|
||||
public float WeaponFovMultiplier = 1f;
|
||||
|
||||
[Tooltip("Delay before switching weapon a second time, to avoid recieving multiple inputs from mouse wheel")]
|
||||
public float WeaponSwitchDelay = 1f;
|
||||
|
||||
[Tooltip("Layer to set FPS weapon gameObjects to")]
|
||||
public LayerMask FpsWeaponLayer;
|
||||
|
||||
public bool IsAiming { get; private set; }
|
||||
public bool IsPointingAtEnemy { get; private set; }
|
||||
public int ActiveWeaponIndex { get; private set; }
|
||||
|
||||
public UnityAction<WeaponController> OnSwitchedToWeapon;
|
||||
public UnityAction<WeaponController, int> OnAddedWeapon;
|
||||
public UnityAction<WeaponController, int> OnRemovedWeapon;
|
||||
|
||||
WeaponController[] m_WeaponSlots = new WeaponController[9]; // 9 available weapon slots
|
||||
PlayerInputHandler m_InputHandler;
|
||||
PlayerCharacterController m_PlayerCharacterController;
|
||||
float m_WeaponBobFactor;
|
||||
Vector3 m_LastCharacterPosition;
|
||||
Vector3 m_WeaponMainLocalPosition;
|
||||
Vector3 m_WeaponBobLocalPosition;
|
||||
Vector3 m_WeaponRecoilLocalPosition;
|
||||
Vector3 m_AccumulatedRecoil;
|
||||
float m_TimeStartedWeaponSwitch;
|
||||
WeaponSwitchState m_WeaponSwitchState;
|
||||
int m_WeaponSwitchNewWeaponIndex;
|
||||
|
||||
void Start()
|
||||
{
|
||||
ActiveWeaponIndex = -1;
|
||||
m_WeaponSwitchState = WeaponSwitchState.Down;
|
||||
|
||||
m_InputHandler = GetComponent<PlayerInputHandler>();
|
||||
DebugUtility.HandleErrorIfNullGetComponent<PlayerInputHandler, PlayerWeaponsManager>(m_InputHandler, this,
|
||||
gameObject);
|
||||
|
||||
m_PlayerCharacterController = GetComponent<PlayerCharacterController>();
|
||||
DebugUtility.HandleErrorIfNullGetComponent<PlayerCharacterController, PlayerWeaponsManager>(
|
||||
m_PlayerCharacterController, this, gameObject);
|
||||
|
||||
SetFov(DefaultFov);
|
||||
|
||||
OnSwitchedToWeapon += OnWeaponSwitched;
|
||||
|
||||
// Add starting weapons
|
||||
foreach (var weapon in StartingWeapons)
|
||||
{
|
||||
AddWeapon(weapon);
|
||||
}
|
||||
|
||||
SwitchWeapon(true);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
// shoot handling
|
||||
WeaponController activeWeapon = GetActiveWeapon();
|
||||
|
||||
if (activeWeapon != null && activeWeapon.IsReloading)
|
||||
return;
|
||||
|
||||
if (activeWeapon != null && m_WeaponSwitchState == WeaponSwitchState.Up)
|
||||
{
|
||||
if (!activeWeapon.AutomaticReload && m_InputHandler.GetReloadButtonDown() && activeWeapon.CurrentAmmoRatio < 1.0f)
|
||||
{
|
||||
IsAiming = false;
|
||||
activeWeapon.StartReloadAnimation();
|
||||
return;
|
||||
}
|
||||
// handle aiming down sights
|
||||
IsAiming = m_InputHandler.GetAimInputHeld();
|
||||
|
||||
// handle shooting
|
||||
bool hasFired = activeWeapon.HandleShootInputs(
|
||||
m_InputHandler.GetFireInputDown(),
|
||||
m_InputHandler.GetFireInputHeld(),
|
||||
m_InputHandler.GetFireInputReleased());
|
||||
|
||||
// Handle accumulating recoil
|
||||
if (hasFired)
|
||||
{
|
||||
m_AccumulatedRecoil += Vector3.back * activeWeapon.RecoilForce;
|
||||
m_AccumulatedRecoil = Vector3.ClampMagnitude(m_AccumulatedRecoil, MaxRecoilDistance);
|
||||
}
|
||||
}
|
||||
|
||||
// weapon switch handling
|
||||
if (!IsAiming &&
|
||||
(activeWeapon == null || !activeWeapon.IsCharging) &&
|
||||
(m_WeaponSwitchState == WeaponSwitchState.Up || m_WeaponSwitchState == WeaponSwitchState.Down))
|
||||
{
|
||||
int switchWeaponInput = m_InputHandler.GetSwitchWeaponInput();
|
||||
if (switchWeaponInput != 0)
|
||||
{
|
||||
bool switchUp = switchWeaponInput > 0;
|
||||
SwitchWeapon(switchUp);
|
||||
}
|
||||
else
|
||||
{
|
||||
switchWeaponInput = m_InputHandler.GetSelectWeaponInput();
|
||||
if (switchWeaponInput != 0)
|
||||
{
|
||||
if (GetWeaponAtSlotIndex(switchWeaponInput - 1) != null)
|
||||
SwitchToWeaponIndex(switchWeaponInput - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pointing at enemy handling
|
||||
IsPointingAtEnemy = false;
|
||||
if (activeWeapon)
|
||||
{
|
||||
// if (Physics.Raycast(WeaponCamera.transform.position, WeaponCamera.transform.forward, out RaycastHit hit,
|
||||
// 1000, -1, QueryTriggerInteraction.Ignore))
|
||||
// {
|
||||
// if (hit.collider.GetComponentInParent<Health>() != null)
|
||||
// {
|
||||
// IsPointingAtEnemy = true;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Update various animated features in LateUpdate because it needs to override the animated arm position
|
||||
void LateUpdate()
|
||||
{
|
||||
UpdateWeaponAiming();
|
||||
UpdateWeaponBob();
|
||||
UpdateWeaponRecoil();
|
||||
UpdateWeaponSwitching();
|
||||
|
||||
// Set final weapon socket position based on all the combined animation influences
|
||||
// WeaponParentSocket.localPosition =
|
||||
// m_WeaponMainLocalPosition + m_WeaponBobLocalPosition + m_WeaponRecoilLocalPosition;
|
||||
}
|
||||
|
||||
// Sets the FOV of the main camera and the weapon camera simultaneously
|
||||
public void SetFov(float fov)
|
||||
{
|
||||
m_PlayerCharacterController.PlayerCamera.fieldOfView = fov;
|
||||
// WeaponCamera.fieldOfView = fov * WeaponFovMultiplier;
|
||||
}
|
||||
|
||||
// Iterate on all weapon slots to find the next valid weapon to switch to
|
||||
public void SwitchWeapon(bool ascendingOrder)
|
||||
{
|
||||
int newWeaponIndex = -1;
|
||||
int closestSlotDistance = m_WeaponSlots.Length;
|
||||
for (int i = 0; i < m_WeaponSlots.Length; i++)
|
||||
{
|
||||
// If the weapon at this slot is valid, calculate its "distance" from the active slot index (either in ascending or descending order)
|
||||
// and select it if it's the closest distance yet
|
||||
if (i != ActiveWeaponIndex && GetWeaponAtSlotIndex(i) != null)
|
||||
{
|
||||
int distanceToActiveIndex = GetDistanceBetweenWeaponSlots(ActiveWeaponIndex, i, ascendingOrder);
|
||||
|
||||
if (distanceToActiveIndex < closestSlotDistance)
|
||||
{
|
||||
closestSlotDistance = distanceToActiveIndex;
|
||||
newWeaponIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle switching to the new weapon index
|
||||
SwitchToWeaponIndex(newWeaponIndex);
|
||||
}
|
||||
|
||||
// Switches to the given weapon index in weapon slots if the new index is a valid weapon that is different from our current one
|
||||
public void SwitchToWeaponIndex(int newWeaponIndex, bool force = false)
|
||||
{
|
||||
if (force || (newWeaponIndex != ActiveWeaponIndex && newWeaponIndex >= 0))
|
||||
{
|
||||
// Store data related to weapon switching animation
|
||||
m_WeaponSwitchNewWeaponIndex = newWeaponIndex;
|
||||
m_TimeStartedWeaponSwitch = Time.time;
|
||||
|
||||
// Handle case of switching to a valid weapon for the first time (simply put it up without putting anything down first)
|
||||
if (GetActiveWeapon() == null)
|
||||
{
|
||||
// m_WeaponMainLocalPosition = DownWeaponPosition.localPosition;
|
||||
m_WeaponSwitchState = WeaponSwitchState.PutUpNew;
|
||||
ActiveWeaponIndex = m_WeaponSwitchNewWeaponIndex;
|
||||
|
||||
WeaponController newWeapon = GetWeaponAtSlotIndex(m_WeaponSwitchNewWeaponIndex);
|
||||
if (OnSwitchedToWeapon != null)
|
||||
{
|
||||
OnSwitchedToWeapon.Invoke(newWeapon);
|
||||
}
|
||||
}
|
||||
// otherwise, remember we are putting down our current weapon for switching to the next one
|
||||
else
|
||||
{
|
||||
m_WeaponSwitchState = WeaponSwitchState.PutDownPrevious;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public WeaponController HasWeapon(WeaponController weaponPrefab)
|
||||
{
|
||||
// Checks if we already have a weapon coming from the specified prefab
|
||||
for (var index = 0; index < m_WeaponSlots.Length; index++)
|
||||
{
|
||||
var w = m_WeaponSlots[index];
|
||||
if (w != null && w.SourcePrefab == weaponPrefab.gameObject)
|
||||
{
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Updates weapon position and camera FoV for the aiming transition
|
||||
void UpdateWeaponAiming()
|
||||
{
|
||||
if (m_WeaponSwitchState == WeaponSwitchState.Up)
|
||||
{
|
||||
WeaponController activeWeapon = GetActiveWeapon();
|
||||
if (IsAiming && activeWeapon)
|
||||
{
|
||||
// m_WeaponMainLocalPosition = Vector3.Lerp(m_WeaponMainLocalPosition,
|
||||
// AimingWeaponPosition.localPosition + activeWeapon.AimOffset,
|
||||
// AimingAnimationSpeed * Time.deltaTime);
|
||||
// SetFov(Mathf.Lerp(m_PlayerCharacterController.PlayerCamera.fieldOfView,
|
||||
// activeWeapon.AimZoomRatio * DefaultFov, AimingAnimationSpeed * Time.deltaTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_WeaponMainLocalPosition = Vector3.Lerp(m_WeaponMainLocalPosition,
|
||||
// DefaultWeaponPosition.localPosition, AimingAnimationSpeed * Time.deltaTime);
|
||||
SetFov(Mathf.Lerp(m_PlayerCharacterController.PlayerCamera.fieldOfView, DefaultFov,
|
||||
AimingAnimationSpeed * Time.deltaTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the weapon bob animation based on character speed
|
||||
void UpdateWeaponBob()
|
||||
{
|
||||
if (Time.deltaTime > 0f)
|
||||
{
|
||||
Vector3 playerCharacterVelocity =
|
||||
(m_PlayerCharacterController.transform.position - m_LastCharacterPosition) / Time.deltaTime;
|
||||
|
||||
// calculate a smoothed weapon bob amount based on how close to our max grounded movement velocity we are
|
||||
float characterMovementFactor = 0f;
|
||||
if (m_PlayerCharacterController.IsGrounded)
|
||||
{
|
||||
characterMovementFactor =
|
||||
Mathf.Clamp01(playerCharacterVelocity.magnitude /
|
||||
(m_PlayerCharacterController.MaxSpeedOnGround *
|
||||
m_PlayerCharacterController.SprintSpeedModifier));
|
||||
}
|
||||
|
||||
m_WeaponBobFactor =
|
||||
Mathf.Lerp(m_WeaponBobFactor, characterMovementFactor, BobSharpness * Time.deltaTime);
|
||||
|
||||
// Calculate vertical and horizontal weapon bob values based on a sine function
|
||||
float bobAmount = IsAiming ? AimingBobAmount : DefaultBobAmount;
|
||||
float frequency = BobFrequency;
|
||||
float hBobValue = Mathf.Sin(Time.time * frequency) * bobAmount * m_WeaponBobFactor;
|
||||
float vBobValue = ((Mathf.Sin(Time.time * frequency * 2f) * 0.5f) + 0.5f) * bobAmount *
|
||||
m_WeaponBobFactor;
|
||||
|
||||
// Apply weapon bob
|
||||
m_WeaponBobLocalPosition.x = hBobValue;
|
||||
m_WeaponBobLocalPosition.y = Mathf.Abs(vBobValue);
|
||||
|
||||
m_LastCharacterPosition = m_PlayerCharacterController.transform.position;
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the weapon recoil animation
|
||||
void UpdateWeaponRecoil()
|
||||
{
|
||||
// if the accumulated recoil is further away from the current position, make the current position move towards the recoil target
|
||||
if (m_WeaponRecoilLocalPosition.z >= m_AccumulatedRecoil.z * 0.99f)
|
||||
{
|
||||
m_WeaponRecoilLocalPosition = Vector3.Lerp(m_WeaponRecoilLocalPosition, m_AccumulatedRecoil,
|
||||
RecoilSharpness * Time.deltaTime);
|
||||
}
|
||||
// otherwise, move recoil position to make it recover towards its resting pose
|
||||
else
|
||||
{
|
||||
m_WeaponRecoilLocalPosition = Vector3.Lerp(m_WeaponRecoilLocalPosition, Vector3.zero,
|
||||
RecoilRestitutionSharpness * Time.deltaTime);
|
||||
m_AccumulatedRecoil = m_WeaponRecoilLocalPosition;
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the animated transition of switching weapons
|
||||
void UpdateWeaponSwitching()
|
||||
{
|
||||
// Calculate the time ratio (0 to 1) since weapon switch was triggered
|
||||
float switchingTimeFactor = 0f;
|
||||
if (WeaponSwitchDelay == 0f)
|
||||
{
|
||||
switchingTimeFactor = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
switchingTimeFactor = Mathf.Clamp01((Time.time - m_TimeStartedWeaponSwitch) / WeaponSwitchDelay);
|
||||
}
|
||||
|
||||
// Handle transiting to new switch state
|
||||
if (switchingTimeFactor >= 1f)
|
||||
{
|
||||
if (m_WeaponSwitchState == WeaponSwitchState.PutDownPrevious)
|
||||
{
|
||||
// Deactivate old weapon
|
||||
WeaponController oldWeapon = GetWeaponAtSlotIndex(ActiveWeaponIndex);
|
||||
if (oldWeapon != null)
|
||||
{
|
||||
oldWeapon.ShowWeapon(false);
|
||||
}
|
||||
|
||||
ActiveWeaponIndex = m_WeaponSwitchNewWeaponIndex;
|
||||
switchingTimeFactor = 0f;
|
||||
|
||||
// Activate new weapon
|
||||
WeaponController newWeapon = GetWeaponAtSlotIndex(ActiveWeaponIndex);
|
||||
if (OnSwitchedToWeapon != null)
|
||||
{
|
||||
OnSwitchedToWeapon.Invoke(newWeapon);
|
||||
}
|
||||
|
||||
if (newWeapon)
|
||||
{
|
||||
m_TimeStartedWeaponSwitch = Time.time;
|
||||
m_WeaponSwitchState = WeaponSwitchState.PutUpNew;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if new weapon is null, don't follow through with putting weapon back up
|
||||
m_WeaponSwitchState = WeaponSwitchState.Down;
|
||||
}
|
||||
}
|
||||
else if (m_WeaponSwitchState == WeaponSwitchState.PutUpNew)
|
||||
{
|
||||
m_WeaponSwitchState = WeaponSwitchState.Up;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle moving the weapon socket position for the animated weapon switching
|
||||
if (m_WeaponSwitchState == WeaponSwitchState.PutDownPrevious)
|
||||
{
|
||||
// m_WeaponMainLocalPosition = Vector3.Lerp(DefaultWeaponPosition.localPosition,
|
||||
// DownWeaponPosition.localPosition, switchingTimeFactor);
|
||||
}
|
||||
else if (m_WeaponSwitchState == WeaponSwitchState.PutUpNew)
|
||||
{
|
||||
// m_WeaponMainLocalPosition = Vector3.Lerp(DownWeaponPosition.localPosition,
|
||||
// DefaultWeaponPosition.localPosition, switchingTimeFactor);
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a weapon to our inventory
|
||||
public bool AddWeapon(WeaponController weaponPrefab)
|
||||
{
|
||||
// if we already hold this weapon type (a weapon coming from the same source prefab), don't add the weapon
|
||||
if (HasWeapon(weaponPrefab) != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// search our weapon slots for the first free one, assign the weapon to it, and return true if we found one. Return false otherwise
|
||||
for (int i = 0; i < m_WeaponSlots.Length; i++)
|
||||
{
|
||||
// only add the weapon if the slot is free
|
||||
if (m_WeaponSlots[i] == null)
|
||||
{
|
||||
// spawn the weapon prefab as child of the weapon socket
|
||||
WeaponController weaponInstance = Instantiate(weaponPrefab, WeaponParentSocket);
|
||||
weaponInstance.transform.localPosition = Vector3.zero;
|
||||
weaponInstance.transform.localRotation = Quaternion.identity;
|
||||
|
||||
// Set owner to this gameObject so the weapon can alter projectile/damage logic accordingly
|
||||
weaponInstance.Owner = gameObject;
|
||||
weaponInstance.SourcePrefab = weaponPrefab.gameObject;
|
||||
weaponInstance.ShowWeapon(false);
|
||||
|
||||
// Assign the first person layer to the weapon
|
||||
int layerIndex =
|
||||
Mathf.RoundToInt(Mathf.Log(FpsWeaponLayer.value,
|
||||
2)); // This function converts a layermask to a layer index
|
||||
foreach (Transform t in weaponInstance.gameObject.GetComponentsInChildren<Transform>(true))
|
||||
{
|
||||
t.gameObject.layer = layerIndex;
|
||||
}
|
||||
|
||||
m_WeaponSlots[i] = weaponInstance;
|
||||
|
||||
if (OnAddedWeapon != null)
|
||||
{
|
||||
OnAddedWeapon.Invoke(weaponInstance, i);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle auto-switching to weapon if no weapons currently
|
||||
if (GetActiveWeapon() == null)
|
||||
{
|
||||
SwitchWeapon(true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool RemoveWeapon(WeaponController weaponInstance)
|
||||
{
|
||||
// Look through our slots for that weapon
|
||||
for (int i = 0; i < m_WeaponSlots.Length; i++)
|
||||
{
|
||||
// when weapon found, remove it
|
||||
if (m_WeaponSlots[i] == weaponInstance)
|
||||
{
|
||||
m_WeaponSlots[i] = null;
|
||||
|
||||
if (OnRemovedWeapon != null)
|
||||
{
|
||||
OnRemovedWeapon.Invoke(weaponInstance, i);
|
||||
}
|
||||
|
||||
Destroy(weaponInstance.gameObject);
|
||||
|
||||
// Handle case of removing active weapon (switch to next weapon)
|
||||
if (i == ActiveWeaponIndex)
|
||||
{
|
||||
SwitchWeapon(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public WeaponController GetActiveWeapon()
|
||||
{
|
||||
return GetWeaponAtSlotIndex(ActiveWeaponIndex);
|
||||
}
|
||||
|
||||
public WeaponController GetWeaponAtSlotIndex(int index)
|
||||
{
|
||||
// find the active weapon in our weapon slots based on our active weapon index
|
||||
if (index >= 0 &&
|
||||
index < m_WeaponSlots.Length)
|
||||
{
|
||||
return m_WeaponSlots[index];
|
||||
}
|
||||
|
||||
// if we didn't find a valid active weapon in our weapon slots, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
// Calculates the "distance" between two weapon slot indexes
|
||||
// For example: if we had 5 weapon slots, the distance between slots #2 and #4 would be 2 in ascending order, and 3 in descending order
|
||||
int GetDistanceBetweenWeaponSlots(int fromSlotIndex, int toSlotIndex, bool ascendingOrder)
|
||||
{
|
||||
int distanceBetweenSlots = 0;
|
||||
|
||||
if (ascendingOrder)
|
||||
{
|
||||
distanceBetweenSlots = toSlotIndex - fromSlotIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
distanceBetweenSlots = -1 * (toSlotIndex - fromSlotIndex);
|
||||
}
|
||||
|
||||
if (distanceBetweenSlots < 0)
|
||||
{
|
||||
distanceBetweenSlots = m_WeaponSlots.Length + distanceBetweenSlots;
|
||||
}
|
||||
|
||||
return distanceBetweenSlots;
|
||||
}
|
||||
|
||||
void OnWeaponSwitched(WeaponController newWeapon)
|
||||
{
|
||||
if (newWeapon != null)
|
||||
{
|
||||
newWeapon.ShowWeapon(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user