void UpdateMoveTowardSigmaBehavior() { // face sigma if (sigmaTransform.position.x < transform.position.x) { myRenderer.flipX = false; } else { myRenderer.flipX = true; } // move toward sigma myRigidbody.MovePosition(transform.position + (myRenderer.flipX ? transform.right : -transform.right) * speed * Time.deltaTime); // attack periodically if (canAttack) { StartCoroutine(WaitToAttack((Attacks)Random.Range(0, 2))); } #region change state if sigma is out of reach // sigma is out of reach if he is higher or lower than the boss's vertical reach bool sigmaIsOutOfReach = sigmaTransform.position.y > (transform.position.y + verticalReach) || sigmaTransform.position.y < (transform.position.y - verticalReach); if (sigmaIsOutOfReach) { currentState = Boss1States.PATROLLING; } #endregion }
// Use this for initialization void Start() { m_rigidbody = this.GetComponent <Rigidbody>(); m_playerTransform = CharactersConfigManager.GetPlayerGameObject().transform; m_state = Boss1States.IDLE; m_animator = GetComponent <Animator>(); m_idlePosition = idlePosition.transform.position; //this.transform.position = m_idlePosition; m_targetPosition = m_idlePosition; m_rigidbody.velocity = new Vector3(0, 0, 0); m_nextSkill = RandomSkillRoller(); hp = maxHP; m_isAttackMeleeLocked = false; m_isAttackFireLocked = false; m_isAttackAOELocked = false; m_isPlayerInAlertRange = false; m_isPlayerInAOERange = false; m_isPlayerInFireRange = false; m_isPlayerInMeleeRange = false; rushTimer = 0; fireChaseTimer = 0; idleTimer = 0; m_FireEffect = null; }
void UpdatePatrolBehavior() { // give up on attacking if sigma is out of reach StopCoroutine(WaitToAttack(Attacks.STOMP)); StopCoroutine(WaitToAttack(Attacks.CHARGE)); // switch patrol points if close to one if (Vector2.Distance(transform.position, targetPos) < 3) { targetPos = (targetPos == navPointLeft.position ? navPointRight.position : navPointLeft.position); } // move back and forth between patrol points myRenderer.flipX = (targetPos == navPointLeft.position ? false : true); myRigidbody.MovePosition(transform.position + (targetPos == navPointLeft.position ? -transform.right : transform.right) * speed * Time.deltaTime); // placeholder #region change state if sigma is in reach // sigma is in reach if he is not higher or lower than the boss's vertical reach bool sigmaIsInReach = !(sigmaTransform.position.y > (transform.position.y + verticalReach)) && !(sigmaTransform.position.y < (transform.position.y - verticalReach)); if (sigmaIsInReach) { currentState = Boss1States.MOVING_TOWARD_SIGMA; } #endregion }
void UpdateInactiveBehavior() { if (Vector2.Distance(transform.position, sigmaTransform.position) < activationRange) { currentState = Boss1States.PATROLLING; } }
void OnCollisionEnter2D(Collision2D collision) { switch (collision.gameObject.tag) { case "Player": if (currentState == Boss1States.CHARGE_ATTACK) { collision.gameObject.GetComponent <IDamageable>().TakeDamage(30); myRenderer.color = originalRendererColor; currentState = Boss1States.PATROLLING; } else { collision.gameObject.GetComponent <IDamageable>().TakeDamage(10); } break; case "Boss1Wall": if (currentState == Boss1States.CHARGE_ATTACK) { currentState = Boss1States.INJURED; myAnim.SetTrigger("HitWall"); StartCoroutine(InjurySequence()); } break; } }
IEnumerator Attack(Attacks attackType) { switch (attackType) { case Attacks.STOMP: currentState = Boss1States.STOMP_ATTACK; #region stomp myRigidbody.AddForce(Vector2.up * stompForce); if (OnBoss1Stomp != null) { OnBoss1Stomp(); } blastWave.SetActive(true); float elapsedTime = 0; while (elapsedTime < 1) { blastWave.transform.localScale = new Vector3(blastWave.transform.localScale.x + 2, blastWave.transform.localScale.y, blastWave.transform.localScale.z); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } blastWave.transform.localScale = originalBlastWaveScale; blastWave.SetActive(false); #endregion currentState = Boss1States.PATROLLING; break; case Attacks.CHARGE: currentState = Boss1States.CHARGE_ATTACK; #region charge myRigidbody.velocity = Vector2.zero; myRigidbody.constraints = RigidbodyConstraints2D.FreezeRotation; elapsedTime = 0; float timer = 3; while (elapsedTime < timer) { myRenderer.color = Color.Lerp(originalRendererColor, Color.red, elapsedTime / timer); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } myRigidbody.AddForce((myRenderer.flipX ? Vector2.right : Vector2.left) * 20000); #endregion break; } }
public void GetAttack(double damage, GameObject attacker) { hp -= damage; m_state = Boss1States.HURT; m_currentAttacker = attacker; }
// Update is called once per frame void Update() { Debug.Log(m_state); if (hp <= 0) { m_state = Boss1States.DEAD; m_animator.SetBool(k_isDead, true); } else if (hp < maxHP / 2) { m_nextSkill = Boss1Skills.AOE; } if (m_state == Boss1States.DEAD) { m_targetPosition = this.transform.position; // stay still m_rigidbody.velocity = new Vector3(0, 0, 0); m_animator.SetBool(k_isDead, true); // after death animation AnimatorStateInfo animatorInfo; animatorInfo = m_animator.GetCurrentAnimatorStateInfo(0); if ((animatorInfo.normalizedTime > 1.0f) && (animatorInfo.IsName("Dead"))) // attack animation ends { if (objectRoot.activeInHierarchy) { objectRoot.SetActive(false); GameObject g = Instantiate(Resources.Load("Prefabs/Effects/Particles/SpiderDeathParticle"), this.transform.position + new Vector3(0, 1, 0), Quaternion.identity) as GameObject; Destroy(g, 5); } } } if (m_state == Boss1States.IDLE) { //if (m_FireEffect) // Destroy(m_FireEffect); m_animator.SetBool(k_isAttackMelee, false); m_animator.SetBool(k_isAttackAOE, false); m_animator.SetBool(k_isAttackFire, false); m_animator.SetBool(k_isHurt, false); if (idleTimer > 0) { // 僵直时间 idleTimer -= Time.deltaTime; m_targetPosition = this.transform.position; m_animator.SetBool(k_isWalking, false); } else { m_targetPosition = m_idlePosition; idleTimer = 0; GoTowardTarget(speed);// ordinary speed if (m_isPlayerInAlertRange) { m_state = Boss1States.CHASE_PLAYER; } } } if (m_state == Boss1States.CHASE_PLAYER) { m_animator.SetBool(k_isWalking, true); Debug.Log(m_nextSkill); m_animator.SetBool(k_isAttackMelee, false); m_animator.SetBool(k_isAttackAOE, false); m_animator.SetBool(k_isAttackFire, false); AdjustFacingRotation(); if (m_nextSkill == Boss1Skills.AOE) { if (m_isPlayerInAOERange) { m_animator.SetBool(k_isAttackAOE, true); m_state = Boss1States.ATTACK_AOE; } else { // continue chasing } } if (m_nextSkill == Boss1Skills.FIRE) { m_targetPosition = m_playerTransform.position; GoTowardTarget(fastSpeed); if (m_isPlayerInFireRange || fireChaseTimer > 3f) // 追到 放技能 没追到 接着追 或者如果追超过3秒了 就直接放了 { m_targetPosition = this.transform.position; // stay still m_rigidbody.velocity = new Vector3(0, 0, 0); m_isAttackFireLocked = false; m_state = Boss1States.ATTACK_FIRE; fireChaseTimer = 0; } else { fireChaseTimer += Time.deltaTime; // continue chasing } } if (m_nextSkill == Boss1Skills.MELEE) { // 朝向玩家冲一段距离 Vector3 dir = (m_playerTransform.position - this.transform.position).normalized; m_rigidbody.velocity = Vector3.Lerp(dir * rushSpeed, new Vector3(0, 0, 0), rushTimer); rushTimer += Time.deltaTime / 0.5f; if (rushTimer > 1f || m_rigidbody.velocity.Equals(Vector3.zero) || m_isPlayerInMeleeRange) // 冲完/撞墙了 { m_isAttackMeleeLocked = false; m_animator.SetBool(k_isAttackMelee, true); m_state = Boss1States.ATTACK_MELEE; rushTimer = 0f; } Debug.Log("MELEE" + m_rigidbody.velocity); } } if (m_state == Boss1States.ATTACK_AOE) { // play aoe animation AnimatorStateInfo animatorInfo; animatorInfo = m_animator.GetCurrentAnimatorStateInfo(0); if ((animatorInfo.normalizedTime > 1.0f) && (animatorInfo.IsName("AttackAOE"))) // attack animation ends { if (m_isPlayerInMeleeRange && !m_isAttackAOELocked) { m_playerTransform.GetComponent <PlayerTestController>().GetDamage(attackAOE); m_isAttackAOELocked = true; idleTimer = 2f; } else { m_nextSkill = RandomSkillRoller(); m_state = Boss1States.IDLE; } } } if (m_state == Boss1States.ATTACK_MELEE) { // play melee animation AnimatorStateInfo animatorInfo; animatorInfo = m_animator.GetCurrentAnimatorStateInfo(0); //Debug.Log(animatorInfo.normalizedTime); if ((animatorInfo.normalizedTime >= 1f) && (animatorInfo.IsName("AttackMelee"))) // attack animation ends { if (m_isPlayerInMeleeRange && !m_isAttackMeleeLocked) { m_playerTransform.GetComponent <PlayerTestController>().GetDamage(attackMelee); m_isAttackMeleeLocked = true; idleTimer = 0.5f; } m_nextSkill = Boss1Skills.FIRE; m_state = Boss1States.IDLE; } } if (m_state == Boss1States.ATTACK_FIRE) { m_targetPosition = this.transform.position; // stay still m_rigidbody.velocity = new Vector3(0, 0, 0); m_animator.SetBool(k_isAttackFire, true); AnimatorStateInfo animatorInfo; animatorInfo = m_animator.GetCurrentAnimatorStateInfo(0); //Debug.Log(animatorInfo.normalizedTime); if ((animatorInfo.normalizedTime >= 1f)) // attack animation ends { if (m_isPlayerInFireRange && !m_isAttackFireLocked) { m_playerTransform.GetComponent <PlayerTestController>().GetDamage(attackFire); m_isAttackFireLocked = true; idleTimer = 0.5f; } m_nextSkill = RandomSkillRoller(); m_state = Boss1States.IDLE; } } if (m_state == Boss1States.HURT) { m_animator.SetBool(k_isHurt, true); AnimatorStateInfo animatorInfo; animatorInfo = m_animator.GetCurrentAnimatorStateInfo(0); if ((animatorInfo.normalizedTime >= 1.0f) && (animatorInfo.IsName("Hurt"))) { m_state = Boss1States.IDLE; } } }
IEnumerator InjurySequence() { weakSpot.SetActive(true); myRigidbody.isKinematic = true; #region blink red float elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(Color.red, originalRendererColor, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(originalRendererColor, Color.red, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(Color.red, originalRendererColor, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(originalRendererColor, Color.red, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(Color.red, originalRendererColor, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(originalRendererColor, Color.red, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(Color.red, originalRendererColor, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(originalRendererColor, Color.red, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(Color.red, originalRendererColor, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(originalRendererColor, Color.red, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } elapsedTime = 0; while (elapsedTime < (injuredTimer / 10)) { myRenderer.color = Color.Lerp(Color.red, originalRendererColor, elapsedTime / (injuredTimer / 10)); elapsedTime += Time.deltaTime; yield return(new WaitForEndOfFrame()); } myRenderer.color = originalRendererColor; #endregion weakSpot.SetActive(false); myRigidbody.isKinematic = false; currentState = Boss1States.PATROLLING; }