Weird behaviour when instantiating, animation won't play

Hello everyone,
I’m a fairly for fun/newbie unity user and recently I’ve been developing a space shooter for my phone inspired by the classic Space Invaders game.
I am creating a boss level and the mechanic is pretty simple after a timer passes the boss gets 2 extra helper ships in front of him and while they are alive he also gains a shield. So the player has to destroy them to get the shield off and do damage the boss.
Everything is working fine the minions spawn the boss’s shield instantiates at an empty child object I’ve placed in front of him and when I destroy the minions the shield disappears. The only problem is the shield will not play it’s default animation.
I have two codes that are responsible for all of this.
The spawner code:

public class secondBossShieldSpawn : MonoBehaviour
{
    public GameObject enemyShield;

    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {

        if (GameObject.Find("Ship4small(Clone)") != null || GameObject.Find("Ship4small2(Clone)") != null && GameObject.Find("bossShield(Clone)") == null)
        {
            Instantiate(enemyShield, transform.position, transform.rotation);
        }
    }
}

Pretty simple basically it checks if one of the two minions exist and if there is another shield already spawned.
And the shield code itself:

public class bossShieldSelfDestruct : MonoBehaviour
{
    public GameObject enemyBoss;
    // Start is called before the first frame update
    void Start()
    {
        enemyBoss = GameObject.Find("ShieldSpawn");
    }

    // Update is called once per frame
    void Update()
    {

        gameObject.transform.position = enemyBoss.transform.position;
        if (GameObject.Find("Ship4small") == null && GameObject.Find("Ship4small2") == null)
         {
           Destroy(gameObject);
         }
    }
}

Which should just follows the ship spawn position and when the minions are destroyed also destroys the shield itself.
I haven’t touched anything about the animator or the animation and even redid them a few times bit the problem persists no animation after instantiating the shield. The only setting that I changed is make the animation non-looping. If anyone has any ideas please share and if you need more info please ask!

Remember the first rule of GameObject.Find():

Do not use GameObject.Find();

More information: https://starmanta.gitbooks.io/unitytipsredux/content/first-question.html

Beyond that you just have to debug it.

You must find a way to get the information you need in order to reason about what the problem is.

What is often happening in these cases is one of the following:

  • the code you think is executing is not actually executing at all
  • the code is executing far EARLIER or LATER than you think
  • the code is executing far LESS OFTEN than you think
  • the code is executing far MORE OFTEN than you think
  • the code is executing on another GameObject than you think it is
  • you’re getting an error or warning and you haven’t noticed it in the console window

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run? what order does it run in?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?
  • are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

Knowing this information will help you reason about the behavior you are seeing.

You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as Debug.Log("Problem!",this);

If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer or iOS: https://discussions.unity.com/t/700551 or this answer for Android: https://discussions.unity.com/t/699654

Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

https://discussions.unity.com/t/839300/3

I’m assuming secondBossShieldSpawn is a script that is tied to the Boss GameObject? Doing

Instantiate (enemyShield, transform);

Should instantiate it as a child of the Boss, you shouldn’t need to have empty child object of the Boss.

Make sure you have a prefab of the enemyShield, and make sure that prefab has the correct Animator component, with the correct controller linked to it. Make sure that prefab is correctly being passed into secondBossShieldSpawn.

Not sure if I’m correct in saying so, but perhaps you should move the logic away from the Update function, place it in it’s own function like spawnShield() which will conditionally check if the shield should be applied to the boss. You can perhaps even do this using an Event System. It’s just because Update is ran per frame, so it’s going to be constantly checking the if statement to see if it’s true or not and then continuously instantiate a shield.

Yeah I think what you’re doing (just guessing here from what you’ve written, correct me if I’m wrong!) is you’re instantiating a shield on the empty game object which has a parent that is the Boss. So it’s like, Boss > empty Game Object > Shield. Whereas you shouldn’t need the Empty Game Object, you can just attach the script to the boss and instantiate a shield from the Boss.