1935 lines
72 KiB
C#
1935 lines
72 KiB
C#
using UnityEngine;
|
|
|
|
namespace Invector.vCharacterController
|
|
{
|
|
using IK;
|
|
using vShooter;
|
|
|
|
[vClassHeader("SHOOTER/MELEE INPUT", iconName = "inputIcon")]
|
|
public class vShooterMeleeInput : vMeleeCombatInput, vIShooterIKController, PlayerController.vILockCamera
|
|
{
|
|
#region Shooter Variables
|
|
|
|
[HideInInspector] public vShooterManager shooterManager;
|
|
public vArmAimAlign leftArmAim, rightArmAim;
|
|
|
|
public virtual bool isAimingByInput { get; set; }
|
|
public virtual bool isReloading { get; set; }
|
|
public virtual bool ignoreIK { get; set; }
|
|
public virtual bool aimConditions { get; protected set; }
|
|
public virtual bool allowAttack { get; set; }
|
|
public virtual bool isCameraRightSwitched { get; set; }
|
|
|
|
protected virtual bool wasAiming { get; set; }
|
|
protected virtual bool wasAimingWithScope { get; set; }
|
|
protected virtual bool lockShooterInput { get; set; }
|
|
protected virtual bool checkCanAimInit { get; set; }
|
|
protected virtual bool _ignoreIKFromAnimator { get; set; }
|
|
protected virtual bool _walkingByDefaultWasChanged { get; set; }
|
|
protected bool _isUsingScopeView;
|
|
protected virtual bool isUsingScopeView { get { return _isUsingScopeView; } set { _isUsingScopeView = value; } }
|
|
|
|
public virtual int onlyArmsLayer { get; set; }
|
|
public virtual int shotLayer { get; set; }
|
|
public virtual int shootCountA { get; set; }
|
|
|
|
public virtual float onlyArmsLayerWeight { get; set; }
|
|
public virtual float supportIKWeight { get; set; }
|
|
public virtual float weaponIKWeight { get; set; }
|
|
|
|
public virtual float armAlignmentWeight { get; protected set; }
|
|
|
|
protected virtual float _aimTiming { get; set; }
|
|
protected virtual float checkCanAimOffsetStartX { get; set; }
|
|
protected virtual float checkCanAimOffsetStartY { get; set; }
|
|
protected virtual float checkCanAimOffsetEndX { get; set; }
|
|
protected virtual float checkCanAimOffsetEndY { get; set; }
|
|
protected virtual float checkCanAimHeight { get; set; }
|
|
protected virtual float scopeDirectionWeight { get; set; }
|
|
|
|
protected virtual GameObject aimAngleReference { get; set; }
|
|
protected virtual GameObject lastShooterWeapon { get; set; }
|
|
protected virtual Vector3 localAimPosition { get; set; }
|
|
protected virtual Vector3 aimHitPoint { get; set; }
|
|
protected virtual Vector3 upperArmPosition { get; set; }
|
|
protected virtual Vector3 muzzlePosition { get; set; }
|
|
protected virtual Vector3 muzzleForward { get; set; }
|
|
protected virtual Vector3 ikRotationOffset { get; set; }
|
|
protected virtual Vector3 ikPositionOffset { get; set; }
|
|
protected virtual Vector3 scopeLocalPosition { get; set; }
|
|
protected virtual Vector3 scopeCameraLocalPosition { get; set; }
|
|
protected virtual Vector3 scopeLocalForward { get; set; }
|
|
protected virtual Vector3 scopeCameraLocalForward { get; set; }
|
|
protected virtual Vector3 lastTargetCameraEuler { get; set; }
|
|
|
|
protected virtual Quaternion handRotation { get; set; }
|
|
protected virtual Quaternion upperArmRotation { get; set; }
|
|
protected virtual Quaternion upperArmRotationAlignment { get; set; }
|
|
protected virtual Quaternion handRotationAlignment { get; set; }
|
|
|
|
protected vHeadTrack headTrack;
|
|
protected vControlAimCanvas _controlAimCanvas;
|
|
protected IKAdjust _currentIKAdjust;
|
|
|
|
protected RaycastHit checkCanAimHit;
|
|
|
|
protected Transform leftHand, rightHand, rightLowerArm, leftLowerArm, rightUpperArm, leftUpperArm;
|
|
|
|
#region IKController Interface Properties
|
|
|
|
public virtual vIKSolver LeftIK { get; set; }
|
|
public virtual vIKSolver RightIK { get; set; }
|
|
|
|
public virtual vWeaponIKAdjustList WeaponIKAdjustList
|
|
{
|
|
get
|
|
{
|
|
if (shooterManager)
|
|
{
|
|
return shooterManager.weaponIKAdjustList;
|
|
}
|
|
|
|
|
|
return null;
|
|
}
|
|
set
|
|
{
|
|
if (shooterManager)
|
|
{
|
|
shooterManager.weaponIKAdjustList = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual vWeaponIKAdjust CurrentWeaponIK
|
|
{
|
|
get
|
|
{
|
|
if (shooterManager)
|
|
{
|
|
return shooterManager.CurrentWeaponIK;
|
|
}
|
|
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public virtual IKAdjust CurrentIKAdjust
|
|
{
|
|
get
|
|
{
|
|
if (CurrentWeaponIK == null) return null;
|
|
if (CurrentIKAdjustStateWithTag != (IKWeaponTag + TargetIKAdjustState) || _currentIKAdjust == null)
|
|
{
|
|
CurrentIKAdjustStateWithTag = (IKWeaponTag + TargetIKAdjustState);
|
|
CurrentIKAdjustState = TargetIKAdjustState;
|
|
_currentIKAdjust = CurrentWeaponIK.GetIKAdjust(CurrentIKAdjustState, CurrentActiveWeapon.isLeftWeapon);
|
|
|
|
}
|
|
return _currentIKAdjust;
|
|
}
|
|
}
|
|
|
|
public virtual bool EditingIKGlobalOffset
|
|
{
|
|
get; set;
|
|
}
|
|
|
|
public virtual string DefaultIKAdjustState => CurrentWeaponIK ? CurrentWeaponIK.GetDefaultStateName(this) : string.Empty;
|
|
|
|
protected virtual string TargetIKAdjustState => (!IsUsingCustomIKAdjust ? DefaultIKAdjustState : CustomIKAdjustState);
|
|
|
|
protected virtual string IKWeaponTag => CurrentActiveWeapon ? CurrentActiveWeapon.weaponCategory + "@" : "";
|
|
|
|
public virtual string CurrentIKAdjustStateWithTag { get; set; }
|
|
|
|
public virtual string CurrentIKAdjustState { get; protected set; }
|
|
|
|
public virtual bool IsUsingCustomIKAdjust => !string.IsNullOrEmpty(CustomIKAdjustState);
|
|
|
|
public string CustomIKAdjustState { get; protected set; }
|
|
|
|
public virtual void SetCustomIKAdjustState(string value)
|
|
{
|
|
if (!string.IsNullOrEmpty(value)) CustomIKAdjustState = value;
|
|
}
|
|
|
|
public virtual void ResetCustomIKAdjustState()
|
|
{
|
|
if (!string.IsNullOrEmpty(CustomIKAdjustState)) CustomIKAdjustState = string.Empty;
|
|
}
|
|
|
|
public virtual bool IsIgnoreIK
|
|
{
|
|
get
|
|
{
|
|
return ignoreIK || _ignoreIKFromAnimator;
|
|
}
|
|
}
|
|
|
|
public virtual bool IsIgnoreSupportHandIK
|
|
{
|
|
get
|
|
{
|
|
return cc.IsAnimatorTag("IgnoreSupportHandIK");
|
|
}
|
|
}
|
|
public virtual bool IsSupportHandIKEnabled
|
|
{
|
|
get; protected set;
|
|
|
|
}
|
|
|
|
public virtual void UpdateWeaponIK()
|
|
{
|
|
if (shooterManager)
|
|
{
|
|
shooterManager.UpdateWeaponIK();
|
|
if (CurrentWeaponIK == null) return;
|
|
_currentIKAdjust = CurrentWeaponIK.GetIKAdjust(CurrentIKAdjustState, CurrentActiveWeapon.isLeftWeapon);
|
|
}
|
|
}
|
|
|
|
public event IKUpdateEvent onStartUpdateIK;
|
|
|
|
public event IKUpdateEvent onFinishUpdateIK;
|
|
/// <summary>
|
|
/// Aim position including <seealso cref="vShooterManager.damageLayer"/>.
|
|
/// This is a point calculated from <seealso cref="vThirdPersonInput.cameraMain"/> position and <seealso cref="vThirdPersonInput.cameraMain"/> forward to get the desired aim position.
|
|
/// Used to align the arms and to define the<see cref="AimPosition"/>
|
|
/// </summary>
|
|
public virtual Vector3 DesiredAimPosition { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// Aim position including <seealso cref="vShooterManager.blockAimLayer"/>.
|
|
/// This is a point calculated from <see cref="vShooterWeapon.aimReference"/> of the weapon and <seealso cref="DesiredAimPosition"/>
|
|
/// </summary>
|
|
public virtual Vector3 AimPosition { get; protected set; }
|
|
|
|
public virtual bool LockAiming
|
|
{
|
|
get
|
|
{
|
|
return shooterManager && shooterManager.alwaysAiming;
|
|
}
|
|
set
|
|
{
|
|
shooterManager.alwaysAiming = value;
|
|
}
|
|
}
|
|
|
|
public virtual bool LockHipFireAiming
|
|
{
|
|
get; set;
|
|
}
|
|
|
|
public virtual bool IsCrouching
|
|
{
|
|
get
|
|
{
|
|
return cc.isCrouching;
|
|
}
|
|
set
|
|
{
|
|
cc.isCrouching = value;
|
|
}
|
|
}
|
|
|
|
public virtual bool IsLeftWeapon
|
|
{
|
|
get
|
|
{
|
|
|
|
return shooterManager && shooterManager.IsLeftWeapon;
|
|
}
|
|
}
|
|
|
|
public virtual bool LockCamera
|
|
{
|
|
get
|
|
{
|
|
return tpCamera && tpCamera.LockCamera;
|
|
}
|
|
set
|
|
{
|
|
if (tpCamera)
|
|
{
|
|
tpCamera.LockCamera = value;
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Is Aiming by <see cref="isAimingByInput"/> or <see cref="isAimingByHipFire"/>
|
|
/// </summary>
|
|
public virtual bool IsAiming
|
|
{
|
|
get
|
|
{
|
|
return lockShooterInput == false && (!cc.isRolling) && (isAimingByInput || isAimingByHipFire);
|
|
}
|
|
}
|
|
|
|
public virtual bool isAimingByHipFire
|
|
{
|
|
get
|
|
{
|
|
if (!shooterManager.hipfireShot && _aimTiming > 0 || (isReloading && !shooterManager.keepAimingWhenReload) || isEquipping || lockShooterInput || cc.customAction)
|
|
{
|
|
_aimTiming = 0;
|
|
return false;
|
|
}
|
|
return shooterManager.hipfireShot && (_aimTiming > 0 || (inputReader != null && inputReader.IsAttackHeld && shooterManager.CurrentWeapon != null) || (!isAimingByInput && shootCountA > 0));
|
|
}
|
|
}
|
|
|
|
public virtual vControlAimCanvas controlAimCanvas
|
|
{
|
|
get
|
|
{
|
|
if (!_controlAimCanvas)
|
|
{
|
|
_controlAimCanvas = FindObjectOfType<vControlAimCanvas>();
|
|
if (_controlAimCanvas)
|
|
{
|
|
_controlAimCanvas.Init(cc);
|
|
}
|
|
}
|
|
|
|
return _controlAimCanvas;
|
|
}
|
|
}
|
|
|
|
public override bool lockInventory
|
|
{
|
|
get
|
|
{
|
|
return base.lockInventory || isReloading || cc.customAction || cc.isRolling;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
protected override void Start()
|
|
{
|
|
shooterManager = GetComponent<vShooterManager>();
|
|
|
|
base.Start();
|
|
checkCanAimHeight = cc._capsuleCollider.height;
|
|
leftHand = animator.GetBoneTransform(HumanBodyBones.LeftHand);
|
|
rightHand = animator.GetBoneTransform(HumanBodyBones.RightHand);
|
|
leftLowerArm = animator.GetBoneTransform(HumanBodyBones.LeftLowerArm);
|
|
rightLowerArm = animator.GetBoneTransform(HumanBodyBones.RightLowerArm);
|
|
leftUpperArm = animator.GetBoneTransform(HumanBodyBones.LeftUpperArm);
|
|
rightUpperArm = animator.GetBoneTransform(HumanBodyBones.RightUpperArm);
|
|
|
|
onlyArmsLayer = animator.GetLayerIndex("OnlyArms");
|
|
shotLayer = animator.GetLayerIndex("Shot");
|
|
aimAngleReference = new GameObject("aimAngleReference");
|
|
aimAngleReference.tag = ("Ignore Ragdoll");
|
|
aimAngleReference.transform.rotation = transform.rotation;
|
|
var aimAngleParent = animator.GetBoneTransform(HumanBodyBones.Head);
|
|
aimAngleReference.transform.SetParent(aimAngleParent);
|
|
aimAngleReference.transform.localPosition = Vector3.zero;
|
|
|
|
headTrack = GetComponent<vHeadTrack>();
|
|
if (headTrack)
|
|
{
|
|
headTrack.onInitUpdate.AddListener(UpdateAimAngleReference);
|
|
}
|
|
if (!controlAimCanvas)
|
|
{
|
|
Debug.LogWarning("Missing the AimCanvas, drag and drop the prefab to this scene in order to Aim", gameObject);
|
|
}
|
|
muzzlePosition = Vector3.forward * cc._capsuleCollider.radius * 2;
|
|
muzzleForward = Vector3.forward;
|
|
}
|
|
|
|
protected override void LateUpdate()
|
|
{
|
|
if ((!updateIK && animator.updateMode == AnimatorUpdateMode.Fixed))
|
|
{
|
|
return;
|
|
}
|
|
|
|
base.LateUpdate();
|
|
UpdateAimBehaviour();
|
|
}
|
|
|
|
|
|
#region Shooter Inputs
|
|
|
|
protected virtual void Reset()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lock only shooter inputs
|
|
/// </summary>
|
|
/// <param name="value">lock or unlock</param>
|
|
public virtual void SetLockShooterInput(bool value)
|
|
{
|
|
lockShooterInput = value;
|
|
|
|
if (value)
|
|
{
|
|
isBlocking = false;
|
|
isAimingByInput = false;
|
|
_aimTiming = 0f;
|
|
if (controlAimCanvas)
|
|
{
|
|
controlAimCanvas.SetActiveAim(false);
|
|
controlAimCanvas.SetActiveScopeCamera(false);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void SetLockAllInput(bool value)
|
|
{
|
|
base.SetLockAllInput(value);
|
|
SetLockShooterInput(value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Always Aiming
|
|
/// </summary>
|
|
/// <param name="value">value to set aiming</param>
|
|
public virtual void SetAlwaysAim(bool value)
|
|
{
|
|
shooterManager.alwaysAiming = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Current active weapon (if weapon gameobject is disabled this return null)
|
|
/// </summary>
|
|
public virtual vShooterWeapon CurrentActiveWeapon
|
|
{
|
|
get
|
|
{
|
|
return shooterManager.CurrentActiveWeapon;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handles all the Controller Input
|
|
/// </summary>
|
|
public override void InputHandle()
|
|
{
|
|
if (cc == null || cc.isDead)
|
|
{
|
|
return;
|
|
}
|
|
|
|
#region BasicInput
|
|
|
|
if (!cc.ragdolled && !lockInput)
|
|
{
|
|
MoveInput();
|
|
SprintInput();
|
|
CrouchInput();
|
|
StrafeInput();
|
|
JumpInput();
|
|
RollInput();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region MeleeInput
|
|
|
|
if (MeleeAttackConditions() && !IsAiming && !isReloading && !lockMeleeInput && !CurrentActiveWeapon)
|
|
{
|
|
if (shooterManager.canUseMeleeWeakAttack_H || shooterManager.CurrentWeapon == null)
|
|
{
|
|
MeleeWeakAttackInput();
|
|
}
|
|
|
|
if (shooterManager.canUseMeleeStrongAttack_H || shooterManager.CurrentWeapon == null)
|
|
{
|
|
MeleeStrongAttackInput();
|
|
}
|
|
|
|
if (shooterManager.canUseMeleeBlock_H || shooterManager.CurrentWeapon == null)
|
|
{
|
|
BlockingInput();
|
|
}
|
|
else
|
|
{
|
|
isBlocking = false;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ShooterInput
|
|
|
|
if (lockShooterInput)
|
|
{
|
|
isAimingByInput = false;
|
|
_aimTiming = 0;
|
|
if (controlAimCanvas != null)
|
|
{
|
|
if (controlAimCanvas.isAimActive || controlAimCanvas.isScopeCameraActive)
|
|
{
|
|
isUsingScopeView = false;
|
|
controlAimCanvas.DisableAim();
|
|
}
|
|
}
|
|
}
|
|
else if (shooterManager.CurrentWeapon)
|
|
{
|
|
if (MeleeAttackConditions() && (!IsAiming || shooterManager.canUseMeleeAiming))
|
|
{
|
|
if (shooterManager.canUseMeleeWeakAttack_E)
|
|
{
|
|
MeleeWeakAttackInput();
|
|
}
|
|
if (shooterManager.canUseMeleeStrongAttack_E)
|
|
{
|
|
MeleeStrongAttackInput();
|
|
}
|
|
if (shooterManager.canUseMeleeBlock_E)
|
|
{
|
|
BlockingInput();
|
|
}
|
|
else
|
|
{
|
|
isBlocking = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isBlocking = false;
|
|
}
|
|
|
|
if (shooterManager == null || CurrentActiveWeapon == null || isEquipping)
|
|
{
|
|
if (_walkingByDefaultWasChanged)
|
|
{
|
|
_walkingByDefaultWasChanged = false;
|
|
ResetWalkByDefault();
|
|
}
|
|
if (IsAiming)
|
|
{
|
|
isAimingByInput = false;
|
|
_aimTiming = 0;
|
|
if (!cc.lockInStrafe && cc.isStrafing)
|
|
{
|
|
cc.Strafe();
|
|
}
|
|
|
|
if (controlAimCanvas != null)
|
|
{
|
|
if (controlAimCanvas.isAimActive || controlAimCanvas.isScopeCameraActive)
|
|
{
|
|
isUsingScopeView = false;
|
|
controlAimCanvas.DisableAim();
|
|
}
|
|
}
|
|
if (shooterManager && shooterManager.CurrentWeapon && shooterManager.CurrentWeapon.chargeWeapon && shooterManager.CurrentWeapon.powerCharge != 0)
|
|
{
|
|
CurrentActiveWeapon.powerCharge = 0;
|
|
}
|
|
|
|
shootCountA = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AimInput();
|
|
ShotInput();
|
|
ReloadInput();
|
|
SwitchCameraSideInput();
|
|
ScopeViewInput();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isAimingByInput = false;
|
|
_aimTiming = 0;
|
|
if (!cc.lockInStrafe && cc.isStrafing && cc.locomotionType != vThirdPersonMotor.LocomotionType.OnlyStrafe)
|
|
{
|
|
cc.Strafe();
|
|
}
|
|
if (_walkingByDefaultWasChanged && !IsAiming)
|
|
{
|
|
_walkingByDefaultWasChanged = false;
|
|
ResetWalkByDefault();
|
|
}
|
|
if (controlAimCanvas != null)
|
|
{
|
|
if (controlAimCanvas.isAimActive || controlAimCanvas.isScopeCameraActive)
|
|
{
|
|
isUsingScopeView = false;
|
|
controlAimCanvas.DisableAim();
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Override the Melee TriggerStrongAttack method to add the call to CancelReload when attacking
|
|
/// </summary>
|
|
public override void TriggerStrongAttack()
|
|
{
|
|
shooterManager.CancelReload();
|
|
base.TriggerStrongAttack();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Control Aim Input
|
|
/// </summary>
|
|
public virtual void AimInput()
|
|
{
|
|
//Change Rotation Method While Aiming
|
|
cc.strafeSpeed.rotateWithCamera = IsAiming ? true : cc.strafeSpeed.defaultRotateWithCamera;
|
|
if (_walkingByDefaultWasChanged && !IsAiming)
|
|
{
|
|
_walkingByDefaultWasChanged = false;
|
|
ResetWalkByDefault();
|
|
}
|
|
if (!shooterManager || isEquipping || isAttacking || (isReloading && (isUsingScopeView || !shooterManager.keepAimingWhenReload)))
|
|
{
|
|
if (!isReloading || (isReloading && !shooterManager.keepAimingWhenReload))
|
|
{
|
|
isAimingByInput = false;
|
|
|
|
ResetWalkByDefault();
|
|
_walkingByDefaultWasChanged = false;
|
|
if (cc.isStrafing && cc.locomotionType != vThirdPersonMotor.LocomotionType.OnlyStrafe)
|
|
{
|
|
cc.Strafe();
|
|
}
|
|
}
|
|
if (controlAimCanvas)
|
|
{
|
|
if (controlAimCanvas.isAimActive || controlAimCanvas.isScopeCameraActive)
|
|
{
|
|
isUsingScopeView = false;
|
|
controlAimCanvas.DisableAim();
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
if (LockHipFireAiming) _aimTiming = 1f;
|
|
|
|
if (shooterManager.onlyWalkWhenAiming && (!isReloading || shooterManager.keepAimingWhenReload))
|
|
{
|
|
if (isAimingByInput)
|
|
{
|
|
SetWalkByDefault(true);
|
|
_walkingByDefaultWasChanged = true;
|
|
}
|
|
else
|
|
{
|
|
ResetWalkByDefault();
|
|
_walkingByDefaultWasChanged = false;
|
|
}
|
|
}
|
|
|
|
if (cc.locomotionType == vThirdPersonMotor.LocomotionType.OnlyFree)
|
|
{
|
|
Debug.LogWarning("Shooter behaviour needs to be OnlyStrafe or Free with Strafe. \n Please change the Locomotion Type.");
|
|
return;
|
|
}
|
|
|
|
if (shooterManager.hipfireShot && !LockHipFireAiming)
|
|
{
|
|
// countdown for the hipfire to reset the aim back to idle
|
|
if (_aimTiming > 0 && CanRotateAimArm())
|
|
{
|
|
_aimTiming -= Time.deltaTime;
|
|
}
|
|
|
|
// reset the aimTimming if you sprint while still aiming through the hipfire
|
|
// if (sprintInput.GetButtonDown() && _aimTiming > 0f)
|
|
// {
|
|
// _aimTiming = 0f;
|
|
// }
|
|
if(inputReader != null && inputReader.IsSprintHeld && _aimTiming > 0f)
|
|
{
|
|
_aimTiming = 0f;
|
|
}
|
|
}
|
|
|
|
if (!shooterManager || !CurrentActiveWeapon)
|
|
{
|
|
if (controlAimCanvas)
|
|
{
|
|
if (controlAimCanvas.isAimActive || controlAimCanvas.isScopeCameraActive)
|
|
{
|
|
isUsingScopeView = false;
|
|
controlAimCanvas.DisableAim();
|
|
}
|
|
}
|
|
isAimingByInput = false;
|
|
if (cc.isStrafing)
|
|
{
|
|
cc.Strafe();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!cc.isRolling)
|
|
{
|
|
isAimingByInput = (!isReloading || shooterManager.keepAimingWhenReload) && (inputReader.IsAimHeld || (shooterManager.alwaysAiming && CurrentActiveWeapon)) && !cc.ragdolled && !cc.customAction;
|
|
}
|
|
|
|
if (inputReader.ConsumeAimReleased() && !inputReader.IsAttackHeld)
|
|
{
|
|
_aimTiming = 0f;
|
|
}
|
|
if (headTrack)
|
|
{
|
|
headTrack.alwaysFollowCamera = isAimingByInput;
|
|
}
|
|
|
|
if (cc.locomotionType == vThirdPersonMotor.LocomotionType.FreeWithStrafe)
|
|
{
|
|
if (!cc.lockInStrafe)
|
|
{
|
|
if (IsAiming && !cc.isStrafing)
|
|
{
|
|
cc.Strafe();
|
|
}
|
|
else if (!IsAiming && cc.isStrafing)
|
|
{
|
|
cc.Strafe();
|
|
}
|
|
}
|
|
|
|
}
|
|
if (IsAiming && shooterManager.onlyWalkWhenAiming && cc.isSprinting)
|
|
{
|
|
cc.isSprinting = false;
|
|
}
|
|
|
|
if (controlAimCanvas)
|
|
{
|
|
if (!isUsingScopeView)
|
|
{
|
|
|
|
if (IsAiming && !controlAimCanvas.isAimActive)
|
|
{
|
|
controlAimCanvas.SetActiveAim(true);
|
|
}
|
|
|
|
if (!IsAiming && controlAimCanvas.isAimActive)
|
|
{
|
|
controlAimCanvas.SetActiveAim(false);
|
|
}
|
|
}
|
|
}
|
|
if (shooterManager.rWeapon)
|
|
{
|
|
shooterManager.rWeapon.SetActiveAim(IsAiming && aimConditions);
|
|
shooterManager.rWeapon.SetActiveScope(IsAiming && isUsingScopeView);
|
|
}
|
|
else if (shooterManager.lWeapon)
|
|
{
|
|
shooterManager.lWeapon.SetActiveAim(IsAiming && aimConditions);
|
|
shooterManager.lWeapon.SetActiveScope(IsAiming && isUsingScopeView);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Control shot inputs (primary and secundary weapons)
|
|
/// </summary>
|
|
public virtual void ShotInput()
|
|
{
|
|
if (!shooterManager || CurrentActiveWeapon == null || cc.isDead || isReloading || isAttacking || isEquipping)
|
|
{
|
|
if (shooterManager && shooterManager.CurrentWeapon.chargeWeapon && shooterManager.CurrentWeapon.powerCharge != 0)
|
|
{
|
|
CurrentActiveWeapon.powerCharge = 0;
|
|
}
|
|
|
|
shootCountA = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
if (IsAiming && !shooterManager.isShooting && aimConditions)
|
|
{
|
|
if (CurrentActiveWeapon || (shooterManager.CurrentWeapon && shooterManager.hipfireShot))
|
|
{
|
|
// HandleShotCount(shooterManager.CurrentWeapon, shotInput.GetButton());
|
|
HandleShotCount(shooterManager.CurrentWeapon, inputReader.IsAttackHeld);
|
|
}
|
|
}
|
|
else if (!IsAiming)
|
|
{
|
|
if (shooterManager.CurrentWeapon.chargeWeapon && shooterManager.CurrentWeapon.powerCharge != 0)
|
|
{
|
|
CurrentActiveWeapon.powerCharge = 0;
|
|
}
|
|
|
|
shootCountA = 0;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Control Shot count
|
|
/// </summary>
|
|
/// <param name="weapon">target weapon</param>
|
|
/// <param name="weaponInput">check input</param>
|
|
public virtual void HandleShotCount(vShooterWeapon weapon, bool weaponInput = true)
|
|
{
|
|
if (weapon.chargeWeapon)
|
|
{
|
|
if (shooterManager.WeaponHasLoadedAmmo() && weapon.powerCharge < 1 && weaponInput)
|
|
{
|
|
if (shooterManager.hipfireShot)
|
|
{
|
|
_aimTiming = shooterManager.HipfireAimTime;
|
|
}
|
|
|
|
weapon.powerCharge += Time.fixedDeltaTime * weapon.chargeSpeed;
|
|
|
|
}
|
|
else if ((weapon.powerCharge >= 1 && weapon.autoShotOnFinishCharge && weaponInput) ||
|
|
(!weaponInput && IsAiming && weapon.powerCharge > 0f))
|
|
{
|
|
if (shooterManager.hipfireShot)
|
|
{
|
|
_aimTiming = shooterManager.HipfireAimTime;
|
|
}
|
|
shootCountA = 1;
|
|
|
|
}
|
|
animator.SetFloat(vAnimatorParameters.PowerCharger, weapon.powerCharge);
|
|
}
|
|
else if (weapon.automaticWeapon && weaponInput)
|
|
{
|
|
if (shooterManager.hipfireShot && !isAimingByInput)
|
|
{
|
|
_aimTiming = shooterManager.HipfireAimTime;
|
|
}
|
|
shootCountA = 1;
|
|
}
|
|
else if (weaponInput)
|
|
{
|
|
if (shooterManager.hipfireShot && !isAimingByInput)
|
|
{
|
|
_aimTiming = shooterManager.HipfireAimTime;
|
|
}
|
|
|
|
if (allowAttack == false)
|
|
{
|
|
shootCountA = 1;
|
|
allowAttack = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
allowAttack = false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Do Shots by shotcount after Ik behaviour updated
|
|
/// </summary>
|
|
public virtual void DoShots()
|
|
{
|
|
if (CanDoShots())
|
|
{
|
|
TriggerShot();
|
|
}
|
|
}
|
|
|
|
public virtual void TriggerShot()
|
|
{
|
|
animator.SetFloat(vAnimatorParameters.Shot_ID, shooterManager.GetShotID());
|
|
shooterManager.Shoot(AimPosition, !isAimingByInput);
|
|
if (CurrentActiveWeapon.chargeWeapon) CurrentActiveWeapon.powerCharge = 0;
|
|
shootCountA--;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reload current weapon
|
|
/// </summary>
|
|
public virtual void ReloadInput()
|
|
{
|
|
if (!shooterManager || CurrentActiveWeapon == null || isReloading || cc.customAction || shooterManager.isShooting || cc.ragdolled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (inputReader.ConsumeReload())
|
|
{
|
|
shootCountA = 0;
|
|
_aimTiming = 0f;
|
|
shooterManager.ReloadWeapon();
|
|
}
|
|
else
|
|
{
|
|
if (CurrentActiveWeapon.autoReload && !shooterManager.WeaponHasLoadedAmmo() && shooterManager.WeaponHasUnloadedAmmo())
|
|
{
|
|
switch (CurrentActiveWeapon.autoReloadStyle)
|
|
{
|
|
case vShooterWeapon.AutoReloadStyle.WhenAiming:
|
|
if (IsAiming) shooterManager.ReloadWeapon();
|
|
break;
|
|
case vShooterWeapon.AutoReloadStyle.WhenShot:
|
|
if (inputReader.ConsumeAttack()) shooterManager.ReloadWeapon();
|
|
break;
|
|
case vShooterWeapon.AutoReloadStyle.WhenAmmoAvailable:
|
|
shooterManager.ReloadWeapon();
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Control Switch Camera side Input
|
|
/// </summary>
|
|
public virtual void SwitchCameraSideInput()
|
|
{
|
|
if (tpCamera == null || inputReader == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (inputReader.ConsumeSwitchSide())
|
|
{
|
|
SwitchCameraSide();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Change side view of the <seealso cref="Invector.vCamera.vThirdPersonCamera"/>
|
|
/// </summary>
|
|
public virtual void SwitchCameraSide()
|
|
{
|
|
if (tpCamera == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
isCameraRightSwitched = !isCameraRightSwitched;
|
|
tpCamera.SwitchRight(isCameraRightSwitched);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset the Aiming and AimCanvas to false
|
|
/// </summary>
|
|
public virtual void CancelAiming()
|
|
{
|
|
isAimingByInput = false;
|
|
_aimTiming = 0;
|
|
if (controlAimCanvas)
|
|
{
|
|
controlAimCanvas.SetActiveAim(false);
|
|
controlAimCanvas.SetActiveScopeCamera(false);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Control Scope view input
|
|
/// </summary>
|
|
public virtual void ScopeViewInput()
|
|
{
|
|
if (!shooterManager || CurrentActiveWeapon == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (isAimingByInput && aimConditions && (inputReader.ConsumeScopeView() || CurrentActiveWeapon.onlyUseScopeUIView))
|
|
{
|
|
if (controlAimCanvas && CurrentActiveWeapon.scopeTarget)
|
|
{
|
|
if (!isUsingScopeView && CurrentActiveWeapon.onlyUseScopeUIView)
|
|
{
|
|
EnableScopeView();
|
|
}
|
|
else if (isUsingScopeView && !CurrentActiveWeapon.onlyUseScopeUIView)
|
|
{
|
|
DisableScopeView();
|
|
}
|
|
else if (!isUsingScopeView)
|
|
{
|
|
EnableScopeView();
|
|
}
|
|
}
|
|
}
|
|
else if (isUsingScopeView && (controlAimCanvas && !isAimingByInput || controlAimCanvas && !aimConditions || cc.isRolling))
|
|
{
|
|
DisableScopeView();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enable scope view (just if is aiming)
|
|
/// </summary>
|
|
public virtual void EnableScopeView()
|
|
{
|
|
if (!isAimingByInput || !controlAimCanvas.scopeBackgroundCamera || isReloading || isEquipping)
|
|
{
|
|
return;
|
|
}
|
|
|
|
isUsingScopeView = true;
|
|
|
|
controlAimCanvas.SetActiveScopeCamera(true, CurrentActiveWeapon.useUI);
|
|
controlAimCanvas.SetActiveAim(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disable scope view
|
|
/// </summary>
|
|
public virtual void DisableScopeView()
|
|
{
|
|
if (!controlAimCanvas.scopeBackgroundCamera) return;
|
|
isUsingScopeView = false;
|
|
var lastState = tpCamera.useSmooth;
|
|
tpCamera.useSmooth = false;
|
|
tpCamera.mouseX = lastTargetCameraEuler.y;
|
|
tpCamera.mouseY = lastTargetCameraEuler.x;
|
|
tpCamera.CameraMovement();
|
|
tpCamera.useSmooth = lastState;
|
|
controlAimCanvas.SetActiveScopeCamera(false);
|
|
controlAimCanvas.SetActiveAim(IsAiming);
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Update Animations
|
|
|
|
protected override void UpdateMeleeAnimations()
|
|
{
|
|
// disable the onlyarms layer and run the melee methods if the character is not using any shooter weapon
|
|
if (!animator)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// find states with the IsEquipping tag
|
|
isEquipping = cc.IsAnimatorTag("IsEquipping");
|
|
// Check if Animator state need to ignore IK
|
|
_ignoreIKFromAnimator = cc.IsAnimatorTag("IgnoreIK");
|
|
|
|
if (cc.customAction)
|
|
{
|
|
ResetMeleeAnimations();
|
|
ResetShooterAnimations();
|
|
// reset to the default camera state
|
|
UpdateCameraStates();
|
|
// reset the aiming
|
|
CancelAiming();
|
|
return;
|
|
}
|
|
// update MeleeManager Animator Properties
|
|
if ((shooterManager == null || !CurrentActiveWeapon) && meleeManager)
|
|
{
|
|
base.UpdateMeleeAnimations();
|
|
// set the uppbody id (armsonly layer)
|
|
//animator.SetFloat(vAnimatorParameters.UpperBody_ID, 0, .2f, Time.fixedDeltaTime);
|
|
// turn on the onlyarms layer to aim
|
|
onlyArmsLayerWeight = Mathf.Lerp(onlyArmsLayerWeight, 0, 6f * vTime.fixedDeltaTime);
|
|
animator.SetLayerWeight(onlyArmsLayer, onlyArmsLayerWeight);
|
|
// reset aiming parameter
|
|
animator.SetBool(vAnimatorParameters.IsAiming, false);
|
|
// animator.SetBool(vAnimatorParameters.IsHipFire, false);
|
|
isReloading = false;
|
|
}
|
|
// update ShooterManager Animator Properties
|
|
else if (shooterManager && CurrentActiveWeapon)
|
|
{
|
|
UpdateShooterAnimations();
|
|
}
|
|
// reset Animator Properties
|
|
else
|
|
{
|
|
ResetMoveSet();
|
|
ResetMeleeAnimations();
|
|
ResetShooterAnimations();
|
|
}
|
|
}
|
|
|
|
public virtual void ResetMoveSet()
|
|
{
|
|
cc.animator.SetFloat(vAnimatorParameters.MoveSet_ID, defaultMoveSetID, .2f, Time.fixedDeltaTime);
|
|
}
|
|
|
|
public virtual void ResetShooterAnimations()
|
|
{
|
|
if (shooterManager == null || !animator)
|
|
{
|
|
return;
|
|
}
|
|
// set the uppbody id (armsonly layer)
|
|
animator.SetFloat(vAnimatorParameters.UpperBody_ID, 0, .2f, vTime.fixedDeltaTime);
|
|
// set if the character can aim or not (upperbody layer)
|
|
animator.SetBool(vAnimatorParameters.CanAim, false);
|
|
// character is aiming
|
|
animator.SetBool(vAnimatorParameters.IsAiming, false);
|
|
// animator.SetBool(vAnimatorParameters.IsHipFire, false);
|
|
// turn on the onlyarms layer to aim
|
|
onlyArmsLayerWeight = Mathf.Lerp(onlyArmsLayerWeight, 0, 6f * vTime.fixedDeltaTime);
|
|
animator.SetLayerWeight(onlyArmsLayer, onlyArmsLayerWeight);
|
|
}
|
|
|
|
protected virtual void UpdateShooterAnimations()
|
|
{
|
|
if (shooterManager == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// turn on the onlyarms layer to aim
|
|
onlyArmsLayerWeight = Mathf.Lerp(onlyArmsLayerWeight, (CurrentActiveWeapon || isEquipping) ? 1f : 0f, shooterManager.onlyArmsSpeed * vTime.fixedDeltaTime);
|
|
animator.SetLayerWeight(onlyArmsLayer, onlyArmsLayerWeight);
|
|
if (CurrentActiveWeapon && IsAiming) animator.SetLayerWeight(shotLayer, isUsingScopeView ? CurrentActiveWeapon.scopeShootAnimationWeight : 1f);
|
|
if (CurrentActiveWeapon && !shooterManager.useDefaultMovesetWhenNotAiming || IsAiming)
|
|
{
|
|
// set the move set id (base layer)
|
|
animator.SetFloat(vAnimatorParameters.MoveSet_ID, shooterMoveSetID, .1f, vTime.fixedDeltaTime);
|
|
}
|
|
else if (!CurrentActiveWeapon && !shooterManager.useDefaultMovesetWhenNotAiming || shooterManager.useDefaultMovesetWhenNotAiming)
|
|
{
|
|
// set the move set id (base layer)
|
|
animator.SetFloat(vAnimatorParameters.MoveSet_ID, defaultMoveSetID, .1f, vTime.fixedDeltaTime);
|
|
}
|
|
animator.SetInteger(vAnimatorParameters.DefenseID, DefenseID);
|
|
// set the isBlocking false while using shooter weapons
|
|
animator.SetBool(vAnimatorParameters.IsBlocking, isBlocking);
|
|
// set the uppbody id (armsonly layer)
|
|
animator.SetFloat(vAnimatorParameters.UpperBody_ID, shooterManager.GetUpperBodyID());
|
|
// set if the character can aim or not (upperbody layer)
|
|
animator.SetBool(vAnimatorParameters.CanAim, aimConditions);
|
|
// character is aiming
|
|
animator.SetBool(vAnimatorParameters.IsAiming, IsAiming);
|
|
// animator.SetBool(vAnimatorParameters.IsHipFire, isAimingByHipFire);
|
|
// find states with the Reload tag
|
|
isReloading = cc.IsAnimatorTag("IsReloading") || shooterManager.isReloadingWeapon;
|
|
|
|
|
|
vAnimatorParameter ap = new vAnimatorParameter(animator, "IsReloading");
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Current moveset id based if is using weapon or not
|
|
/// </summary>
|
|
public virtual int shooterMoveSetID
|
|
{
|
|
get
|
|
{
|
|
int id = shooterManager.GetMoveSetID();
|
|
if (id == 0 || overrideWeaponMoveSetID)
|
|
{
|
|
id = defaultMoveSetID;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
}
|
|
|
|
public override void UpdateCameraStates()
|
|
{
|
|
// CAMERA STATE - you can change the CameraState here, the bool means if you want lerp of not, make sure to use the same CameraState String that you named on TPCameraListData
|
|
if (ignoreTpCamera)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (tpCamera == null)
|
|
{
|
|
tpCamera = FindObjectOfType<vCamera.vThirdPersonCamera>();
|
|
if (tpCamera == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (tpCamera)
|
|
{
|
|
tpCamera.SetMainTarget(this.transform);
|
|
tpCamera.Init();
|
|
}
|
|
}
|
|
|
|
if (changeCameraState)
|
|
{
|
|
tpCamera.ChangeState(customCameraState, customlookAtPoint, true);
|
|
}
|
|
else if (cc.isCrouching && !isAimingByInput)
|
|
{
|
|
tpCamera.ChangeState("Crouch", true);
|
|
}
|
|
else if (cc.isStrafing && !isAimingByInput)
|
|
{
|
|
tpCamera.ChangeState("Strafing", true);
|
|
}
|
|
else if (isAimingByInput && CurrentActiveWeapon)
|
|
{
|
|
if (isUsingScopeView)
|
|
{
|
|
if (string.IsNullOrEmpty(CurrentActiveWeapon.customScopeCameraState))
|
|
{
|
|
tpCamera.ChangeState(cc.isCrouching ? "CrouchingAiming" : "Aiming", true);
|
|
}
|
|
else
|
|
{
|
|
tpCamera.ChangeState(CurrentActiveWeapon.customScopeCameraState, true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (string.IsNullOrEmpty(CurrentActiveWeapon.customAimCameraState))
|
|
{
|
|
tpCamera.ChangeState(cc.isCrouching ? "CrouchingAiming" : "Aiming", true);
|
|
}
|
|
else
|
|
{
|
|
tpCamera.ChangeState(CurrentActiveWeapon.customAimCameraState, true);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tpCamera.ChangeState("Default", true);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Update Aim
|
|
|
|
protected Ray ray = new Ray();
|
|
/// <summary>
|
|
/// Calculate the <see cref="DesiredAimPosition"/>
|
|
/// </summary>
|
|
protected virtual void UpdateDesiredAimPosition()
|
|
{
|
|
if (!shooterManager)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (CurrentActiveWeapon == null)
|
|
{
|
|
return;
|
|
}
|
|
if (isUsingScopeView)
|
|
{
|
|
DesiredAimPosition = cameraMain.transform.TransformPoint(localAimPosition);
|
|
return;
|
|
}
|
|
var camT = cameraMain.transform;
|
|
|
|
var vOrigin = camT.position;
|
|
var desiredAimPoint = camT.position + camT.forward * cameraMain.farClipPlane;
|
|
|
|
ray.origin = vOrigin;
|
|
ray.direction = camT.forward;
|
|
if (shooterManager.raycastAimTarget && CurrentActiveWeapon.raycastAimTarget)
|
|
{
|
|
RaycastHit hit;
|
|
if (Physics.Raycast(ray, out hit, cameraMain.farClipPlane, shooterManager.damageLayer))
|
|
{
|
|
bool canAimToHit = false;
|
|
var dist = cameraMain.farClipPlane;
|
|
|
|
//Check if hit object is child of character transform
|
|
if (hit.collider.transform.IsChildOf(transform))
|
|
{
|
|
var collider = hit.collider;
|
|
//Clear last hit infor
|
|
hit = new RaycastHit();
|
|
var hits = Physics.RaycastAll(ray, cameraMain.farClipPlane, shooterManager.damageLayer);
|
|
///Try to find other hit point next to character transform
|
|
for (int i = 0; i < hits.Length; i++)
|
|
{
|
|
if (hits[i].distance < dist && hits[i].collider.gameObject != collider.gameObject && !hits[i].collider.transform.IsChildOf(transform))
|
|
{
|
|
dist = hits[i].distance;
|
|
hit = hits[i];
|
|
canAimToHit = true;
|
|
}
|
|
}
|
|
}
|
|
else canAimToHit = true;
|
|
|
|
if (canAimToHit)
|
|
{
|
|
desiredAimPoint = hit.point;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
var localAimPoint = aimAngleReference.transform.InverseTransformPoint(desiredAimPoint);
|
|
if (!isUsingScopeView)
|
|
{
|
|
if (!shooterManager.ignoreBackAimPoint) localAimPoint.z = Mathf.Max(localAimPoint.z, (muzzlePosition.z + shooterManager.backAimPointOffset + shooterManager.minAimHitPointDistance));
|
|
desiredAimPoint = aimAngleReference.transform.TransformPoint(localAimPoint);
|
|
}
|
|
DesiredAimPosition = desiredAimPoint;
|
|
localAimPosition = cameraMain.transform.InverseTransformPoint(DesiredAimPosition);
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Calculate the <see cref="AimPosition"/>
|
|
/// </summary>
|
|
protected virtual void UpdateAimPosition()
|
|
{
|
|
if (!shooterManager)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (CurrentActiveWeapon == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Vector3 rayDirection = DesiredAimPosition - CurrentActiveWeapon.aimReference.position;
|
|
ray.origin = CurrentActiveWeapon.aimReference.position;
|
|
ray.direction = rayDirection;
|
|
Vector3 desiredAimPoint = DesiredAimPosition;
|
|
|
|
|
|
RaycastHit hit;
|
|
var castLayer = shooterManager.blockAimLayer;
|
|
var castDistance = rayDirection.magnitude;
|
|
var castRay = ray;
|
|
|
|
if (Physics.Raycast(castRay, out hit, castDistance, castLayer))
|
|
{
|
|
bool canAimToHit = false;
|
|
var dist = cameraMain.farClipPlane;
|
|
|
|
//Check if hit object is child of character transform
|
|
if (hit.collider.transform.IsChildOf(transform))
|
|
{
|
|
var collider = hit.collider;
|
|
//Clear last hit infor
|
|
hit = new RaycastHit();
|
|
var hits = Physics.RaycastAll(castRay, castDistance, castLayer);
|
|
///Try to find other hit point next to character transform
|
|
for (int i = 0; i < hits.Length; i++)
|
|
{
|
|
if (hits[i].distance < dist && hits[i].collider.gameObject != collider.gameObject && !hits[i].collider.transform.IsChildOf(transform))
|
|
{
|
|
dist = hits[i].distance;
|
|
hit = hits[i];
|
|
canAimToHit = true;
|
|
}
|
|
}
|
|
}
|
|
else canAimToHit = true;
|
|
if (hit.collider && canAimToHit)
|
|
{
|
|
desiredAimPoint = hit.point;
|
|
}
|
|
|
|
}
|
|
|
|
AimPosition = desiredAimPoint;
|
|
|
|
if (isUsingScopeView)
|
|
{
|
|
var rotation = Quaternion.LookRotation(AimPosition - cameraMain.transform.position, cameraMain.transform.up);
|
|
lastTargetCameraEuler = rotation.eulerAngles.NormalizeAngle();
|
|
}
|
|
|
|
if (isAimingByInput)
|
|
{
|
|
shooterManager.CameraSway();
|
|
}
|
|
|
|
}
|
|
|
|
public override void ControlRotation()
|
|
{
|
|
|
|
base.ControlRotation();
|
|
}
|
|
|
|
public override void CameraInput()
|
|
{
|
|
|
|
base.CameraInput();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IK behaviour
|
|
|
|
protected virtual void UpdateAimBehaviour()
|
|
{
|
|
if (cc.isDead || cc.ragdolled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
UpdateDesiredAimPosition();
|
|
UpdateHeadTrack();
|
|
OnStartUpdateIK();
|
|
CheckAimConditions();
|
|
if (shooterManager && CurrentActiveWeapon)
|
|
{
|
|
UpdateIKAdjust(shooterManager.IsLeftWeapon);
|
|
AlignArmToAimPosition(shooterManager.IsLeftWeapon);
|
|
UpdateArmsIK(shooterManager.IsLeftWeapon);
|
|
}
|
|
UpdateAimPosition();
|
|
OnFinishUpdateIK();
|
|
UpdateAimHud();
|
|
DoShots();
|
|
CheckAimEvents();
|
|
}
|
|
|
|
protected virtual void CheckAimEvents()
|
|
{
|
|
if (IsAiming != wasAiming)
|
|
{
|
|
wasAiming = IsAiming;
|
|
if (IsAiming) shooterManager.onEnableAim.Invoke(shooterManager.CurrentWeapon);
|
|
else shooterManager.onDisableAim.Invoke(shooterManager.CurrentWeapon);
|
|
}
|
|
if (isUsingScopeView != wasAimingWithScope)
|
|
{
|
|
wasAimingWithScope = isUsingScopeView;
|
|
if (IsAiming) shooterManager.onEnableScopeView.Invoke(shooterManager.CurrentWeapon);
|
|
else shooterManager.onDisableScopeView.Invoke(shooterManager.CurrentWeapon);
|
|
}
|
|
}
|
|
|
|
protected virtual void UpdateAimAngleReference()
|
|
{
|
|
aimAngleReference.transform.rotation = transform.rotation;
|
|
UpdateCheckAimHelpers(shooterManager.IsLeftWeapon);
|
|
}
|
|
|
|
protected void UpdateCheckAimHelpers(bool isUsingLeftHand)
|
|
{
|
|
if (!CurrentActiveWeapon) return;
|
|
var weight = (float)System.Math.Round(armAlignmentWeight, 1);
|
|
var upperArm = isUsingLeftHand ? leftUpperArm : rightUpperArm;
|
|
upperArmPosition = Vector3.Lerp(upperArmPosition, aimAngleReference.transform.InverseTransformPoint(upperArm.position), weight);
|
|
muzzlePosition = Vector3.Lerp(muzzlePosition, aimAngleReference.transform.InverseTransformPoint(CurrentActiveWeapon.muzzle.position), weight);
|
|
muzzleForward = Vector3.Lerp(muzzleForward, aimAngleReference.transform.InverseTransformDirection(CurrentActiveWeapon.muzzle.forward), weight);
|
|
|
|
}
|
|
|
|
public virtual void UpdateCheckAimPoints(ref Vector3 start, ref Vector3 end)
|
|
{
|
|
if (CurrentActiveWeapon)
|
|
{
|
|
float checkAimSmooth = shooterManager.checkAimOffsetSmooth;
|
|
///Lerp offsets
|
|
checkCanAimOffsetStartX = Mathf.Lerp(checkCanAimOffsetStartX, IsCrouching ? shooterManager.checkAimCrouchedOffsetStartX : shooterManager.checkAimStandingOffsetStartX, checkAimSmooth * Time.fixedDeltaTime);
|
|
checkCanAimOffsetStartY = Mathf.Lerp(checkCanAimOffsetStartY, IsCrouching ? shooterManager.checkAimCrouchedOffsetStartY : shooterManager.checkAimStandingOffsetStartY, checkAimSmooth * Time.fixedDeltaTime);
|
|
checkCanAimOffsetEndX = Mathf.Lerp(checkCanAimOffsetEndX, IsCrouching ? shooterManager.checkAimCrouchedOffsetEndX : shooterManager.checkAimStandingOffsetEndX, checkAimSmooth * Time.fixedDeltaTime);
|
|
checkCanAimOffsetEndY = Mathf.Lerp(checkCanAimOffsetEndY, IsCrouching ? shooterManager.checkAimCrouchedOffsetEndY : shooterManager.checkAimStandingOffsetEndY, checkAimSmooth * Time.fixedDeltaTime);
|
|
|
|
var startX = checkCanAimOffsetStartX;
|
|
var startY = checkCanAimOffsetStartY;
|
|
var endX = checkCanAimOffsetEndX;
|
|
var endY = checkCanAimOffsetEndY;
|
|
|
|
onUpdateCheckAimPointsEvent?.Invoke(ref startX, ref endX, ref startY, ref endY);
|
|
/// Make original points to check aim
|
|
Vector3 startPoint = aimAngleReference.transform.TransformPoint(upperArmPosition);
|
|
float upperArmToMuzzleDistance = Vector3.Distance(startPoint, aimAngleReference.transform.TransformPoint(muzzlePosition));
|
|
var endPoint = startPoint + (DesiredAimPosition - startPoint).normalized * upperArmToMuzzleDistance;
|
|
Vector3 forward = (DesiredAimPosition - startPoint).normalized;
|
|
///Apply offsets
|
|
Vector3 newStartPoint = startPoint + cameraMain.transform.right * (startX * (tpCamera.switchRight > 0 ? 1 : -1)) + cameraMain.transform.up * startY;
|
|
Vector3 newEndPoint = endPoint + cameraMain.transform.right * (endX * (tpCamera.switchRight > 0 ? 1 : -1)) + cameraMain.transform.up * endY + forward * shooterManager.checkAimOffsetZ;
|
|
|
|
start = newStartPoint;
|
|
end = newEndPoint;
|
|
}
|
|
}
|
|
public delegate void UpdateCheckAimPointsEvent(ref float startX, ref float endX,ref float startY,ref float endY);
|
|
public UpdateCheckAimPointsEvent onUpdateCheckAimPointsEvent;
|
|
protected virtual void OnFinishUpdateIK()
|
|
{
|
|
onFinishUpdateIK?.Invoke();
|
|
}
|
|
|
|
protected virtual void OnStartUpdateIK()
|
|
{
|
|
onStartUpdateIK?.Invoke();
|
|
}
|
|
|
|
protected virtual void UpdateIKAdjust(bool isUsingLeftHand)
|
|
{
|
|
|
|
// create left arm ik solver if equal null
|
|
if (LeftIK == null || !LeftIK.isValidBones)
|
|
{
|
|
LeftIK = new vIKSolver(animator, AvatarIKGoal.LeftHand);
|
|
LeftIK.UpdateIK();
|
|
}
|
|
if (RightIK == null || !RightIK.isValidBones)
|
|
{
|
|
RightIK = new vIKSolver(animator, AvatarIKGoal.RightHand);
|
|
RightIK.UpdateIK();
|
|
}
|
|
|
|
|
|
if (WeaponIKAdjustList == null) return;
|
|
else
|
|
{
|
|
CurrentActiveWeapon.handIKTargetOffset.localPosition = isUsingLeftHand ? WeaponIKAdjustList.ikTargetPositionOffsetL : WeaponIKAdjustList.ikTargetPositionOffsetR;
|
|
CurrentActiveWeapon.handIKTargetOffset.localEulerAngles = isUsingLeftHand ? WeaponIKAdjustList.ikTargetRotationOffsetL : WeaponIKAdjustList.ikTargetRotationOffsetR;
|
|
}
|
|
|
|
if (!CurrentWeaponIK )
|
|
{
|
|
LeftIK.UpdateIK();
|
|
RightIK.UpdateIK();
|
|
RightIK.SetIKWeight(0);
|
|
LeftIK.SetIKWeight(0);
|
|
weaponIKWeight = 0;
|
|
return;
|
|
}
|
|
bool isValidIK = !IsIgnoreIK && !cc.customAction && !isReloading && !isEquipping && CurrentWeaponIK != null && CurrentIKAdjust != null;
|
|
weaponIKWeight = Mathf.Lerp(weaponIKWeight, isValidIK ? 1 : 0, shooterManager.ikAdjustSmooth*Time.fixedDeltaTime);
|
|
if (weaponIKWeight <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (isUsingLeftHand)
|
|
{
|
|
ApplyOffsets(LeftIK, RightIK, isValidIK);
|
|
}
|
|
else
|
|
{
|
|
ApplyOffsets(RightIK, LeftIK, isValidIK);
|
|
}
|
|
}
|
|
|
|
protected virtual void ApplyOffsets(vIKSolver weaponHand, vIKSolver supportHand, bool isValidIK = true)
|
|
{
|
|
if (!weaponHand.isValidBones || !supportHand.isValidBones) return;
|
|
//Apply Offset to Weapon Arm
|
|
weaponHand.SetIKWeight(shooterManager.ikAdjustWeightCurve.Evaluate(weaponIKWeight));
|
|
ApplyOffsetToTargetBone(isValidIK ? CurrentIKAdjust.weaponHandOffset : null, weaponHand.endBoneOffset, isValidIK);
|
|
ApplyOffsetToTargetBone(isValidIK ? CurrentIKAdjust.weaponHintOffset : null, weaponHand.middleBoneOffset, isValidIK);
|
|
weaponHand.AnimationToIK();
|
|
//Apply offset to Support Weapon Arm
|
|
ApplyOffsetToTargetBone(isValidIK ? CurrentIKAdjust.supportHandOffset : null, supportHand.endBoneOffset, !EditingIKGlobalOffset && isValidIK);
|
|
ApplyOffsetToTargetBone(isValidIK ? CurrentIKAdjust.supportHintOffset : null, supportHand.middleBoneOffset, !EditingIKGlobalOffset && isValidIK);
|
|
}
|
|
|
|
protected virtual void ApplyOffsetToTargetBone(IKOffsetTransform iKOffset, Transform target, bool isValidIK)
|
|
{
|
|
try
|
|
{
|
|
target.localPosition = Vector3.Lerp(target.localPosition, isValidIK ? iKOffset.position : Vector3.zero, shooterManager.ikAdjustSmooth * vTime.fixedDeltaTime);
|
|
target.localRotation = Quaternion.Lerp(target.localRotation, isValidIK ? Quaternion.Euler(iKOffset.eulerAngles) : Quaternion.Euler(Vector3.zero), shooterManager.ikAdjustSmooth * vTime.fixedDeltaTime);
|
|
}
|
|
catch
|
|
{
|
|
Debug.LogWarning("Can't Get IK Adjust");
|
|
}
|
|
}
|
|
|
|
protected virtual void UpdateArmsIK(bool isUsingLeftHand = false)
|
|
{
|
|
// create left arm ik solver if equal null
|
|
if (LeftIK == null || !LeftIK.isValidBones)
|
|
{
|
|
LeftIK = new vIKSolver(animator, AvatarIKGoal.LeftHand);
|
|
}
|
|
|
|
if (RightIK == null || !RightIK.isValidBones)
|
|
{
|
|
RightIK = new vIKSolver(animator, AvatarIKGoal.RightHand);
|
|
}
|
|
|
|
vIKSolver targetIK = null;
|
|
|
|
if (isUsingLeftHand)
|
|
{
|
|
targetIK = RightIK;
|
|
}
|
|
else
|
|
{
|
|
targetIK = LeftIK;
|
|
}
|
|
bool useIK = isUsingLeftHand ? shooterManager.useLeftIK : shooterManager.useRightIK;
|
|
if ((!shooterManager || !CurrentActiveWeapon || IsIgnoreIK || isEquipping) ||
|
|
(cc.IsAnimatorTag("Shot Fire") && CurrentActiveWeapon.disableIkOnShot))
|
|
{
|
|
useIK = false;
|
|
}
|
|
|
|
bool useIkConditions = false;
|
|
var animatorInput = System.Math.Round(cc.inputMagnitude, 1);
|
|
if(!useIK)
|
|
{
|
|
useIkConditions = false;
|
|
}
|
|
else if (!IsAiming && !isAttacking)
|
|
{
|
|
var locomotionValidation = cc.isStrafing ? CurrentActiveWeapon.strafeIKOptions : CurrentActiveWeapon.freeIKOptions;
|
|
if (locomotionValidation.use)
|
|
{
|
|
if (animatorInput <= 0.1f)
|
|
{
|
|
useIkConditions = locomotionValidation.useOnIdle;
|
|
}
|
|
else if (animatorInput <= 0.5f)
|
|
{
|
|
useIkConditions = locomotionValidation.useOnWalk;
|
|
}
|
|
else if (animatorInput <= 1f)
|
|
{
|
|
useIkConditions = locomotionValidation.useOnRun;
|
|
}
|
|
else if (animatorInput <= 1.5f)
|
|
{
|
|
useIkConditions = locomotionValidation.useOnSprint;
|
|
}
|
|
}
|
|
else useIkConditions = false;
|
|
}
|
|
else if (IsAiming && !isAttacking)
|
|
{
|
|
useIkConditions = shooterManager.isShooting ? !CurrentActiveWeapon.disableIkOnShot : CurrentActiveWeapon.useIKOnAiming;
|
|
}
|
|
else if (isAttacking)
|
|
{
|
|
useIkConditions = CurrentActiveWeapon.useIkAttacking;
|
|
}
|
|
|
|
|
|
IsSupportHandIKEnabled = useIkConditions && !IsIgnoreSupportHandIK;
|
|
|
|
if (targetIK != null)
|
|
{
|
|
if (shooterManager.weaponIKAdjustList)
|
|
{
|
|
if (isUsingLeftHand)
|
|
{
|
|
ikRotationOffset = shooterManager.weaponIKAdjustList.ikTargetRotationOffsetR;
|
|
ikPositionOffset = shooterManager.weaponIKAdjustList.ikTargetPositionOffsetR;
|
|
}
|
|
else
|
|
{
|
|
ikRotationOffset = shooterManager.weaponIKAdjustList.ikTargetRotationOffsetL;
|
|
ikPositionOffset = shooterManager.weaponIKAdjustList.ikTargetPositionOffsetL;
|
|
}
|
|
}
|
|
|
|
// Debug.Log($"using ik {useIkConditions.ToStringColor()}");//Debug IK Conditions
|
|
// control weight of ik
|
|
if (CurrentActiveWeapon && CurrentActiveWeapon.handIKTargetOffset && !isReloading && !cc.customAction && (cc.isGrounded || (IsAiming)) && IsSupportHandIKEnabled)
|
|
{
|
|
supportIKWeight = Mathf.Lerp(supportIKWeight, 1, shooterManager.armIKSmoothIn * vTime.fixedDeltaTime);
|
|
}
|
|
else
|
|
{
|
|
supportIKWeight = Mathf.Lerp(supportIKWeight, 0, shooterManager.armIKSmoothOut * vTime.fixedDeltaTime);
|
|
}
|
|
|
|
if (supportIKWeight <= 0 )
|
|
{
|
|
if (!IsSupportHandIKEnabled && shooterManager.CurrentWeaponIK)
|
|
{
|
|
targetIK.SetIKWeight(shooterManager.armIKCurve.Evaluate(supportIKWeight));
|
|
targetIK.AnimationToIK();
|
|
}
|
|
return;
|
|
}
|
|
|
|
// update IK
|
|
targetIK.SetIKWeight(shooterManager.armIKCurve.Evaluate(supportIKWeight));
|
|
if (shooterManager && CurrentActiveWeapon && CurrentActiveWeapon.handIKTargetOffset)
|
|
{
|
|
|
|
targetIK.SetIKPosition(CurrentActiveWeapon.handIKTargetOffset.position);
|
|
targetIK.SetIKRotation(CurrentActiveWeapon.handIKTargetOffset.rotation);
|
|
|
|
|
|
if (shooterManager.CurrentWeaponIK)
|
|
{
|
|
targetIK.AnimationToIK();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual bool CanRotateAimArm()
|
|
{
|
|
return cc.IsAnimatorTag("Upperbody Pose") && cc.animatorStateInfos.GetCurrentNormalizedTime(cc.upperBodyLayer) > 0.5f;
|
|
}
|
|
|
|
protected virtual bool CanDoShots()
|
|
{
|
|
return armAlignmentWeight >= 0.5f && cc.IsAnimatorTag("Upperbody Pose") && shootCountA > 0 && !isReloading;
|
|
}
|
|
|
|
protected virtual void AlignArmToAimPosition(bool isUsingLeftHand = false)
|
|
{
|
|
if (!shooterManager)
|
|
{
|
|
return;
|
|
}
|
|
///Init the arms, if needs that
|
|
if (leftArmAim == null) leftArmAim = new vArmAimAlign(leftUpperArm, leftLowerArm, leftHand);
|
|
if (rightArmAim == null) rightArmAim = new vArmAimAlign(rightUpperArm, rightLowerArm, rightHand);
|
|
/// Select the arm
|
|
vArmAimAlign arm = isUsingLeftHand ? leftArmAim : rightArmAim;
|
|
|
|
///Calculate the Alignment weight based on aim conditions.
|
|
armAlignmentWeight = IsAiming && aimConditions && CanRotateAimArm() ? Mathf.Lerp(armAlignmentWeight, Mathf.Clamp(cc.upperBodyInfo.normalizedTime, 0, 1f), shooterManager.smoothArmWeight * (.001f + Time.fixedDeltaTime)) : 0;
|
|
|
|
if (CurrentActiveWeapon)
|
|
{
|
|
if (!shooterManager.isShooting)
|
|
{
|
|
///Update arm to use default animation rotation while not shooting
|
|
arm.UpdateDefaultAlignment();
|
|
}
|
|
else
|
|
{
|
|
///Use last alignment to ignore shoot animation rotation
|
|
///When shooting the arm position and rotation will be changed by the animation
|
|
///This method avoid this changes using the last alignment before the shot was performed
|
|
arm.RestoreToLastAlignment();
|
|
}
|
|
/// Set the Arm aligment values
|
|
arm.smoothIKAlignmentPoint = shooterManager.smoothIKAlignmentPoint;
|
|
arm.aimReference = CurrentActiveWeapon.aimReference;
|
|
arm.smooth = shooterManager.smoothArmIKRotation;
|
|
arm.maxVerticalAligmentAngle = shooterManager.maxVerticalAimAngle;
|
|
arm.maxHorizontalAligmentAngle = shooterManager.maxHorizontalAimAngle;
|
|
if (shooterManager.showCheckAimGizmos) arm.DrawBones(Color.blue);
|
|
///Align arm to target aim position
|
|
|
|
arm.AlignToArmToPosition(targetArmAlignmentPosition, armAlignmentWeight, CurrentActiveWeapon.alignRightUpperArmToAim, CurrentActiveWeapon.alignRightHandToAim);
|
|
if (shooterManager.showCheckAimGizmos) arm.DrawHelpers(Color.green);
|
|
}
|
|
}
|
|
|
|
protected virtual void CheckAimConditions()
|
|
{
|
|
if (!shooterManager)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var weaponSide = (tpCamera.switchRight < 0 ? -1 : 1);
|
|
|
|
if (CurrentActiveWeapon == null)
|
|
{
|
|
aimConditions = false;
|
|
return;
|
|
}
|
|
|
|
if (shooterManager.useCheckAim == false)
|
|
{
|
|
aimConditions = true;
|
|
return;
|
|
}
|
|
Vector3 startPoint = Vector3.zero;
|
|
Vector3 endPoint = Vector3.zero;
|
|
Ray _ray = new Ray(startPoint, ((endPoint) - startPoint).normalized);
|
|
bool _aimCondition = aimConditions;
|
|
if (animator.IsInTransition(0))
|
|
{
|
|
if (Physics.SphereCast(_ray, shooterManager.checkAimRadius, out checkCanAimHit, (endPoint - startPoint).magnitude, shooterManager.blockAimLayer))
|
|
{
|
|
aimConditions = false;
|
|
}
|
|
_aimCondition = aimConditions;
|
|
checkAimConditionOverride?.Invoke(startPoint, endPoint, ref _aimCondition);
|
|
aimConditions = _aimCondition;
|
|
return;
|
|
}
|
|
|
|
|
|
UpdateCheckAimPoints(ref startPoint, ref endPoint);
|
|
_ray = new Ray(startPoint, ((endPoint) - startPoint).normalized);
|
|
if (Vector3.Distance(startPoint, AimPosition) < Vector3.Distance(startPoint, endPoint))
|
|
aimConditions = false;
|
|
|
|
|
|
if (Physics.SphereCast(_ray, shooterManager.checkAimRadius, out checkCanAimHit, (endPoint - startPoint).magnitude, shooterManager.blockAimLayer))
|
|
{
|
|
aimConditions = false;
|
|
}
|
|
else
|
|
{
|
|
aimConditions = true;
|
|
}
|
|
_aimCondition = aimConditions;
|
|
checkAimConditionOverride?.Invoke(startPoint, endPoint, ref _aimCondition);
|
|
aimConditions = _aimCondition;
|
|
}
|
|
public delegate void CheckAimConditionsEvent( Vector3 startPoint, Vector3 endPoint,ref bool aimConditions);
|
|
public CheckAimConditionsEvent checkAimConditionOverride;
|
|
protected virtual Vector3 targetArmAlignmentPosition
|
|
{
|
|
get
|
|
{
|
|
return shooterManager.alignArmToHitPoint || isUsingScopeView ? DesiredAimPosition : cameraMain.transform.position + cameraMain.transform.forward * 100;
|
|
}
|
|
}
|
|
|
|
protected virtual Transform targetCamera
|
|
{
|
|
get
|
|
{
|
|
var t = controlAimCanvas && controlAimCanvas.isScopeCameraActive && controlAimCanvas.scopeBackgroundCamera ? controlAimCanvas.scopeBackgroundCamera.transform : cameraMain.transform;
|
|
return t;
|
|
}
|
|
}
|
|
|
|
protected virtual Vector3 targetArmAlignmentDirection
|
|
{
|
|
get
|
|
{
|
|
|
|
return targetCamera.forward;
|
|
}
|
|
}
|
|
|
|
protected virtual void UpdateHeadTrack()
|
|
{
|
|
if (headTrack)
|
|
{
|
|
UpdateHeadTrackLookPoint();
|
|
}
|
|
if (!shooterManager || !headTrack)
|
|
{
|
|
if (headTrack)
|
|
{
|
|
headTrack.offsetSpine = Vector2.Lerp(headTrack.offsetSpine, Vector2.zero, weaponIKWeight);
|
|
headTrack.offsetHead = Vector2.Lerp(headTrack.offsetHead, Vector2.zero, weaponIKWeight);
|
|
}
|
|
return;
|
|
}
|
|
if (!CurrentActiveWeapon || !headTrack || !CurrentWeaponIK || CurrentIKAdjust == null)
|
|
{
|
|
if (headTrack)
|
|
{
|
|
headTrack.offsetSpine = Vector2.Lerp(headTrack.offsetSpine, Vector2.zero, weaponIKWeight);
|
|
headTrack.offsetHead = Vector2.Lerp(headTrack.offsetHead, Vector2.zero, weaponIKWeight);
|
|
}
|
|
return;
|
|
}
|
|
if (IsAiming)
|
|
{
|
|
var ikAdjust = CurrentIKAdjust;
|
|
var offsetSpine = ikAdjust.spineOffset.spine;
|
|
var offsetHead = ikAdjust.spineOffset.head;
|
|
headTrack.offsetSpine = Vector2.Lerp(headTrack.offsetSpine, offsetSpine, weaponIKWeight);
|
|
headTrack.offsetHead = Vector2.Lerp(headTrack.offsetHead, offsetHead, weaponIKWeight);
|
|
}
|
|
else
|
|
{
|
|
var ikAdjust = CurrentIKAdjust;
|
|
var offsetSpine = ikAdjust.spineOffset.spine;
|
|
var offsetHead = ikAdjust.spineOffset.head;
|
|
headTrack.offsetSpine = Vector2.Lerp(headTrack.offsetSpine, offsetSpine, headTrack.Smooth);
|
|
headTrack.offsetHead = Vector2.Lerp(headTrack.offsetHead, offsetHead, headTrack.Smooth);
|
|
}
|
|
}
|
|
|
|
protected virtual void UpdateHeadTrackLookPoint()
|
|
{
|
|
if (IsAiming /*&& !isUsingScopeView*/ && CurrentActiveWeapon && aimConditions)
|
|
{
|
|
headTrack.SetTemporaryLookPoint(targetArmAlignmentPosition); //cameraMain.transform.TransformPoint(Vector3.forward * (cameraMain.transform.InverseTransformPoint(CurrentActiveWeapon.muzzle.position).z + 10)), 0.1f);
|
|
}
|
|
}
|
|
|
|
protected virtual void UpdateAimHud()
|
|
{
|
|
|
|
if (!shooterManager || !controlAimCanvas)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (CurrentActiveWeapon == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var _aimPoint = AimPosition;
|
|
|
|
controlAimCanvas.SetAimCanvasID(CurrentActiveWeapon.scopeID);
|
|
if (controlAimCanvas.scopeBackgroundCamera && controlAimCanvas.scopeBackgroundCamera.gameObject.activeSelf)
|
|
{
|
|
|
|
controlAimCanvas.SetAimToCenter(true);
|
|
|
|
}
|
|
else if (IsAiming && aimConditions)
|
|
{
|
|
var aimDistance = Vector3.Distance(aimAngleReference.transform.position, _aimPoint);
|
|
var validAim = (aimDistance > shooterManager.maxAimHitPointIndicator || Vector3.Distance(AimPosition, DesiredAimPosition) < 0.1f) && aimConditions;
|
|
|
|
if (aimDistance > shooterManager.maxAimHitPointIndicator || Vector3.Distance(AimPosition, DesiredAimPosition) < 0.1f)
|
|
controlAimCanvas.SetAimToCenter(true);
|
|
else
|
|
controlAimCanvas.SetWordPosition(_aimPoint, validAim);
|
|
|
|
}
|
|
else
|
|
{
|
|
controlAimCanvas.SetAimToCenter(aimConditions);
|
|
}
|
|
|
|
if ((controlAimCanvas.scopeBackgroundCamera && CurrentActiveWeapon.scopeTarget))
|
|
{
|
|
if (isUsingScopeView || controlAimCanvas.isScopeCameraActive)
|
|
{
|
|
vArmAimAlign arm = shooterManager.IsLeftWeapon ? leftArmAim : rightArmAim;
|
|
if (!shooterManager.isShooting)
|
|
{
|
|
scopeLocalForward = arm.aimReferenceHelper.InverseTransformDirection(CurrentActiveWeapon.scopeTarget.forward);
|
|
scopeLocalPosition = arm.aimReferenceHelper.InverseTransformPoint(CurrentActiveWeapon.scopeTarget.position);
|
|
|
|
scopeCameraLocalForward = aimAngleReference.transform.InverseTransformDirection(controlAimCanvas.scopeBackgroundCamera.transform.forward);
|
|
scopeCameraLocalPosition = aimAngleReference.transform.InverseTransformPoint(controlAimCanvas.scopeBackgroundCamera.transform.position);
|
|
}
|
|
var weight = (shooterManager.isShooting ? (1 - CurrentActiveWeapon.scopeShootAnimationWeight) : 1f);
|
|
|
|
var scopCameraPosition = aimAngleReference.transform.TransformPoint(scopeCameraLocalPosition);
|
|
var scopCameraForward = aimAngleReference.transform.TransformDirection(scopeCameraLocalForward);
|
|
var scopeLookDirection = Vector3.Lerp(scopCameraForward, arm.aimReferenceHelper.TransformDirection(scopeLocalForward), scopeDirectionWeight = Mathf.Lerp(scopeDirectionWeight, 1.001f, (10f / CurrentActiveWeapon.shootFrequency) * Time.fixedDeltaTime));
|
|
var scopePosition = Vector3.Lerp(scopCameraPosition, arm.aimReferenceHelper.TransformPoint(scopeLocalPosition), weight);
|
|
controlAimCanvas.UpdateScopeCamera(scopePosition, scopeLookDirection, aimAngleReference.transform.up, CurrentActiveWeapon.backGroundScopeZoom, IsAiming);
|
|
}
|
|
else scopeDirectionWeight = 1f;
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
public static partial class vAnimatorParameters
|
|
{
|
|
public static int UpperBody_ID = Animator.StringToHash("UpperBody_ID");
|
|
public static int CanAim = Animator.StringToHash("CanAim");
|
|
public static int IsAiming = Animator.StringToHash("IsAiming");
|
|
public static int IsHipFire = Animator.StringToHash("IsHipFire");
|
|
public static int Shot_ID = Animator.StringToHash("Shot_ID");
|
|
public static int PowerCharger = Animator.StringToHash("PowerCharger");
|
|
}
|
|
} |