Forum begins after the advertisement:


[part 10] boss problems

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

    my pillers are rotated 90degrees for some reason and my boss does double damage or sometimes instantly kills me. also my i-frames doesnt seem to work when im fighting the boss

    View post on imgur.com

    #14362
    Anuk Thotawatta
    Participant

    i changed my diving pillars script to this:

    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(piller, _pillarSpawnPointRight, Quaternion.Euler(0,0,0));
                Instantiate(piller, _pillarSpawnPointLeft, Quaternion.Euler(0,0,0));
    
                _spawnDistance += 5;
            }
            ResetAllAttacks();
        }

    and now my pillar is straight but now all 10 pillars are in one spot and touching that insta kills me. how do i get my pillars to be far apart?

    View post on imgur.com

    #14375
    Joseph Tang
    Moderator

    For the code, you would want it to be this:

        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();
        }

    the code should work, and the only problem with yours is that the Quaternion.Euler() is not [-90].
    This should allow the _spawnDistance to work.

    #14381
    Anuk Thotawatta
    Participant

    i figured it out. the problem was that when i was animating the pillars i have accidently recorded the position along with the scale. that makes every pillar move to a set position.

    I made it until the outbreak attack in the video. and a new bug appeared. the boss slowly floats down after doing the outbreak attack.

    View post on imgur.com

    also my i-frames and time slow effect doesnt seem to work when im fighting the boss

    #14382
    Anuk Thotawatta
    Participant

    Fixed the slow falling bug but now the boss keeps running mid air instead of being in the last frame of the cast animation.
    also if the player hits boss mid outbreak the boss starts to rotate.

    View post on imgur.com

    i added the RigidbodyConstraints2D.FreezeRotation; line to void outbreak() but then the boss doesnt float during outbreak. he just follows me around while shooting fireballs

    View post on imgur.com

    void OutBreakAttack(){
            if(THK_Boss.Instance.outBreakAttack){
                Vector2 _newPos = Vector2.MoveTowards(rb.position, THK_Boss.Instance.moveToPosition, THK_Boss.Instance.speed * 1.5f * Time.fixedDeltaTime);
                rb.MovePosition(_newPos);
                float _distance = Vector2.Distance(rb.position, _newPos);
                if(_distance < 0.1f){
                    THK_Boss.Instance.rb.constraints = RigidbodyConstraints2D.FreezePosition;
                    THK_Boss.Instance.rb.constraints = RigidbodyConstraints2D.FreezeRotation;
                }
            }
        }
    #14391
    Joseph Tang
    Moderator

    For all the problems with your Outbreak attack,
    follow the code below and it should fix your rotation, the falling off the Boss and staying in place.

    What’s likely happening is that
    1) Your boss is not falling fast because it’s gravity scale is 1 and you did not include the rb.velocity code in your Outbreak() method to push the boss to the ground & there is not falling set in the Boss_Idle or Boss_Run.
    2) Your boss is rotating after being hit because in your Outbreak() method, likely because you did not freeze rotation in the code.
    3) Check that your Cast animation parameter is a Bool. Then check if you have a code: anim.SetBool("Cast", false);, being called early instead of only after the Oubreak()

    Please check that your code is as follows:

    For your TheHollowKnight.cs

        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(110, 130))); //downwards
                Instantiate(barrageFireball, transform.position, Quaternion.Euler(0, 0, Random.Range(50, 70))); // diagonally right
                Instantiate(barrageFireball, transform.position, Quaternion.Euler(0, 0, Random.Range(260, 280))); // diagonally 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();
        }

    For the Boss_BendDown.cs

        void OutbreakAttack()
        {
            if (TheHollowKnight.Instance.outbreakAttack)
            {
                Vector2 _newPos = Vector2.MoveTowards(rb.position, TheHollowKnight.Instance.moveToPosition,
                    TheHollowKnight.Instance.speed * 1.5f * Time.fixedDeltaTime);
                rb.MovePosition(_newPos);
    
                float _distance = Vector2.Distance(rb.position, _newPos);
                if (_distance < 0.1f)
                {
                    TheHollowKnight.Instance.rb.constraints = RigidbodyConstraints2D.FreezePosition;
                }
            }
        }

    In your Boss_Idle and Boss_Run, ensure there’s one of this code:

            if (!TheHollowKnight.Instance.Grounded())
            {
                rb.velocity = new Vector2(rb.velocity.x, -25); //if knight is not grounded, fall to ground
            }
    #14394
    Anuk Thotawatta
    Participant

    my code is identical to yours. and it seems when the boss locks x and y position the rotation(z) lock tickbox becomes unchecked

    View post on imgur.com

    #14405
    Joseph Tang
    Moderator

    If you could, can you copy and paste the entire TheHollowKnight.cs and Boss_Dive.cs code?

    You likely have a RigidbodyConstraints2D.None being called somewhwere early.

    #14416
    Anuk Thotawatta
    Participant

    THK_boss code:

    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(!attacking){
                attackCountdown-=Time.deltaTime;
            }
            if(stunned){
                rb.velocity = Vector2.zero;
            }
            /*if(!Grounded()){
                anim.SetBool("Run",false);
            }*/
        }
    
        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;
                        break;
                    case EnemyStates.THK_Stage2:
                        canStun = true;
                        break;
                    case EnemyStates.THK_Stage3:
                        canStun = false;
                        break;
                    case EnemyStates.THK_Stage4:
                        canStun = false;
                        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());
                    DiveAttackJump();
                    //BarrageBendDown();
                    //OutBreakBendDown();
                    //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.5f);
            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){//testing how many hits to stun
                            ResetAllAttacks();
                            StartCoroutine(Stunned());
                        }
    
                    }
                    base.EnemyHit(_damageDone,_hitDirection,_hitForce);
                    if(currentEnemyState != EnemyStates.THK_Stage4){
                        ResetAllAttacks();
                        StartCoroutine(Parry());
                    }
                    
                }
                else{
                    StopCoroutine(Parry());
                    ResetAllAttacks();   
                    StartCoroutine(Slash());//riposte
                }
            }
            else{
                StopCoroutine(Stunned());
                anim.SetBool("Stunned",false);
                stunned = false;
            }
            #region Health to State
            if(health>20){
                ChangeState(EnemyStates.THK_Stage1);
            }
            if(health<= 15 && health<10){
                ChangeState(EnemyStates.THK_Stage2);
            }
            if(health<= 10 && health<5){
                ChangeState(EnemyStates.THK_Stage3);
            }
            if(health<5){
                ChangeState(EnemyStates.THK_Stage4);
            }
            #endregion
            
        }
        
    
        public IEnumerator Stunned(){
            stunned = true;
            hitCounter = 0;
            anim.SetBool("Stunned",true);
            yield return new WaitForSeconds(6f);
            anim.SetBool("Stunned",false);
            stunned = false;
        }
    }
    
    

    Boss_Dive:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class THK_Dive : StateMachineBehaviour
    {
        Rigidbody2D rb;
        bool callOnce;
        // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
        override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
        {
            rb = animator.GetComponentInParent<Rigidbody2D>();
        }
    
        // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
        override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
        {
            THK_Boss.Instance.divingCollider.SetActive(true);
            if(THK_Boss.Instance.Grounded()){
                THK_Boss.Instance.divingCollider.SetActive(false);
                if(!callOnce){
                    THK_Boss.Instance.DivingPillars();
                    animator.SetBool("Dive", false);
                    THK_Boss.Instance.ResetAllAttacks();
                    callOnce = true;
                }
            }
        }
    
        // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
        override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
        {
            callOnce = false;  
        }
    
    }
    
    #14436
    Joseph Tang
    Moderator

    Sorry, I gave the wrong instruction, I wanted to check the Boss_BendDown script instead.

    However, I want you to try this first:

    1) Delete the RigidbodyConstraints2D.None;

        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(110, 130))); //downwards
                Instantiate(barrageFireball, transform.position, Quaternion.Euler(0, 0, Random.Range(50, 70))); // diagonally right
                Instantiate(barrageFireball, transform.position, Quaternion.Euler(0, 0, Random.Range(260, 280))); // diagonally 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();
        }

    2) If you’ve tested it out and see that your Boss now has both it’s Freeze Position and Freeze Rotation active,

        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(110, 130))); //downwards
                Instantiate(barrageFireball, transform.position, Quaternion.Euler(0, 0, Random.Range(50, 70))); // diagonally right
                Instantiate(barrageFireball, transform.position, Quaternion.Euler(0, 0, Random.Range(260, 280))); // diagonally left
    
                yield return new WaitForSeconds(0.2f);
            }
            yield return new WaitForSeconds(0.1f);
            rb.constraints &= ~RigidbodyConstraints2D.FreezePosition;
            rb.constraints = RigidbodyConstraints2D.FreezeRotation;
            rb.velocity = new Vector2(rb.velocity.x, -10);
            yield return new WaitForSeconds(0.1f);
            anim.SetBool("Cast", false);
            ResetAllAttacks();
        }

    The code above selectively removes the freezeposition constraints only, effectively doing the initial intentions of the code by removing the freeze position and keeping freeze rotation.

    Of course, If Freeze Rotation is still being removed, that means that there is definitely another piece of code somewhere calling to remove the freezerotation.

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

Go to Login Page →


Advertisement below: