using UnityEngine; using System.Collections; using MalbersAnimations.Weapons; using MalbersAnimations.Utilities; namespace MalbersAnimations.HAP { ///────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── /// LOGIC ///────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── public partial class MWeaponManager { #region Reset Awake Start Update LateUpdate protected virtual void Awake() { Anim = GetComponent(); //Get the Animator Aimer = GetComponent(); Rider = GetComponent(); DefaultAnimUpdateMode = Anim.updateMode; defaultAimSide = Aimer.AimSide; StoreAfterTime = new WaitForSeconds(StoreAfter.Value); GetHashIDs(); Head = Anim.GetBoneTransform(HumanBodyBones.Head); //Get the Rider Head transform Chest = Anim.GetBoneTransform(HumanBodyBones.Chest); //Get the Rider Head transform RightHand = Anim.GetBoneTransform(HumanBodyBones.RightHand); //Get the Rider Right Hand transform LeftHand = Anim.GetBoneTransform(HumanBodyBones.LeftHand); //Get the Rider Left Hand transform RightShoulder = Anim.GetBoneTransform(HumanBodyBones.RightUpperArm); //Get the Rider Right Shoulder transform LeftShoulder = Anim.GetBoneTransform(HumanBodyBones.LeftUpperArm); //Get the Rider Left Shoulder transform } PrepareHolsters(); } private void OnEnable() { SetBoolParameter += SetAnimParameter; SetIntParameter += SetAnimParameter; SetFloatParameter += SetAnimParameter; SetTriggerParameter += SetAnimParameter; // Aimer.OnAiming.AddListener(Aim_Set); } private void OnDisable() { SetBoolParameter -= SetAnimParameter; SetIntParameter -= SetAnimParameter; SetFloatParameter -= SetAnimParameter; SetTriggerParameter -= SetAnimParameter; // Aimer.OnAiming.RemoveListener(Aim_Set); } protected virtual void GetHashIDs() { Hash_WAction = Animator.StringToHash(m_WeaponAction); Hash_WAim = Animator.StringToHash(m_WeaponAim); Hash_WType = Animator.StringToHash(m_WeaponType); Hash_WCharge = Animator.StringToHash(m_WeaponCharge); Hash_WHand = Animator.StringToHash(m_WeaponHand); } void FixedUpdate() { SetHorizontalAngle(); WeaponCharged(Time.fixedDeltaTime); } void LateUpdate() { if (Active && CombatMode && WeaponIsActive) { if (Aim) Weapon.LateUpdateWeaponIK(this); //Do the IK logic to the Character using the weapon Weapon.LateWeaponModification(this); //If there's an Active Ability do the Late Ability thingy } } void OnAnimatorIK() { if (Active && CombatMode && WeaponIsActive && WeaponIKW != 0) //If there's a Weapon Active { Weapon.OnAnimatorWeaponIK(this); if (Weapon.TwoHandIK) Weapon.TwoWeaponIK(this); } } #endregion protected virtual void WeaponCharged(float time) { if (Active && CombatMode && WeaponIsActive) //If there's a Weapon Active { Weapon.Attack_Charge(this, time); } } #region AIMSTUFFS ///────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── /// This method is used to activate the AIM mode when the right click is pressed public virtual void SetHorizontalAngle() { if (!Aimer.Active) Aimer.CalculateAiming(); //Recalculate when the Aimer is not Active float NewHorizontalAngle = Aimer.HorizontalAngle / 180; //Get the Normalized value for the look direction HorizontalAngle = Mathf.Lerp(HorizontalAngle, NewHorizontalAngle, Time.fixedDeltaTime * 10f); //Smooth Swap between 1 and -1 SetFloatParameter(Hash_WAim, HorizontalAngle); } /// Set the Value of the Weapon Charge on the Animator public void SetWeaponCharge(float Charge) => SetFloatParameter(Hash_WCharge, Charge * Weapon.ChargeCharMultiplier); public void SetWeaponHand() => SetBoolParameter(Hash_WHand, Weapon.IsRightHanded); #endregion #region Draw Store Equip Unequip Weapons /// If the Rider had a weapon before mounting.. equip it. /// The weapon need an |IMWeapon| Interface, if not it wont be equiped public virtual void SetWeaponBeforeMounting(GameObject weapon) => SetWeaponBeforeMounting(weapon.GetComponent()); /// If the Rider had a weapon before mounting.. equip it. /// The weapon need an |IMWeapon| Interface, if not it wont be equiped public virtual void SetWeaponBeforeMounting(MWeapon weapon) { if (weapon == null) return; Weapon = weapon; if (Weapon) //If the weapon doesn't have IMweapon Interface do nothing { CombatMode = true; Weapon.PrepareWeapon(this); Holster_SetActive(Weapon.HolsterID); //Set the Active holster for the Active Weapon WeaponType = Weapon.WeaponType; //Set the Weapon Type WeaponAction = WA.Idle; OnEquipWeapon.Invoke(Weapon.gameObject); Weapon.GetComponent()?.Pick(); ExitAim(); Weapon.gameObject.SetActive(true); //Set the Game Object Instance Active ParentWeapon(); SendMessage(Weapon.IsRightHanded ? FreeRightHand : FreeLeftHand, true); //IK REINS Message Weapon.gameObject.SetActive(true); //Set the Game Object Instance Active ParentWeapon(); Weapon.GetComponent()?.Pick(); Debugging($"Equip Before Mounting → [{Weapon.Holster.name}] → [{Weapon.name}]"); //Debug } } /// If using Holsters this will toggle the Active weapon (Call this by an Input) public virtual void ToggleActiveHolster() { if (Weapon) { if (WeaponAction == WA.Idle) Store_Weapon(); //Draw a weapon if we are on Action Idle } else { Draw_Weapon(); } } /// If using Holsters this will toggle the Active weapon (Call this by an Input) public virtual void ToggleActiveHolster_FAST() { if (Weapon) { if (WeaponAction == WA.Idle) UnEquip_FAST(); //Draw a weapon if we are on Action Idle } else { Equip_FAST(); } } /// Equip Weapon from holster or from Inventory (Called by the Animator) public virtual void Equip_Weapon() { if (!Active) return; //if (Weapon.gameObject.IsPrefab()) return; //Means the Weapon is a prefab and is not instantiated yet (MAKE A WAIT COROYTINE) WeaponAction = WA.Idle; //Set the Action to Equip CombatMode = true; if (Weapon == null) return; Debugging($"Equip → [{Weapon.name}] T:{Time.time:F2}", "orange"); Weapon.PrepareWeapon(this); if (UseHolsters) //If Use holster Means that the weapons are on the holster { ParentWeapon(); //Smoothly put the weapon in the hand StartCoroutine(MTools.AlignTransformLocal(Weapon.transform, Weapon.PositionOffset, Weapon.RotationOffset, Weapon.ScaleOffset, HolsterTime)); } else //if (UseInventory) //If Use Inventory means that the weapons are on the inventory { if (!AlreadyInstantiated) //Do this if the Instantiation is not handled Externally { ParentWeapon(); Weapon.ApplyOffset(); } Weapon.gameObject.SetActive(true); //Set the Game Object Instance Active } OnEquipWeapon.Invoke(Weapon.gameObject); //Let everybody know that the weapon is equipped Weapon.PlaySound(WSound.Equip); //Play Equip Sound } /// Unequip Weapon from holster or from Inventory (Called by the Animator) public virtual void Unequip_Weapon() { // if (!Active) return; ResetCombat(); if (Weapon == null) return; Debugging($"Unequip → [{Weapon.name}] T:{Time.time:F2}" , "orange"); //Debug OnUnequipWeapon.Invoke(Weapon.gameObject); //Let the rider know that the weapon has been unequiped. if (UseHolsters) //If Use holster Parent the ActiveMWeapon the the holster { Weapon.transform.parent = ActiveHolster.Transform; //Parent the weapon to his original holster StartCoroutine(MTools.AlignTransform(Weapon.transform, Weapon.HolsterOffset, HolsterTime)); } else if (!AlreadyInstantiated) { Destroy(Weapon.gameObject); } Weapon = null; //IMPORTANT } /// Parents the Weapon to the Correct Hand public virtual void ParentWeapon() => Weapon.transform.parent = Weapon.IsRightHanded ? RightHandEquipPoint : LeftHandEquipPoint; //Parent the Active Weapon to the Right/Left Hand /// Draw (Set the Correct Parameters to play Draw Weapon Animation) public virtual void Draw_Weapon() { if (!Active) return; ExitAim(); if (UseInventory) //If is using External Equip { if (Weapon != null) Holster_SetActive(Weapon.HolsterID); //Set the Current holster to the weapon asigned holster (THE WEAPON IS ALREADY SET) } if (UseHolsters) { Weapon = ActiveHolster.Weapon; //Set the new Weapon from the Holster Weapon } if (Weapon) { if (Weapon.IgnoreDraw) { Equip_FAST(); return; } WeaponType = Weapon.WeaponType; //Set the Weapon Type (For the correct Animations) Action(DrawWeaponID); //Set the Weapon Action to +1 to Draw Weapons From Right or from Left -1 SendMessage(Weapon.IsRightHanded ? FreeRightHand : FreeLeftHand, true); //IK REINS Message Debugging($"Draw → { (Weapon.IsRightHanded ? "Right Hand" : "Left Hand")} → {Weapon.Holster.name} → {Weapon.name}]","yellow"); //Debug } } /// Store (Set the Correct Parameters to play Store Weapon Animation) public virtual void Store_Weapon() { if (Weapon == null) return; //Skip if there's no Active Weapon or is not inCombatMode, meaning there's an active weapon ExitAim(); if (Weapon.IgnoreDraw) { UnEquip_FAST(); return; } WeaponAction = StoreWeaponID; //Set the Weapon Action to Store Weapons Debugging($"Store → { (Weapon.IsRightHanded ? "Right Hand" : "Left Hand")} → {Weapon.Holster.name} → {Weapon.name}]","cyan"); //Debug } public virtual void Equip_FAST() { if (UseHolsters) Weapon = ActiveHolster.Weapon; //Check if the Child on the holster Has a IMWeapon on it if (Weapon == null || Weapon.gameObject.IsPrefab()) return; //Means the Weapon is a prefab and is not instantiated yet (MAKE A WAIT COROUTINE) Equip_FAST(Weapon,true); } /// Performs a Fast equiping of a MWeapon /// Weapon to equip /// Parent the weapon to the Hand, it also resets the scale to 1.1.1 public virtual void Equip_FAST(MWeapon weapon, bool doParent = true) { Weapon = weapon; Debugging($"Fast Equip → {Weapon.Holster.name} → {Weapon.name}", "cyan"); //Debug ExitAim(); SendMessage(Weapon.IsRightHanded ? FreeRightHand : FreeLeftHand, true); //IK REINS WeaponType = Weapon.WeaponType; WeaponAction = WA.Idle; //Set the Action to Equip CombatMode = true; Weapon.PrepareWeapon(this); Weapon.GetComponent()?.Pick(); Weapon.PlaySound(0); //Play Draw Sound if (doParent) { Weapon.gameObject.SetActive(true); //Set the Game Object Instance Active ParentWeapon(); Weapon.transform.SetLocalTransform(Weapon.PositionOffset, Weapon.RotationOffset, Weapon.ScaleOffset); //Local position when is Parent to the weapon } OnEquipWeapon.Invoke(Weapon.gameObject); } public void UnEquip_FAST() { if (Weapon == null) return; Debugging($"Fast Unequip → {Weapon.Holster.name} → {Weapon.name}", "cyan"); //Debug ResetCombat(); // LastStoredWeaponHand = Weapon.IsRightHanded; OnUnequipWeapon.Invoke(Weapon.gameObject); //Let the rider know that the weapon has been unequiped. if (UseHolsters) //If Use holster Parent the ActiveMWeapon the the holster { Weapon.transform.parent = ActiveHolster.Transform; //Parent the weapon to his original holster Weapon.transform.SetLocalTransform(Weapon.HolsterOffset); //Set the Holster Offset Option } else if (UseInventory && !AlreadyInstantiated) { Destroy(Weapon.gameObject); } OnUnequipWeapon.Invoke(Weapon.gameObject); Weapon = null; //IMPORTANT } /// Used By the Animator at the end of the Store Weapon animations public virtual void Finish_StoreW() { if (Weapon == null) //Means that there's no next Weapon Trying to equip { Action(0); } } /// Enable Disable the Attack Trigger in case it has one... this is called by the animator Like the Attack Triggers!!! public void ActivateDamager(int value) => Weapon?.ActivateDamager(value); /// Update all Damagers on the Character public void UpdateDamagerSet() { } private void TryInstantiateWeapon(MWeapon Next_Weapon) { if (!AlreadyInstantiated) { var WeaponGO = Instantiate(Next_Weapon.gameObject, transform); //Instanciate the Weapon GameObject WeaponGO.SetActive(false); //Hide it to show it later Next_Weapon = WeaponGO.GetComponent(); //UPDATE THE REFERENCE Debugging($"{WeaponGO.name} Instantiated"); } Weapon = Next_Weapon; } /// Is called to swap weapons private IEnumerator SwapWeaponsHolster(int HolstertoSwap) { Store_Weapon(); // yield return new WaitWhile(() => WeaponAction != WA.None); // Wait for the weapon is Unequiped Before it can Draw Another while (WeaponAction != WA.None) yield return null; // Wait for the weapon is Unequiped Before it can Draw Another Holster_SetActive(HolstertoSwap); Draw_Weapon(); //Set the parameters so draw a weapon } /// Is called to swap weapons private IEnumerator SwapWeaponsInventory(GameObject nextWeapon) { Store_Weapon(); while (WeaponAction != WA.None) yield return null; // Wait for the weapon is Unequiped Before it can Draw Another TryInstantiateWeapon(nextWeapon.GetComponent()); Draw_Weapon(); //Set the parameters so draw a weapon } #endregion } }