Prefab not displayed

Hi !

So I’m having this weird issue. I’m building this game where I instantiate enemies in running time every given seconds. I have two types of enemies to instantiate, one is working OK, but the second type isn’t displayed event though it is created in my hierarchy. Even weirder, when I press pause in game, they are visible in the game screen. I’ve checked the prefab’s order in layer and it’s OK. Here’s my script, note that both types of enemies use more or less the same script, with only slight changes.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InstantiateBomber : MonoBehaviour
{
    private float bomberSpawnRate = 2.5f;

    public GameObject bomberPrefab;

    public Transform spawn_1, spawn_2, spawn_3, spawn_4, spawn_5, spawn_6, spawn_7, spawn_8;
    private float timer;
    private float waitTime = 5.0f;
    private int spawn_point;

    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating("CreateBomber", 0.5f, bomberSpawnRate);
    }

    void Update()
    {
        timer += Time.deltaTime;

        if (timer > waitTime)
        {
            if (bomberPrefab.GetComponent<BomberMove>().moveSpeed < 15.0)
            {
                bomberPrefab.GetComponent<BomberMove>().moveSpeed = AddSpeed(bomberPrefab.GetComponent<BomberMove>().moveSpeed);
            }

            timer = timer - waitTime;
        }

    }

    void CreateBomber()
    {
        spawn_point = Random.Range(1, 9);

        switch (spawn_point)
        {
            case 1:
                Instantiate(bomberPrefab, spawn_1.position, spawn_1.rotation);
                break;

            case 2:
                Instantiate(bomberPrefab, spawn_2.position, spawn_2.rotation);
                break;

            case 3:
                Instantiate(bomberPrefab, spawn_3.position, spawn_3.rotation);
                break;

            case 4:
                Instantiate(bomberPrefab, spawn_4.position, spawn_4.rotation);
                break;

            case 5:
                Instantiate(bomberPrefab, spawn_5.position, spawn_5.rotation);
                break;

            case 6:
                Instantiate(bomberPrefab, spawn_6.position, spawn_6.rotation);
                break;

            case 7:
                Instantiate(bomberPrefab, spawn_7.position, spawn_7.rotation);
                break;

            case 8:
                Instantiate(bomberPrefab, spawn_8.position, spawn_8.rotation);
                break;
        }
    }

    float AddSpeed(float newSpeed)
    {
        newSpeed += 0.2f;
        return newSpeed;
    }

}

Unlikely to be anything to do with the script, probably has to do with the prefabs themselves or how they are arranged in your object hierarchy.

You’re saying that these enemies are invisible in your game view while the game is running, but when you pause they suddenly appear? In both cases you’re looking at the game view and not the scene view? By “pause” do you mean the Unity editor’s pause feature, or some sort of in-game pause screen you’ve created?

Let me start out by saying welcome, but also recommending that you familiarize yourself with arrays / lists / collections to avoid having spawn_1, spawn_2, etc. Computers are really good at lists!

As to your issue, it looks like you are conflating the notion of an Instantiated object, and a prefab on disk.

I presume bomberPrefab points to something on disk. When you Instantiate it, the Instantiate returns a fresh copy of the thing that it just made, now living in the scene. In your code above, you are not doing anything with the value that Instantiate returns. Typically you would keep a copy of this reference if you wanted to do something further with it.

Another oddity is that this script is a spawner and it seems concerned with the speed of the bombers. That first off seems wrong, but what is further wrong is that it is modifying only ONE bomber, and it happens that it is modifying the actual disk asset, not the one you think is in the scene!

So straightening out the flow of how data typically goes:

  • you create a prefab, that exists on the disk(I assume you did this)
  • you drag a reference into your bomberPrefab (I assume you did this)
  • you call Instantiate on that prefab (as you did… sort of… keep reading)
  • usually that prefab has scripts to do things like increase its speed every so often (this obeys “area of concern” and makes each bomber responsible for itself)
  • if your spawner mechanism needs to do something more with the instantiated object, it must save the returned value from Instantiate:
public GameObject bomberPrefab; // as your code has
GameObject lastActualBomberCreated;

Now when you instantiate you can write down that latest one:

lastActualBomberCreated = Instantiate<GameObject>( bomberPrefab, position, rotation);

Keep in mind that only has has very last one. The next time something spawns, the original reference will be lost and that object will be all on its own, which is usually fine if it has scripts inside it that can control it.

Once you get familiar with Lists, you can put all those spawn points in a list, AND you can (optionally) make a list of bombers you created (i.e., add the reference that you get back from Instantiate into a list), which might have uses such as saying “are there too many bombers already on?”

Indeed I didn’t check this, it appears that my object is never displayed in my game view, but is visible in my scene view. I meant Unity pause feature.

Thanks for your reply !

I have indeed a prefab existing on the disk, which I instantiate every so often. I’m actually modifying the speed value of my object by referencing the moveSpeed variable in the bomber’s movement script, which is attached to the bomber prefab. The script shown above is actually attached to my “god object” so to speak, which manages the spawning of the enemies. The reason for this is that the game is kind of fast paced, so the enemies don’t stay long on screen. I want them to spawn with an enhanced moveSpeed every given seconds. I am in fact not modifying the object’s speed once it’s been instantiated.

Since I don’t need to access any specific enemy in runtime, I just use the Tag feature. For exemple I can detect a collision between an object tagged as “Enemy” and the player. This is why I don’t save the returned value of Instantiate.

I’ll definitely learn how to work with arrays & lists once I’ve fully understood the basics. I’ll probably try to optimize my code in a near future !

1 Like

Problem solved !
I tried to mangle with my camera’s parametres a bit, and it appears that if I alter the “near” parametre of the camera’s clipping planes, my object is visible.

Thanks for your time, and sorry it was such a stupid issue !

3 Likes

This helped me too.

hello, I am having the same issue as you and am wondering what values did you adjust the cameras neer parameters to ?