Script trying to delete prefab. Need help!

I’m coding a portal network system into my game, and have it setup so that whenever the player goes through the portal, the portals get destroyed. The problem is that instead of destroying the objects in the scene, the script tries to delete the prefabs themselves! I know I’m doing something wrong, I just don’t know how to fix it. Can someone please help?

Current code:

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

public class PortalController : MonoBehaviour
{
    float range = 50f;

    //Makes sure there is always exactly one player created portal network in the scene
    int netCount;

    //The game objects I'm trying to destroy after the portal is used. I know why it's not working (Assigned to prefabs and therefore trying to destroy said prefabs), I just have no clue how to fix it
    public GameObject portalEnter;
    public GameObject portalExit;

    GameObject switcher;

    public Camera playerCam;

    public Transform portalEnterLocation;

    void Start()
    {
        netCount = 0;
    }

    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            SetNet();
        }
    }

    void SetNet()
    {
        //Instantiates the first portal right next to the player.
        Instantiate(portalEnter, portalEnterLocation.position, Quaternion.identity);

        //setting the second portal using raycasting. For whatever reason doesn't show the mesh renderer when instantiated. Teleporting to it on it works fine, so it might just be fully inside the hit object. Other theories welcome
        RaycastHit hit;
        if (Physics.Raycast(playerCam.transform.position, playerCam.transform.forward, out hit, range))
        {
            Instantiate(portalExit, hit.transform.position, Quaternion.identity);
            netCount++;
            switcher.GetComponentInParent<WeaponSwitcher>().SwitchToPistol();
            switcher.GetComponentInParent<WeaponSwitcher>().StartPortalCooldown();
        }
    }

    public void Teleported()
    {
        //Call from PlayerController.cs after teleport
        Destroy(portalEnter);
        Destroy(portalExit);
        netCount--;
    }
}

If your portalEnter and portalExit are prefabs, it’s doing exactly what you tell it to.

When you Instantiate the clones, you get a reference back to the clones.

So you probably want two more variables for those (assuming you can only have 1 clone each)

private GameObject clonedPortalEnter; //Set this at the top with your other variables.


clonedPortalEnter = Instantiate(portalEnter, portalEnterLocation.position, Quaternion.identity);

Destroy(clonedPortalEnter);
1 Like

So do I replace Instantiate(portalEnter, yada yada yada) with clonedPortalEnter = Instantiate(portalEnter, yada yada yada)?

Yes, with the variable at the top. Instantiate returns a reference to the cloned object, so you need to capture that at the time of creation.

The other option is you don’t instantiate or destroy the clones, you just have them off in the scene and turn them on and move them as needed. But, that’s another tutorial.

Okay, thanks a lot, b’y!

@Brathnann it’s still trying to delete the prefabs. Help?

And did you change the destroy code like I showed?

Yes, I did.

If it’s trying to delete your prefabs, then it’s not this code doing it anymore. Assuming you have it setup correctly and recompiled. Where else do you reference those prefabs?

Please show your updated code if this is the only script targeting those prefabs.

Here:

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

public class PortalController : MonoBehaviour
{
    float range = 50f;

    int netCount;

    //The prefabs

    public GameObject portalEnter;
    public GameObject portalExit;

    //The clones. Not sure exactly why it isn't working.
    GameObject portalEnterClone;
    GameObject portalExitClone;

    GameObject switcher;

    public Camera playerCam;

    public Transform portalEnterLocation;

    void Start()
    {
        netCount = 0;
    }

    void Update()
    {
        if (Input.GetButtonDown("Fire1") && netCount == 0)
        {
            SetNet();
        }
    }

    void SetNet()
    {
        //Instantiates the first portal right next to the player. Followed the instructions, but is still trying to delete prefabs
        portalEnterClone = Instantiate(portalEnter, portalEnterLocation.position, Quaternion.identity);

        //seting the second portal using raycasting.
        RaycastHit hit;
        if (Physics.Raycast(playerCam.transform.position, playerCam.transform.forward, out hit, range))
        {
            portalExitClone = Instantiate(portalExit, hit.transform.position, Quaternion.identity);
            netCount++;
            switcher.GetComponentInParent<WeaponSwitcher>().SwitchToPistol();
            switcher.GetComponentInParent<WeaponSwitcher>().StartPortalCooldown();
        }
    }

    public void Teleported()
    {
        //Call from PlayerController.cs after teleport

        //These two lines aren't working
        Destroy(portalEnterClone);
        Destroy(portalExitClone);

        netCount--;
    }
}

The prefabs are referenced in the player controller to be able to teleport… F*ck, that’s where it’s stemming, isn’t it?

There is definitely nothing wrong with this script now. What is the PlayerController script doing?

I think I figured it out. Was telling it to both run the teleport function AND destroy the objects from that script. I’m stupid sometimes.

I’ll tell you one thing. It’s not stupidity. It’s programming. lol.

Doesn’t matter how many years a person has been programming, we all make mistakes and for different reasons. Late nights. Distractions. Or my favorite, I’m thinking of another script in my head while working on a completely different script. Sometimes it happens.

Mistakes are made sometimes and it’s good to be able to have someone to walk through the code on occasion to find that error.

Glad you have it figured out now.

1 Like

@Brathnann thanks! Now I gotta figure out how to get some additional crap working for it. Do you know how to make something happen at the end of a raycast if it doesn’t hit something inside it’s range?

I’m assuming what you want is similar to Unity’s example.
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

Just a simple if else statement to determine if it hits something.

Yeah, kinda like that. Not sure how to make it work, though (Instantiating something at the end of the raycast).