Forum begins after the advertisement:


[Part 10] Can you help me to see the boss I created?

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity [Part 10] Can you help me to see the boss I created?

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #14999
    #15000
    Elvin Sim
    Participant
    public class GateOfDarkness : Enemy
    {
        // Summoning variables
        [SerializeField] public GameObject[] summonableEnemies; // array of enemies that can be summoned
        [SerializeField] public float summonCooldown = 5f; // cooldown between summons
        [SerializeField] public float summonRange = 10f; // range within which enemies can be summoned
    
        // Teleportation variables
        [SerializeField] public float teleportCooldown = 10f; // cooldown between teleports
        [SerializeField] public float teleportRange = 20f; // range within which the boss can teleport
    
        // Animation variables
        /*[SerializeField] public string idleAnimation = "GateOfDarkness_Idle";
        [SerializeField] public string summonAnimation = "GateOfDarkness_Summon";
        [SerializeField] public string teleportAnimation = "GateOfDarkness_Teleport";
        [SerializeField] public string deathAnimation = "GateOfDarkness_Death";
        */
    
        [SerializeField] private float chaseDistance;
    
        private float summonTimer = 2f;
        private float teleportTimer = 2f;
    
        float timer;
    
        protected override void Start()
        {
            base.Start();
            ChangeState(EnemyStates.GateOfDarkness_Idle);
        }
    
        protected override void Update()
        {
            base.Update();
            if (!PlayerController.Instance.pState.alive)
            {
                ChangeState(EnemyStates.GateOfDarkness_Idle);
            }
    
            // Summoning logic
            if (summonTimer < summonCooldown)
            {
                summonTimer += Time.deltaTime;
            }
            else
            {
                SummonEnemy();
                summonTimer = 0f;
            }
    
            // Teleportation logic
            if (teleportTimer < teleportCooldown)
            {
                teleportTimer += Time.deltaTime;
            }
            else
            {
                Teleport();
                teleportTimer = 0f;
            }
        }
    
        protected override void UpdateEnemyState()
        {
            /*// Update state based on current animation
            if (anim.GetCurrentAnimatorStateInfo(0).IsName(idleAnimation))
            {
                GetCurrentEnemyState = EnemyStates.GateOfDarkness_Idle;
            }
            else if (anim.GetCurrentAnimatorStateInfo(0).IsName(summonAnimation))
            {
                GetCurrentEnemyState = EnemyStates.GateOfDarkness_Summon;
            }
            else if (anim.GetCurrentAnimatorStateInfo(0).IsName(teleportAnimation))
            {
                GetCurrentEnemyState = EnemyStates.GateOfDarkness_Teleport;
            }*/
            float _dist = Vector2.Distance(transform.position, PlayerController.Instance.transform.position);
            
            switch (GetCurrentEnemyState)
            {
                case EnemyStates.GateOfDarkness_Idle:
                    rb.velocity = new Vector2(0, 0);
                    if (_dist < chaseDistance)
                    {
                        ChangeState(EnemyStates.GateOfDarkness_Summon);
                    }
                    break;
    
                case EnemyStates.GateOfDarkness_Summon:
                    rb.MovePosition(Vector2.MoveTowards(transform.position, PlayerController.Instance.transform.position, Time.deltaTime * speed));
                    if (_dist > chaseDistance)
                    {
                        ChangeState(EnemyStates.GateOfDarkness_Idle);
                    }
                    break;
    
                case EnemyStates.GateOfDarkness_Teleport:
                    timer += Time.deltaTime;
    
                    if (timer > teleportTimer)
                    {
                        ChangeState(EnemyStates.GateOfDarkness_Idle);
                        timer = 0;
                    }
                    break;
    
                case EnemyStates.GateOfDarkness_Death:
                    Death(Random.Range(5, 10));
                    break;
            }
        }
    
        protected override void ChangeCurrentAnimation()
        {
            anim.SetBool("Idle", GetCurrentEnemyState == EnemyStates.GateOfDarkness_Idle);
    
            anim.SetBool("Summon", GetCurrentEnemyState == EnemyStates.GateOfDarkness_Summon);
    
            anim.SetBool("Teleport", GetCurrentEnemyState == EnemyStates.GateOfDarkness_Teleport);
    
            if (GetCurrentEnemyState == EnemyStates.GateOfDarkness_Death)
            {
                anim.SetTrigger("Death");
                int LayerIgnoreRaycast = LayerMask.NameToLayer("IgnorePlayer");
                gameObject.layer = LayerIgnoreRaycast;
            }
        }
    
        private void SummonEnemy()
        {
            // Choose a random enemy to summon
            int randomIndex = Random.Range(0, summonableEnemies.Length);
            GameObject summonedEnemy = summonableEnemies[randomIndex];
    
            // Instantiate the enemy at a random position within the summon range
            Vector3 summonPosition = transform.position + new Vector3(Random.Range(-summonRange, summonRange), Random.Range(-summonRange, summonRange));
            GameObject instantiatedEnemy = Instantiate(summonedEnemy, summonPosition, Quaternion.identity);
    
            // Set the enemy's parent to the portal boss
            instantiatedEnemy.transform.parent = transform;
        }
    
        private void Teleport()
        {
            // Teleport to a random position within the teleport range
            Vector3 teleportPosition = transform.position + new Vector3(Random.Range(-teleportRange, teleportRange), Random.Range(-teleportRange, teleportRange));
            transform.position = teleportPosition;
        }
    
        public override void EnemyGetsHit(float _damageDone, Vector2 _hitDirection, float _hitForce)
        {
            base.EnemyGetsHit(_damageDone, _hitDirection, _hitForce);
    
            if (health > 0)
            {
                ChangeState(EnemyStates.GateOfDarkness_Teleport);
            }
            else
            {
                ChangeState(EnemyStates.GateOfDarkness_Death);
            }
        }
    
        protected override void Death(float _destroyTime)
        {
            rb.gravityScale = 12;
            base.Death(_destroyTime);
        }
    }
    #15001
    Elvin Sim
    Participant

    The boss can idle, summon, teleport and death, but for the summon and teleport animation, I don’t know why cannot play, and if you see the big comment things is that I previous use code but cannot work, so I use the bat as reference still cannot work, so can you help me to see where is the bug, thank you very much!

    #15004
    Joseph Tang
    Moderator

    I am unable to test your code, so you will have to test it on your end. I suggest commenting out certain states first and checking if your method of using a Bool for your animations is necessary.
    I suggest you test by playing with your boss in action with the animator window open to see what’s actually happening in there. Perhaps bools are being called or set false too quiclkly.

    Perhaps you should simply use a Trigger parameter for your Summon and Teleport animation instead.

    Then you should have exit time added to your transiitons from Summon > Idle, and also Any State > Teleport.

    This will prevent instantly switching animations if the bools change while in the middle of an animation.

    #15005
    Elvin Sim
    Participant

    okok thank you I will test it later

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: