Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Question Want prefab instance instead of clone

Discussion in 'General Discussion' started by Cosmology27, Feb 21, 2023.

  1. Cosmology27

    Cosmology27

    Joined:
    Jul 11, 2019
    Posts:
    61
    I'm using a script to generate objects, and the objects being told to instantiate is a prefab. Here's the line.
    Code (CSharp):
    1. var NewMapTile = Instantiate(MapTilePrefab, (CurrentPos), Quaternion.identity);
    In this, MapTilePrefab is a serialized gameobject, where I have dragged in a prefab that I have made. This script is [ExecuteInEditMode], so when I run it, it creates the objects in the actual hierarchy permanently. The problem is, it's creating clones, rather than instances of the prefab. I want all the instances it creates to be actual references to the prefab, so that if I edit the prefab, it will edit every instance created.
    I have also tried this line of code, but I really don't understand how this works, and I'm getting a lot of errors.
    Code (CSharp):
    1. var NewMapTile = PrefabUtility.InstantiatePrefab(MapTilePrefab, (CurrentPos), Quaternion.identity);
    Not only am I getting errors in the line of code itself, but it also seems my further references in the code to change stuff gets errors too. For example, I do this right after instantiating the object.
    Code (CSharp):
    1. NewMapTile.transform.GetComponent<MapTileStats>().CoordX = x + 1f;
    2.                     NewMapTile.transform.GetComponent<MapTileStats>().CoordZ = y + 1f;
    So my question is, how do I make the instantiated objects prefab references, rather than clones?
    Thanks for any help you can provide.
     
  2. Cosmology27

    Cosmology27

    Joined:
    Jul 11, 2019
    Posts:
    61
    Sorry for the post, I figured it out from a YouTube video basically immediately.


    Here's what I did to fix it, in case anyone else wants to see. Doing it this way, it makes it an actual link to the prefab, BUT it doesn't let you insert the position to create it, so you have to tell it after (like I did in the second line here).
    Also note, you need to include "using UnityEditor;" at the top.

    Code (CSharp):
    1. GameObject NewMapTile = PrefabUtility.InstantiatePrefab(MapTilePrefab) as GameObject;
    2.                     NewMapTile.transform.position = CurrentPos;
     
  3. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,917
    Just an FYI you're posting a lot of stuff in the wrong sub forum section. General Discussion is not a help section.

    Your most recent two posts should be in the scripting sub-forum.
     
    Ryiah likes this.
  4. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,137
    Meanwhile I fed the question directly into the chatbot. Less time to read than listen to that guy ramble and you can copy/paste the code right into your script.

    -----

    To instantiate a prefab as an actual reference rather than a clone, you can use the PrefabUtility.InstantiatePrefab method, as you have already attempted. The reason you are getting errors is because this method returns an object of type UnityEngine.Object, rather than the actual game object that you need to access the components and modify their properties. To fix this, you can cast the returned object to a GameObject:

    Code (csharp):
    1. var NewMapTile = PrefabUtility.InstantiatePrefab(MapTilePrefab) as GameObject;
    2. NewMapTile.transform.position = CurrentPos;
    3. NewMapTile.transform.rotation = Quaternion.identity;
    Note that you should set the position and rotation of the new instance after instantiating the prefab. This is because the InstantiatePrefab method does not take a position or rotation as arguments.

    Now, when you modify the properties of the MapTileStats component, it will modify the instance's values, rather than those of the prefab. If you modify the prefab, the changes will be reflected in all instances of the prefab.

    Code (csharp):
    1. NewMapTile.GetComponent<MapTileStats>().CoordX = x + 1f;
    2. NewMapTile.GetComponent<MapTileStats>().CoordZ = y + 1f;
     
    Last edited: Feb 21, 2023