/// <summary> /// start hit reaction animation /// </summary> /// <param name="attacker"></param> /// <param name="hitType"></param> /// <param name="applyHitReaction"></param> /// <param name="attackSource"></param> private void _startHitReaction(IGameCharacter attacker, int hitType, bool applyHitReaction, int attackSource) { if (hitType == -1) { return; } if (m_Blocking) { if (m_DefaultWeaponSounds) { GameUtils.PlayRandomClipAtPosition(m_DefaultWeaponSounds.blockSounds, transform.position); } if (applyHitReaction) { _end_attack_combo(); Vector3 toAttacker = attacker.stats.transform.position - transform.position; m_BodyLookDir = toAttacker; m_BodyLookDir.y = 0.0f; transform.rotation = Quaternion.LookRotation(m_BodyLookDir.normalized); string stateName = "BlockHit" + hitType; int stateID = Animator.StringToHash(stateName); if (m_Character.animator.HasState(0, stateID)) { m_Character.animator.CrossFade(stateID, 0.05f, 0, 0.0f); } else { Debug.LogWarning("state '" + stateName + "' dont exist"); m_Character.animator.CrossFade("BlockHit0", 0.05f, 0, 0.0f); } } } else { if (applyHitReaction) { _end_attack_combo(); Vector3 toAttacker = attacker.stats.transform.position - transform.position; m_BodyLookDir = toAttacker; m_BodyLookDir.y = 0.0f; transform.rotation = Quaternion.LookRotation(m_BodyLookDir.normalized); string stateName = "TakeHit" + hitType; int stateID = Animator.StringToHash(stateName); if (m_Character.animator.HasState(0, stateID)) { m_Character.animator.CrossFade(stateID, 0.05f, 0, 0.0f); } else { Debug.LogWarning("state '" + stateName + "' dont exist"); m_Character.animator.CrossFade("TakeHit", 0.05f, 0, 0.0f); } } } }
public Quaternion rot_offset = Quaternion.identity; // rotation offset /// <summary> /// arrow constructor /// </summary> /// <param name="_arrowObject"></param> public Arrow(GameObject _arrowObject, IGameCharacter _owner) { if (!_arrowObject) { Debug.LogError("_arrowObject cannot be null"); } // set to default values lifetime = 0.0f; maxLifetime = 12.0f; advanceLifetime = false; gobject = _arrowObject; trailObj = null; parent = null; if (_arrowObject.transform.childCount > 0) { trailObj = _arrowObject.transform.GetChild(0); trailObj.gameObject.SetActive(false); } RigidBody = gobject.GetComponent <Rigidbody>(); Collider = gobject.GetComponent <Collider>(); owner = _owner; OnArrowHit = null; }
/// <summary> /// notify npc that he is attacked /// </summary> /// <param name="attacker">attacker transform</param> /// <param name="hitType">current hit type</param> /// <param name="damage">attackers damage</param> /// <param name="blocking">ref notify attacker that npc has blocked attack</param> /// <returns>success</returns> public bool attack_hit_notify(IGameCharacter attacker, int hitType, int attackSource, ref bool blocking, bool applyHitReaction = true, Vector3?hitVelocity = null, int[] hitParts = null) { if (!m_Initialized) { Debug.LogError("component not initialized" + " < " + this.ToString() + ">"); return(false); } if (isDead) { return(false); } if (!m_Blocking) { int rnd = Random.Range(0, blockOdds); m_Blocking = rnd == 0; if (m_Blocking) { m_Animator.SetBool(HashIDs.BlockBool /*"pBlock"*/, true); m_BlockTimer = 0.0f; } } _end_attack_combo(); m_InCombat = true; blocking = m_Blocking; m_Character.fullStop(); _startHitReaction(attacker, hitType, applyHitReaction, attackSource); int damageReceived = GameUtils.CalculateDamage(this, attacker, m_Blocking); if (m_Stats.currentHealth <= 0) { m_Player.attack_end_notify(this, m_CurrentAttackType); m_InCombat = false; m_Character.animator.SetBool(/*"pAttack1"*/ HashIDs.Attack1Bool, false); m_Attack_combo_started = false; m_Kooldown = true; m_AttackTimer = 0.0f; attackSweepBody.gameObject.SetActive(false); m_Ragdoll.startRagdoll(hitParts, hitVelocity, hitVelocity * 0.025f); } if (!blocking) { if (m_DamageUI) { m_DamageUI.setText("-" + damageReceived); } } return(true); }
/// <summary> /// unity Awake method /// is called when the script instance is being loaded /// </summary> void Awake() { if (!ParentObject) { Debug.LogError("BodyColliderScript has not assigned 'ParentObject'"); return; } // get game character interface m_GCharacterOwner = ParentObject.GetComponent <IGameCharacter>(); }
/// <summary> /// OnStateExit is called when a transition ends and the state machine finishes evaluating this state /// </summary> /// <param name="animator">current animator</param> /// <param name="stateInfo">state info struct</param> /// <param name="layerIndex">animator layer index</param> override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { if (character == null) { character = animator.gameObject.GetComponent <IGameCharacter>(); } if (character != null) { character.takingHit = false; } }
/// <summary> /// calculte damage received based on player and attacker stats /// </summary> /// <param name="defenderStats"></param> /// <param name="attackerStats"></param> /// <param name="blocking"></param> /// <param name="perHitAdditionalDamage"></param> public static int CalculateDamage(IGameCharacter defender, IGameCharacter attacker, bool blocking /*, int damage*/) { if (blocking) { return(0); //blocking 伤害为0 } int damageAccum = attacker.stats.currentDamage + attacker.stats.attack; int damageReduced = Mathf.Max((damageAccum - defender.stats.defence), 1); defender.stats.decreaseHealth(damageReduced); return(damageReduced); }
/// <summary> /// attack procedure /// </summary> /// <param name="attack"></param> private void _attackCombo(bool attack) { #if DEBUG_INFO if (!m_Initialized) { Debug.LogError("Component not initialized < " + this.ToString() + " >"); return; } #endif bool isAttacking = m_Animator.GetBool(/*"pAttack1"*/ HashIDs.Attack1Bool); if (attack) { if (m_Character.isOnGround) { if (!m_Attack_combo_started && !isAttacking && !m_AttackStateUnderway) { IGameCharacter npc = m_PrimaryTargetNPC; #if TESTING_USE_ALL_NPC_ARRAY m_PrimaryTargetNPC = _getPrimaryTarget(); #else m_PrimaryTargetNPC = _getPrimaryTargetInZone(); #endif if (m_PrimaryTargetNPC != npc) { if (npc != null) { npc.attack_end_notify(this, 1); } } m_BreakCombo = false; m_Character.turnTransformToDirection(m_TargetDirection); m_Animator.SetBool(/*"pAttack1"*/ HashIDs.Attack1Bool, true); m_Attack_combo_started = true; if (m_PrimaryTargetNPC != null) { m_InCombat = true; if (enableJumpToTarget) { _jumpToTarget(); } } } else { m_BreakCombo = false; } } } }
/// <summary> /// start trigger interaction /// </summary> /// <param name="character">character interacting with trigger</param> /// <param name="limbsIK">ik helper</param> /// <param name="use">use flag</param> /// <param name="jump">jump flag</param> /// <param name="v">vertical value</param> /// <param name="h">horizontal value</param> /// <returns>all succeded</returns> public override bool start(TPCharacter character, IKHelper limbsIK, bool use, bool secondaryUse, bool jump, float v, float h) { if (use) { IGameCharacter icharacter = character.GetComponent <IGameCharacter>(); if (icharacter != null) { icharacter.setNewItem(item); } } if (secondaryUse) { IGameCharacter icharacter = character.GetComponent <IGameCharacter>(); if (icharacter != null) { icharacter.setSecondaryItem(item); } } return(false); }
/// <summary> /// creates arrow and sets it up in hand /// </summary> /// <param name="arrowPrefab">arrow prefab to instantiate</param> /// <param name="arrowAttachBone">transform on which to attach arrow</param> /// <returns></returns> public static Arrow CreateArrow( GameObject arrowPrefab, Transform arrowAttachBone, float maxLifetime, float arrowLength, LayerMask layers, IGameCharacter _owner) { #if DEBUG_INFO if (m_arrowPool == null) { Debug.LogError("object cannot be null"); return(null); } if (m_active_arrows == null) { Debug.LogError("object cannot be null"); return(null); } if (!arrowPrefab) { Debug.LogError("_currentArrowPrefab is null. Cannot create arrow"); return(null); } if (!arrowAttachBone) { Debug.LogError("object cannot be null"); return(null); } #endif ArrowUnit newArrowUnit = null; // try to find available arrow for (int i = 0; i < m_arrowPool.Count; i++) { if (!m_arrowPool[i].inUse) { newArrowUnit = m_arrowPool[i]; newArrowUnit.inUse = true; break; } } // if not create new if (newArrowUnit == null) { GameObject arrowObject = (GameObject)MonoBehaviour.Instantiate(arrowPrefab); Arrow newArrow = new Arrow(arrowObject, _owner); newArrowUnit = new ArrowUnit(newArrow); m_arrowPool.Add(newArrowUnit); newArrow.gobject.name = arrowPrefab.name + m_arrowPool.Count; #if DEBUG_ARROW_PATH arrow_debug_paths[newArrow] = new List <Vector3>(); #endif } #if DEBUG_INFO if (newArrowUnit == null) { Debug.LogError("creating arrow failed."); return(null); } #endif newArrowUnit.arrow.gobject.transform.position = Vector3.zero; newArrowUnit.arrow.gobject.transform.rotation = Quaternion.identity; newArrowUnit.arrow.gobject.transform.SetParent(arrowAttachBone, false); newArrowUnit.arrow.gobject.SetActive(true); newArrowUnit.arrow.position = Vector3.zero; newArrowUnit.arrow.prevPosition = Vector3.zero; newArrowUnit.arrow.direction = Vector3.zero; newArrowUnit.arrow.fly_time = 0.0f; newArrowUnit.arrow.state = Arrow.STATES.READY; newArrowUnit.arrow.speed = 0.0f; newArrowUnit.arrow.advanceLifetime = false; newArrowUnit.arrow.RigidBody.detectCollisions = false; newArrowUnit.arrow.RigidBody.isKinematic = true; newArrowUnit.arrow.Collider.enabled = false; newArrowUnit.arrow.layers = layers; newArrowUnit.arrow.length = arrowLength; newArrowUnit.arrow.maxLifetime = maxLifetime; m_active_arrows.Add(newArrowUnit.arrow); return(newArrowUnit.arrow); }
public void SetMaster(IGameCharacter master) { _someoneWhoShotThisProjectile = master; }
/// <summary> /// notify npc to attack combo end /// </summary> /// <param name="attacker">attacker transform</param> /// <param name="hitType">current attack type</param> public void attack_end_notify(IGameCharacter attacker, int hitType) { m_InCombat = false; }
/// <summary> /// notify npc of start attack /// </summary> /// <param name="attacker">attacker game character</param> /// <param name="hitType">attack hit type</param> public void attack_start_notify(IGameCharacter attacker, int hitType) { }
public void SetMaster(IGameCharacter master) { _master = master; }
/// <summary> /// attack procedure /// </summary> /// <param name="attack"></param> /// <param name="direction2cursor"></param> private void _attackCombo(bool attack, Vector3 direction2cursor) { #if DEBUG_INFO if (!m_Initialized) { Debug.LogError("Component not initialized < " + this.ToString() + " >"); return; } #endif bool isAttacking = m_TopDownPlayer.animator.GetBool(/*"pAttack1"*/ HashIDs.Attack1Bool); if (attack) { if (m_TopDownPlayer.character.isOnGround) { m_TopDownPlayer.stop(); m_TargetDirection = direction2cursor; float angleDiff = Vector3.Angle(m_PrevTargetDirection, m_TargetDirection); if (angleDiff > CHANGE_TARGET_ANGLE_BUFFER) { m_ChangeTarget = true; } m_PrevTargetDirection = m_TargetDirection; bool attackState = m_TopDownPlayer.animator.GetCurrentAnimatorStateInfo(0).IsName("AttackCombo"); if (!m_Attack_combo_started && !isAttacking && !attackState) { IGameCharacter npc = m_PrimaryTargetNPC; #if TESTING_USE_ALL_NPC_ARRAY m_PrimaryTargetNPC = _getPrimaryTarget(); #else m_PrimaryTargetNPC = _getPrimaryTargetInZone(); #endif if (m_PrimaryTargetNPC != npc) { if (npc != null) { npc.attack_end_notify(this, 1); } } m_BreakCombo = false; m_TopDownPlayer.character.turnTransformToDirection(m_TargetDirection); m_TopDownPlayer.animator.SetBool(/*"pAttack1"*/ HashIDs.Attack1Bool, true); m_Attack_combo_started = true; if (m_PrimaryTargetNPC != null) { m_InCombat = true; if (enableJumpToTarget) { _jumpToTarget(); } } } else { m_BreakCombo = false; } } } }