Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

How can I place a prefab in another gameobject place with the same center ?

Discussion in 'Scripting' started by DubiDuboni, Oct 13, 2019 at 1:14 AM.

  1. DubiDuboni

    DubiDuboni

    Joined:
    Feb 5, 2019
    Posts:
    90
    I have this door and it's center is : 23.1, 52, -6



    And then when replacing a prefab instead this door the prefab center is 20.9, 52, -6
    The result is that the prefab placed a bit in the back from the door position and if I'm using local in my script the prefab will be position a bit to the front position from the door position.

    It will show that the prefab is at the same position as the door was but since the center is not the same it will not place the prefab at the right position.

    This is the prefab after replaced instead the door:



    And this is my code. I wonder how can I keep or set the prefab center to be like the door center through the code :

    Or if I need to do it once in the editor using a empty GameObject and then make a prefab from the empty GameObject then how do I make it in the editor ? I didn't understand if the prefab should be child of the empty gameobject ? And then how to set the empty gameobject to be in the right center of the door ? And then the prefab child what position should he be ?


    Maybe someone can draw it visual to show how to do it ? I didn't understand.


    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Linq;
    5. using UnityEditor;
    6. using UnityEngine;
    7.  
    8. public class SaveTransformsInfo : EditorWindow
    9. {
    10.     [SerializeField] private GameObject prefab;
    11.  
    12.     [MenuItem("Tools/Replace With Prefab")]
    13.     static void CreateReplaceWithPrefab()
    14.     {
    15.         EditorWindow.GetWindow<SaveTransformsInfo>();
    16.     }
    17.  
    18.     private void OnGUI()
    19.     {
    20.         prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", prefab, typeof(GameObject), false);
    21.  
    22.         if (prefab == null || Selection.gameObjects.Length == 0)
    23.         {
    24.             GUI.enabled = false;
    25.         }
    26.         else
    27.         {
    28.             GUI.enabled = true;
    29.         }
    30.         if (GUILayout.Button("Replace"))
    31.         {
    32.             var selection = Selection.gameObjects;
    33.             var parentGameobjects = CheckParents(selection);
    34.  
    35. #if UNITY_EDITOR
    36.             UnityEditor.Selection.objects = parentGameobjects;
    37. #endif
    38.  
    39.             for (var i = parentGameobjects.Length - 1; i >= 0; --i)
    40.             {
    41.                 var selected = parentGameobjects[i];
    42.                 var prefabType = PrefabUtility.GetPrefabType(prefab);
    43.                 GameObject newObject;
    44.  
    45.                 if (prefabType == PrefabType.Prefab)
    46.                 {
    47.                     newObject = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
    48.                 }
    49.                 else
    50.                 {
    51.                     newObject = Instantiate(prefab);
    52.                     newObject.name = prefab.name;
    53.                 }
    54.  
    55.                 if (newObject == null)
    56.                 {
    57.                     Debug.LogError("Error instantiating prefab");
    58.                     break;
    59.                 }
    60.  
    61.                 Undo.RegisterCreatedObjectUndo(newObject, "Replace With Prefabs");
    62.                 newObject.transform.parent = selected.transform.parent;
    63.                 newObject.transform.position = selected.transform.position;
    64.                 newObject.transform.rotation = selected.transform.rotation;
    65.                 newObject.transform.localScale = selected.transform.localScale;
    66.                 newObject.transform.SetSiblingIndex(selected.transform.GetSiblingIndex());
    67.                 DestroyObjectInPrefab(selected.transform);
    68.             }
    69.         }
    70.  
    71.         if(GUILayout.Button("Get Info"))
    72.         {
    73.             TransformSaver.SaveTransform(null, Selection.gameObjects[0]);
    74.         }
    75.  
    76.         GUI.enabled = false;
    77.         EditorGUILayout.LabelField("Selection count: " + Selection.gameObjects.Length);
    78.     }
    79.  
    80.     private GameObject[] CheckParents(params GameObject[] objects)
    81.     {
    82.         List<GameObject> parents = new List<GameObject>(objects.Length);
    83.         Transform[] transforms = objects.Select(go => go.transform).ToArray();
    84.         for (int objectIndex = 0; objectIndex < transforms.Length; objectIndex++)
    85.         {
    86.             if (!IsChildOfAny(transforms[objectIndex], transforms))
    87.                 parents.Add(transforms[objectIndex].gameObject);
    88.         }
    89.  
    90.         return parents.ToArray();
    91.     }
    92.  
    93.     private bool IsChildOfAny(Transform potentialChild, params Transform[] potentialParents)
    94.     {
    95.         for (int index = 0; index < potentialParents.Length; index++)
    96.         {
    97.             if (IsParentOf(potentialParents[index], potentialChild))
    98.                 return true;
    99.         }
    100.         return false;
    101.     }
    102.  
    103.     private bool IsParentOf(Transform potentialParent, Transform potentialChild)
    104.     {
    105.         if (potentialChild.parent == null)
    106.             return false;
    107.  
    108.         if (potentialChild.parent == potentialParent)
    109.             return true;
    110.  
    111.         return IsParentOf(potentialParent, potentialChild.parent);
    112.     }
    113.  
    114.     private void DestroyObjectInPrefab(Transform transform)
    115.     {
    116.         if (PrefabUtility.IsPartOfPrefabInstance(transform))
    117.         {
    118.             //if a part of a prefab instance then get the instance handle
    119.             Object prefabInstance = PrefabUtility.GetPrefabInstanceHandle(transform);
    120.             //destroy the handle
    121.             if (prefabInstance != null)
    122.             {
    123.                 Undo.DestroyObjectImmediate(prefabInstance);
    124.             }
    125.         }
    126.         //the usual destroy immediate to clean up scene objects
    127.         //DestroyImmediate(transform.gameObject, true);
    128.         Undo.DestroyObjectImmediate(transform.gameObject);
    129.     }
    130.  
    131.     private void OnSelectionChange()
    132.     {
    133.         Repaint();
    134.     }
    135. }
    136.  
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    5,694
    When you create a prefab, make sure its center is a the base. Then align objects in prefab. After than, when you drop you prefab at floor position, all object should be positioned correctly.
     
    MNNoxMortem likes this.