Forum begins after the advertisement:


[part 10] parry is bugged

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #14439
    Anuk Thotawatta
    Participant

    when i hit the boss he parries once in the whole fight and does a riposte slash whenever i attack. also boss doesnt take damage once parried.

    View post on imgur.com

    #14441
    Joseph Tang
    Moderator

    Here’s a tip when testing out enemies, you can always set the damage to 0 to let your player take the hits to test for longer periods of time, especially when you are not testing damage.

    As for this case, it’s likely that the boss has not finished the parry method. Check out this thread to see if it can fix your issue.

    [Part 10] The Boss have some bugs and cannot respawn from other scene if die

    Otherwise, please drop the entire THK.cs.

    #14445
    Anuk Thotawatta
    Participant
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class THK_Boss : Enemy
    {
        public static THK_Boss Instance;
        [SerializeField] GameObject slashEffect;
    
        [SerializeField] public Transform SideAttackTransform; //the middle of the side attack area
        [SerializeField] public Vector2 SideAttackArea; //how large the area of side attack is
    
        [SerializeField] public Transform UpAttackTransform; //the middle of the up attack area
        [SerializeField] public Vector2 UpAttackArea; //how large the area of side attack is
    
        [SerializeField] public Transform DownAttackTransform; //the middle of the down attack area
        [SerializeField] public Vector2 DownAttackArea; //how large the area of down attack is
    
        public float attackRange;
        public float attackTimer;
    
        [HideInInspector] public bool facingRight;
    
        [Header("Ground Check Settings:")]
        [SerializeField] private Transform groundCheckPoint; //point at which ground check happens
        [SerializeField] private float groundCheckY = 0.2f; //how far down from ground chekc point is Grounded() checked
        [SerializeField] private float groundCheckX = 0.5f; //how far horizontally from ground chekc point to the edge of the player is
        [SerializeField] private LayerMask whatIsGround; //sets the ground layer
    
        int hitCounter;
        bool stunned, canStun;
        bool alive;
    
        [HideInInspector] public float runSpeed;
        
    
        private void Awake()
        {
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
        }
    
        protected override void Start()
        {
            base.Start();
            sr = GetComponentInChildren<SpriteRenderer>();
            anim = GetComponentInChildren<Animator>();
            ChangeState (EnemyStates.THK_Stage1);
            alive = true;
    
        }
    
        public bool Grounded()
        {
            if (Physics2D.Raycast(groundCheckPoint.position, Vector2.down, groundCheckY, whatIsGround) 
                || Physics2D.Raycast(groundCheckPoint.position + new Vector3(groundCheckX, 0, 0), Vector2.down, groundCheckY, whatIsGround) 
                || Physics2D.Raycast(groundCheckPoint.position + new Vector3(-groundCheckX, 0, 0), Vector2.down, groundCheckY, whatIsGround))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    
        private void OnDrawGizmos()
        {
            Gizmos.color = Color.red;
            Gizmos.DrawWireCube(SideAttackTransform.position, SideAttackArea);
            Gizmos.DrawWireCube(UpAttackTransform.position, UpAttackArea);
            Gizmos.DrawWireCube(DownAttackTransform.position, DownAttackArea);
        }
    
        protected override void Update()
        {
            base.Update();
            if(health<=0 && alive){
                Death(0);
                rb.constraints = RigidbodyConstraints2D.FreezePosition;
            }
            if(!attacking){
                attackCountdown-=Time.deltaTime;
            }
            if(stunned){
                rb.velocity = Vector2.zero;
            }
            /*if(!Grounded()){
                anim.SetBool("Run",false);
            }*/
        }
        void OnCollisionEnter2D(Collision2D _other) {
            if(_other.gameObject.tag == "Player"){
                PlayerController.Instance.TakeDamage(THK_Boss.Instance.damage);
            }
        }
    
        public void Flip(){
            if(PlayerController.Instance.transform.position.x < transform.position.x && transform.localScale.x >0){
                transform.eulerAngles = new Vector2(transform.eulerAngles.x,180);
                facingRight = false;
            }
            else{
                transform.eulerAngles = new Vector2(transform.eulerAngles.x,0);
                facingRight = true;
            }
        }
    
        protected override void UpdateEnemyStates(){
            if(PlayerController.Instance != null){
                switch(GetCurrentEnemyState){
                    case EnemyStates.THK_Stage1:
                        canStun = true;
                        attackTimer = 1;
                        runSpeed = speed;
                        break;
                    case EnemyStates.THK_Stage2:
                        canStun = true;
                        attackTimer = 0.5f;
                        break;
                    case EnemyStates.THK_Stage3:
                        canStun = true;
                        attackTimer = 1.5f;
                        break;
                    case EnemyStates.THK_Stage4:
                        canStun = false;
                        attackTimer = 2;
                        runSpeed = speed/2;
                        break;
                }
            }
        }
    
        protected override void OnCollisionStay2D(Collision2D _other)
        {
          
        }
        #region attacking
        #region variables
        [HideInInspector] public bool attacking;
        [HideInInspector] public float attackCountdown;
        [HideInInspector] public bool damagedPlayer = false;
        [HideInInspector] public bool parrying;
        [HideInInspector] public Vector2 moveToPosition;
        [HideInInspector] public bool diveAttack;
        [HideInInspector] public bool barrageAttack;
        public GameObject barrageFireBall;
        public GameObject divingCollider;
        public GameObject pillar;
        [HideInInspector] public bool outBreakAttack;
        [HideInInspector] public bool bounceAttack;
        [HideInInspector] public float rotationDirectionToTarget;
        [HideInInspector] public int bounceCount;
    
        #endregion
        #region Control
        public void AttackHandler(){
            if(currentEnemyState ==EnemyStates.THK_Stage1){
                if(Vector2.Distance(PlayerController.Instance.transform.position, rb.position)<=attackRange){
                    StartCoroutine(TripleSlash());
                }
                else{
                    StartCoroutine(Lunge());
                }
            }
            if(currentEnemyState ==EnemyStates.THK_Stage2){
                if(Vector2.Distance(PlayerController.Instance.transform.position, rb.position)<=attackRange){
                    StartCoroutine(TripleSlash());
                }
                else{
                    int _attackChosen = Random.Range(1,3);
                    if(_attackChosen == 1){
                        //StartCoroutine(Lunge());
                        BarrageBendDown();
                    }
                    if(_attackChosen == 2){
                        DiveAttackJump();
                    }
                    if(_attackChosen == 3){
                        //BarrageBendDown();
                        StartCoroutine(Lunge());
                    }
                }
            }
    
            if(currentEnemyState ==EnemyStates.THK_Stage3){
                int _attackChosen = Random.Range(1,4);
                    if(_attackChosen == 1){
                        OutBreakBendDown();
                    }
                    if(_attackChosen == 2){
                        DiveAttackJump();
                    }
                    if(_attackChosen == 3){
                        BounceAttack();
                    }
                    if(_attackChosen == 4){
                        BarrageBendDown();
                    }
            }
            if(currentEnemyState ==EnemyStates.THK_Stage4){
                if(Vector2.Distance(PlayerController.Instance.transform.position, rb.position)<=attackRange){
                    StartCoroutine(Slash());
                }
                else{
                    BounceAttack();
                }
            }
        }
    
        public void ResetAllAttacks(){
            attacking = false;
            StopCoroutine(TripleSlash());
            StopCoroutine(Lunge());
            StopCoroutine(Parry());
            StopCoroutine(Slash());
            diveAttack = false;
            barrageAttack = false;
            outBreakAttack = false;
            bounceAttack = false;
        }
        #endregion
    
        #region Stage1
        IEnumerator TripleSlash(){
            attacking = true;
            rb.velocity = Vector2.zero;
    
            anim.SetTrigger("Slash");
            SlashAngle();
            yield return new WaitForSeconds(0.3f);
            anim.ResetTrigger("Slash");
    
            anim.SetTrigger("Slash");
            SlashAngle();
            yield return new WaitForSeconds(0.5f);
            anim.ResetTrigger("Slash");
    
            anim.SetTrigger("Slash");
            SlashAngle();
            yield return new WaitForSeconds(0.2f);
            anim.ResetTrigger("Slash");
    
            ResetAllAttacks();
        }
        void SlashAngle(){
            if(PlayerController.Instance.transform.position.x>transform.position.x || PlayerController.Instance.transform.position.x<transform.position.x){
                Instantiate(slashEffect, SideAttackTransform);
            }
            else if(PlayerController.Instance.transform.position.y>transform.position.y){
                SlashEffectAtAngle(slashEffect,80,UpAttackTransform);
            }
            else if(PlayerController.Instance.transform.position.y<transform.position.y){
                SlashEffectAtAngle(slashEffect,-90,DownAttackTransform);
            }
        }
        void SlashEffectAtAngle(GameObject _slashEffect, int _effectAngle, Transform _attackTransform)
        {
            _slashEffect = Instantiate(_slashEffect, _attackTransform);
            _slashEffect.transform.eulerAngles = new Vector3(0, 0, _effectAngle);
            _slashEffect.transform.localScale = new Vector2(transform.localScale.x, transform.localScale.y);
        }
    
        IEnumerator Lunge(){
            Flip();
            attacking = true;
    
            anim.SetBool("Lunge",true);
            yield return new WaitForSeconds(0.7f);
            anim.SetBool("Lunge",false);
            damagedPlayer = false;
            ResetAllAttacks();
        }
        IEnumerator Parry()
        {
            attacking = true;
            rb.velocity = Vector2.zero;
            anim.SetBool("Parry", true);
            yield return new WaitForSeconds(0.8f);
            anim.SetBool("Parry", false);
    
            parrying = false;
            ResetAllAttacks();
        }
        IEnumerator Slash(){
            attacking = true;
            rb.velocity = Vector2.zero;
    
            anim.SetTrigger("Slash");
            SlashAngle();
            yield return new WaitForSeconds(0.2f);
            anim.ResetTrigger("Slash");
    
            ResetAllAttacks();
        }
        #endregion
        #region Stage2
        public void DiveAttackJump(){
            attacking = true;
            moveToPosition = new Vector2(PlayerController.Instance.transform.position.x, rb.position.y +10);
            diveAttack = true;
            anim.SetBool("Jump",true);
        }
         public void Dive(){
            anim.SetBool("Dive",true);
            anim.SetBool("Jump",false);
        } 
        private void OnTriggerEnter2D(Collider2D _other) {
            if(_other.GetComponent<PlayerController>() != null && (diveAttack||bounceAttack)){
                _other.GetComponent<PlayerController>().TakeDamage(damage*2);
                PlayerController.Instance.pState.recoilingX = true;
            }    
        }
    
        public void DivingPillars(){
            Vector2 _impactPoint = groundCheckPoint.position;
            float _spawnDistance = 5;
            for(int i = 0; i<10; i++){
                Vector2 _pillarSpawnPointRight = _impactPoint + new Vector2(_spawnDistance,0);
                Vector2 _pillarSpawnPointLeft = _impactPoint - new Vector2(_spawnDistance,0);
                Instantiate(pillar, _pillarSpawnPointRight, Quaternion.Euler(0,0,-90));
                Instantiate(pillar, _pillarSpawnPointLeft, Quaternion.Euler(0,0,-90));
    
                _spawnDistance += 5;
            }
            ResetAllAttacks();
        }
    
        void BarrageBendDown(){
            attacking = true;
            rb.velocity = Vector2.zero;
            barrageAttack = true;
            anim.SetTrigger("BendDown");
        }
    
        public IEnumerator Barrage(){
            rb.velocity = Vector2.zero; 
            float _currentAngle = 30f;
            for(int i = 0; i<10; i++){
                GameObject _projectile = Instantiate(barrageFireBall,transform.position,Quaternion.Euler(0,0,_currentAngle));
                if(facingRight){
                    _projectile.transform.eulerAngles = new Vector3(_projectile.transform.eulerAngles.x,0,_currentAngle-20);
                }
                else{
                    _projectile.transform.eulerAngles = new Vector3(_projectile.transform.eulerAngles.x,180,_currentAngle-20);
                }
                _currentAngle+=5f;
                yield return new WaitForSeconds(0.3f);
            }
            yield return new WaitForSeconds(0.1f);
            anim.SetBool("Cast",false);
            ResetAllAttacks();
        }
        #endregion
        #region Stage3
        void OutBreakBendDown(){
            attacking = true;
            rb.velocity = Vector2.zero;
            moveToPosition = new Vector2(transform.position.x, rb.position.y +5);
            outBreakAttack = true;
            anim.SetBool("BendDown",true);
        }
    
        public IEnumerator OutBreak(){
            yield return new WaitForSeconds(1f);
            anim.SetBool("Cast",true);
            rb.velocity = Vector2.zero;
            for(int i = 0; i < 30; i++){
                Instantiate(barrageFireBall, transform.position, Quaternion.Euler(0,0,Random.Range(230,310)));//down
                Instantiate(barrageFireBall, transform.position, Quaternion.Euler(0,0,Random.Range(0,50)));//right
                Instantiate(barrageFireBall, transform.position, Quaternion.Euler(0,0,Random.Range(130,180)));//left
    
                yield return new WaitForSeconds(0.2f);
            }
            yield return new WaitForSeconds(0.1f);
            rb.constraints = RigidbodyConstraints2D.None;
            rb.constraints = RigidbodyConstraints2D.FreezeRotation;
            rb.velocity = new Vector2(rb.velocity.x, -10);
            yield return new WaitForSeconds(0.1f);
            anim.SetBool("Cast",false);
            ResetAllAttacks();
        }
        void BounceAttack(){
            attacking = true;
            bounceCount = Random.Range(2,6);
            BounceBendDown();
        }
        int _bounces = 0;
        public void CheckBounce(){
            if(_bounces < bounceCount-1){
                _bounces++;
                BounceBendDown();
            }
            else{
                _bounces = 0;
                anim.Play("THK_Run");
            }
        }
    
        public void BounceBendDown(){
            rb.velocity = Vector2.zero;
            moveToPosition = new Vector2(PlayerController.Instance.transform.position.x, rb.position.y +10);
            bounceAttack = true;
            anim.SetTrigger("BendDown");
        }
    
        public void CalculateTargetAngle(){
            Vector3 _directionToTarget = (PlayerController.Instance.transform.position - transform.position).normalized;
            float _angleOfTarget = Mathf.Atan2(_directionToTarget.y, _directionToTarget.x) * Mathf.Rad2Deg;
            rotationDirectionToTarget = _angleOfTarget;
        }
        #endregion
        #endregion
        public override void EnemyHit(float _damageDone,Vector2 _hitDirection,float _hitForce){
            if (!stunned)
            {
                if (!parrying)
                {
                if (canStun)
                {
                    hitCounter++;
                    if(hitCounter >= 3)
                    {
                        ResetAllAttacks();
                        StartCoroutine(Stunned());
                    }
                }
                base.EnemyHit(_damageDone, _hitDirection, _hitForce);
    
                if (currentEnemyState != EnemyStates.THK_Stage4)
                    {
                    ResetAllAttacks(); //cancel any current attack to avoid bugs
                    StartCoroutine(Parry());
                    }
    
                }
                else
                {
                    StopCoroutine(Parry());
                    ResetAllAttacks();
                    StartCoroutine(Slash()); //riposte
                }
            }
            else
            {
            StopCoroutine(Stunned());
            anim.SetBool("Stunned", false);
            stunned = false;
            }
            #region Health to State
            if(health>120){
                ChangeState(EnemyStates.THK_Stage1);
            }
            if(health<= 90  && health<60){
                ChangeState(EnemyStates.THK_Stage2);
            }
            if(health<= 60 && health<30){
                ChangeState(EnemyStates.THK_Stage3);
            }
            if(health<30){
                ChangeState(EnemyStates.THK_Stage4);
            }
            if(health<0){
                Death(0);
                rb.constraints = RigidbodyConstraints2D.FreezePosition;
            }
            #endregion
            
        }
        
    
        public IEnumerator Stunned(){
            stunned = true;
            hitCounter = 0;
            anim.SetBool("Stunned",true);
            yield return new WaitForSeconds(6f);
            anim.SetBool("Stunned",false);
            stunned = false;
        }
        
        protected override void Death(float __destroyTime){
            ResetAllAttacks();
            alive = false;
            rb.velocity = new Vector2(rb.velocity.x, -25);
            anim.SetTrigger("Die");
        }
    
        public void DestroyAfterDeath(){
            Destroy(gameObject);
        }
    }
    
    
    #14458
    Joseph Tang
    Moderator

    If you saw, the change i suggested in the other forum post was to add this code.

    While in your else statement for EnemyHit(), change the following code:

                else
                {
                    StopCoroutine(Parry());
                    parrying = false;
                    ResetAllAttacks();
                    StartCoroutine(Slash());  //riposte
                }

    If it doesn’t work do notify us.

    #14472
    Anuk Thotawatta
    Participant

    ah thank you. it finally works. i’ve put parrying = false in the wrong place. thats why it was bugged

Viewing 5 posts - 1 through 5 (of 5 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: