//Unit was hit public void Hit(DamageObject d) { if (HitableStates.Contains(enemyState)) { //only allow ground attacks to hit us when we are knocked down if (enemyState == UNITSTATE.KNOCKDOWNGROUNDED && !d.isGroundAttack) { return; } CancelInvoke(); StopAllCoroutines(); animator.StopAllCoroutines(); Move(Vector3.zero, 0f); //add attack time out so this enemy cannot attack instantly after a hit lastAttackTime = Time.time; //don't hit this unit when it's allready down if ((enemyState == UNITSTATE.KNOCKDOWNGROUNDED || enemyState == UNITSTATE.GROUNDHIT) && !d.isGroundAttack) { return; } //defend an incoming attack if (!d.DefenceOverride && defendableStates.Contains(enemyState)) { int rand = Random.Range(0, 100); if (rand < defendChance) { Defend(); return; } } //hit sfx GlobalAudioPlayer.PlaySFXAtPosition(d.hitSFX, transform.position); //hit particle effect ShowHitEffectAtPosition(new Vector3(transform.position.x, d.inflictor.transform.position.y + d.collHeight, transform.position.z)); //camera Shake CamShake camShake = Camera.main.GetComponent <CamShake>(); if (camShake != null) { camShake.Shake(.1f); } //activate slow motion camera if (d.slowMotionEffect) { CamSlowMotionDelay cmd = Camera.main.GetComponent <CamSlowMotionDelay>(); if (cmd != null) { cmd.StartSlowMotionDelay(.2f); } } //substract health HealthSystem hs = GetComponent <HealthSystem>(); if (hs != null) { hs.SubstractHealth(d.damage); if (hs.CurrentHp == 0) { return; } } //ground attack if (enemyState == UNITSTATE.KNOCKDOWNGROUNDED) { StopAllCoroutines(); enemyState = UNITSTATE.GROUNDHIT; StartCoroutine(GroundHit()); return; } //turn towards the direction of the incoming attack int dir = d.inflictor.transform.position.x > transform.position.x? 1 : -1; TurnToDir((DIRECTION)dir); //check for a knockdown if (d.knockDown) { StartCoroutine(KnockDownSequence(d.inflictor)); return; } else { //default hit int rand = Random.Range(1, 3); animator.SetAnimatorTrigger("Hit" + rand); enemyState = UNITSTATE.HIT; //add small force from the impact LookAtTarget(d.inflictor.transform); animator.AddForce(-KnockbackForce); //switch enemy state from passive to aggressive when attacked if (enemyTactic != ENEMYTACTIC.ENGAGE) { EnemyManager.setAgressive(gameObject); } Invoke("Ready", hitRecoveryTime); return; } } }
//knockDown sequence public IEnumerator KnockDownSequence(GameObject inflictor) { playerState.SetState(UNITSTATE.KNOCKDOWN); animator.StopAllCoroutines(); yield return(new WaitForFixedUpdate()); //look towards the direction of the incoming attack int dir = inflictor.transform.position.x > transform.position.x ? 1 : -1; currentDirection = (DIRECTION)dir; TurnToDir(currentDirection); //update playermovement var pm = GetComponent <PlayerMovement>(); if (pm != null) { pm.CancelJump(); pm.SetDirection(currentDirection); } //add knockback force animator.SetAnimatorTrigger("KnockDown_Up"); while (IsGrounded()) { SetVelocity(new Vector3(KnockbackForce * -dir, KnockdownUpForce, 0)); yield return(new WaitForFixedUpdate()); } //going up... while (rb.velocity.y >= 0) { yield return(new WaitForFixedUpdate()); } //going down animator.SetAnimatorTrigger("KnockDown_Down"); while (!IsGrounded()) { yield return(new WaitForFixedUpdate()); } //hit ground animator.SetAnimatorTrigger("KnockDown_End"); CamShake camShake = Camera.main.GetComponent <CamShake>(); if (camShake != null) { camShake.Shake(.3f); } animator.ShowDustEffectLand(); //sfx GlobalAudioPlayer.PlaySFXAtPosition("Drop", transform.position); //ground slide float t = 0; float speed = 2; Vector3 fromVelocity = rb.velocity; while (t < 1) { SetVelocity(Vector3.Lerp(new Vector3(fromVelocity.x, rb.velocity.y + Physics.gravity.y * Time.fixedDeltaTime, fromVelocity.z), new Vector3(0, rb.velocity.y, 0), t)); t += Time.deltaTime * speed; yield return(null); } //knockDown Timeout SetVelocity(Vector3.zero); yield return(new WaitForSeconds(KnockdownTimeout)); //stand up animator.SetAnimatorTrigger("StandUp"); playerState.currentState = UNITSTATE.STANDUP; yield return(new WaitForSeconds(KnockdownStandUpTime)); playerState.currentState = UNITSTATE.IDLE; }
/// <summary> /// 被攻击 /// </summary> /// <param name="d"></param> public void Hit(DamageObject d) { if (HitableStates.Contains(enemyState)) { //只有在第一次被击倒时才能进行地面攻击 if (enemyState == UNITSTATE.KNOCKDOWNGROUNDED && !d.isGroundAttack) { return; } CancelInvoke(); StopAllCoroutines(); animator.StopAllCoroutines(); Move(Vector3.zero, 0f); //给敌人添加硬直时间 lastAttackTime = Time.time; //在倒地状态只能被攻击一次 if ((enemyState == UNITSTATE.KNOCKDOWNGROUNDED || enemyState == UNITSTATE.GROUNDHIT) && !d.isGroundAttack) { return; } //防御状态能够攻击 if (!d.DefenceOverride && defendableStates.Contains(enemyState)) { int rand = Random.Range(0, 100); if (rand < defendChance) { Defend(); return; } } //攻击声音播放 GlobalAudioPlayer.PlaySFXAtPosition(d.hitSFX, transform.position); //攻击特效 ShowHitEffectAtPosition(new Vector3(transform.position.x, d.inflictor.transform.position.y + d.collHeight, transform.position.z)); //相机震动 CamShake camShake = Camera.main.GetComponent <CamShake>(); if (camShake != null) { camShake.Shake(.1f); } //摄像机慢动作 if (d.slowMotionEffect) { CamSlowMotionDelay cmd = Camera.main.GetComponent <CamSlowMotionDelay>(); if (cmd != null) { cmd.StartSlowMotionDelay(.2f); } } //减少HP HealthSystem hs = GetComponent <HealthSystem>(); if (hs != null) { hs.SubstractHealth(d.damage); if (hs.CurrentHp == 0) { return; } } //地面攻击 if (enemyState == UNITSTATE.KNOCKDOWNGROUNDED) { StopAllCoroutines(); enemyState = UNITSTATE.GROUNDHIT; StartCoroutine(GroundHit()); return; } //转向攻击的方向 int dir = d.inflictor.transform.position.x > transform.position.x? 1 : -1; TurnToDir((DIRECTION)dir); //检测是否倒地 if (d.knockDown) { StartCoroutine(KnockDownSequence(d.inflictor)); return; } else { //默认攻击 int rand = Random.Range(1, 3); animator.SetAnimatorTrigger("Hit" + rand); enemyState = UNITSTATE.HIT; //对攻击对象施加力 LookAtTarget(d.inflictor.transform); animator.AddForce(-KnockbackForce); //当收到攻击的时候将敌人的状态从被动切换到主动 if (enemyTactic != ENEMYTACTIC.ENGAGE) { EnemyManager.setAgressive(gameObject); } Invoke("Ready", hitRecoveryTime); return; } } }