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?
- This topic has 4 replies, 2 voices, and was last updated 6 months, 2 weeks ago by Elvin Sim.
-
AuthorPosts
-
June 6, 2024 at 4:03 am #14999June 6, 2024 at 4:04 am #15000::
<code>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); } }</code>
June 6, 2024 at 4:06 am #15001::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!
June 6, 2024 at 4:03 pm #15004::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.
June 6, 2024 at 4:10 pm #15005 -
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: