コード例 #1
0
    // Compile all hierarchical prefabs
    public static void CompileAllHierarchicalPrefabs()
    {
        // Ensure the compilation directory exist
        Directory.CreateDirectory(GetCompiledHierarchicaPrefabFolderGlobalPath());

        // Empty it
        DestroyAllCompiledHierarchicalPrefabs();

        // Will keep track of the dirty instance model
        // Because if we set the resource to dirty too soon it will only save the root and let the children in the scene
        List <HierarchicalPrefabInstance> oDirtyHierarchicalPrefabInstanceModels = new List <HierarchicalPrefabInstance>();

        // loop through all the hierarchical prefabs in the resources
        bool bAtLeastOnePrefabCompiled = false;

        foreach (string rAssetPath in AssetDatabase.GetAllAssetPaths())
        {
            // Is this a prefab?
            GameObject rGameObjectPrefab = AssetDatabase.LoadAssetAtPath(rAssetPath, typeof(GameObject)) as GameObject;
            if (rGameObjectPrefab != null)
            {
                // Try to grab a hierarchical prefab
                HierarchicalPrefabInstance rHierarchicalPrefabInstanceModel = rGameObjectPrefab.GetComponent <HierarchicalPrefabInstance>();
                if (rHierarchicalPrefabInstanceModel != null)
                {
                    // If need to be compile
                    if (rHierarchicalPrefabInstanceModel.CanBeInstantiatedAtRuntime)
                    {
                        // Compile it
                        rHierarchicalPrefabInstanceModel.Compile();
                        // Add it to the dirty list
                        oDirtyHierarchicalPrefabInstanceModels.Add(rHierarchicalPrefabInstanceModel);

                        bAtLeastOnePrefabCompiled = true;
                    }
                }
            }
        }

        // loop through all the hierarchical prefabs in the resources
        foreach (HierarchicalPrefabInstance rHierarchicalPrefabInstanceModel in oDirtyHierarchicalPrefabInstanceModels)
        {
            // Set dirty
            EditorUtility.SetDirty(rHierarchicalPrefabInstanceModel);
        }

        // Compilation is up to date
        NestedPrefabEditorSettings.MustCompile = false;

        if (bAtLeastOnePrefabCompiled)
        {
            // Notify the user of the compilation completion
            Debug.Log("Compilation Successful!");
        }
        else
        {
            DisplayNothingToCompileMessage();
        }
    }
コード例 #2
0
    // On inspector gui
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        HierarchicalPrefabInstance rHierarchicalPrefabInstance = target as HierarchicalPrefabInstance;

        rHierarchicalPrefabInstance.CanBeInstantiatedAtRuntime = EditorGUILayout.Toggle("Can Be Instantiated", rHierarchicalPrefabInstance.CanBeInstantiatedAtRuntime);
    }
コード例 #3
0
    // Convert into hierarchical prefab
    public static HierarchicalPrefabInstance ConvertIntoHierarchicalPrefab(GameObject a_rGameObjectToConvert)
    {
        // Add the hierarchical prefab if not there
        HierarchicalPrefabInstance rHierarchicalPrefabInstance = NestedPrefabComponentUtility.GetOrCreate <HierarchicalPrefabInstance>(a_rGameObjectToConvert);

        // Clear the hierarchy from the prefab and add instantiator to respawn them when needed
        TrimHierarchicalPrefab(a_rGameObjectToConvert.transform);

        return(rHierarchicalPrefabInstance);
    }
コード例 #4
0
    // Save as hierarchical prefab
    public static bool SaveAsHierarchicalPrefab(GameObject a_rGameObjectToSave, string a_rSavePath)
    {
        // Convert to hierarchical prefab
        HierarchicalPrefabInstance rHierarchicalPrefabInstanceModel = NestedPrefabEditorUtility.ConvertIntoHierarchicalPrefab(a_rGameObjectToSave);

        // The prefab to save into
        Object rPrefabObjectToSaveInto = AssetDatabase.LoadAssetAtPath(a_rSavePath, typeof(Object));

        // Check if the hierarchical prefab is cyclic
        if (IsHierarchicalPrefabInstanceCyclic(rHierarchicalPrefabInstanceModel, rPrefabObjectToSaveInto))
        {
            Debug.LogError("You can't create cyclic hierarchy!");
            rHierarchicalPrefabInstanceModel.RevertToHierarchicalPrefab();
            return(false);
        }

        // Save into a prefab at save path
        if (rPrefabObjectToSaveInto == null)
        {
            rPrefabObjectToSaveInto = PrefabUtility.CreateEmptyPrefab(a_rSavePath);
        }
        else
        {
            // If an object replace a prefab copy the replaced prefab version number
            // To the one replacing
            if (rPrefabObjectToSaveInto != rHierarchicalPrefabInstanceModel.HierarchicalPrefab)
            {
                // Try to get the hierarchical prefab instance model of the soon to de replaced prefab
                GameObject rPrefabToBeReplacedGameObject = NestedPrefabEditorUtility.GetPrefabGameObject(rPrefabObjectToSaveInto);
                if (rPrefabToBeReplacedGameObject != null)
                {
                    HierarchicalPrefabInstance rHierarchicalPrefabInstanceModelToBeReplaced = rPrefabToBeReplacedGameObject.GetComponent <HierarchicalPrefabInstance>();
                    if (rHierarchicalPrefabInstanceModelToBeReplaced != null)
                    {
                        // Copy the version number of the instance to be replaced
                        rHierarchicalPrefabInstanceModel.CopyVersionNumber(rHierarchicalPrefabInstanceModelToBeReplaced);
                    }
                }
            }
        }

        // Notify model instance of it's saving
        rHierarchicalPrefabInstanceModel.OnSaveModelInstanceBeforePrefabReplacement(PrefabUtility.GetPrefabObject(rPrefabObjectToSaveInto));

                #if BEFORE_UNITY_4_3
        EditorUtility.ReplacePrefab(a_rGameObjectToSave, rPrefabObjectToSaveInto, ReplacePrefabOptions.ConnectToPrefab);
                #else
        PrefabUtility.ReplacePrefab(a_rGameObjectToSave, rPrefabObjectToSaveInto, ReplacePrefabOptions.ConnectToPrefab);
                #endif

        // Compilation is not up to date
        NestedPrefabEditorSettings.MustCompile = true;

        return(true);
    }
コード例 #5
0
    // Ensure the prefab validity :
    // Either a functionning hierarchical prefab or a clean classic prefab.
    public static void EnsurePrefabValidity(GameObject a_rPrefabGameObjectToCheck)
    {
        // If the prefab is still valid don't bother updating it
        HierarchicalPrefabInstance rHierarchicalPrefabInstanceModel = a_rPrefabGameObjectToCheck.GetComponent <HierarchicalPrefabInstance>();

        if (rHierarchicalPrefabInstanceModel == null || rHierarchicalPrefabInstanceModel.IsValid() == false)
        {
            // If it's not a hierarchical prefab, ensure that the prefab is clean
            NestedPrefabEditorUtility.DisconnectResourceFromHierarchicalPrefab(a_rPrefabGameObjectToCheck);
        }
    }
コード例 #6
0
    // On Hierarchical prefab update
    public void OnHierarchicalPrefabUpdate(HierarchicalPrefabInstance a_rHierarchicalInstanceCaller)
    {
        if (this != null)
        {
            // if the connection with the hierarchical prefab is broken
            if (HierarchicalPrefab == null)
            {
                // If the prefab is still there and has just been replaced
                if (m_rPrefabObject != null)
                {
                    // Try to grab the nested prefab data from the potential instantiator
                    NestedPrefabData rNestedPrefabData = TryGrabNestedPrefabData();

                    // Replace the current object by an instance of the new prefab
                    GameObject rNewInstance = PrefabUtility.InstantiatePrefab(NestedPrefabEditorUtility.GetPrefabGameObject(m_rPrefabObject)) as GameObject;
                    HierarchicalPrefabInstance rNewHierarchicalPrefabInstance = rNewInstance.GetComponent <HierarchicalPrefabInstance>();
                    // If nested
                    if (rNestedPrefabData != null && rNewHierarchicalPrefabInstance != null && transform.parent != null)
                    {
                        rNewHierarchicalPrefabInstance.ReloadNestedPrefabData(rNestedPrefabData);
                        // Change the parent without changing the local transform information
                        NestedPrefabUtility.ChangeParentAndKeepSameLocalTransform(rNewHierarchicalPrefabInstance.transform, transform.parent);
                    }
                    else
                    {
                        Vector3 f3LocalScaleSave = rNewInstance.transform.localScale;
                        rNewInstance.transform.parent        = transform.parent;
                        rNewInstance.transform.localPosition = transform.localPosition;
                        rNewInstance.transform.localRotation = transform.localRotation;
                        rNewInstance.transform.localScale    = f3LocalScaleSave;
                    }

                    // Auto destruction
                    Editor.DestroyImmediate(gameObject);
                }
            }
            else
            {
                // Revert to hierarchical prefab
                //RevertToHierarchicalPrefab();
                if (this == a_rHierarchicalInstanceCaller)
                {
                    // if it's the updated instance we just redeploy the hierarchy
                    DeployHierarchy();
                }
                else
                {
                    // Revert to hierarchical prefab
                    RevertToHierarchicalPrefab();
                }
            }
        }
    }
コード例 #7
0
    // Try to reinstantiate a hierarchical prefab
    public bool TryToReloadData(HierarchicalPrefabInstance a_rHierarchicalPrefabInstance)
    {
        // Try to find a prefab data corresponding to the hierarchical prefab
        NestedPrefabData rNestedPrefabData = TryGrabNestedPrefabData(a_rHierarchicalPrefabInstance.gameObject);

        if (rNestedPrefabData != null)
        {
            // Load its property modifications
            rNestedPrefabData.LoadModifications(a_rHierarchicalPrefabInstance.gameObject);

            return(true);
        }

        return(false);
    }
コード例 #8
0
    // Is a nested prefab
    public static bool IsNestedPrefab(GameObject a_rChild, GameObject a_rRoot)
    {
        HierarchicalPrefabInstance rHierarchicalPrefabInstance = a_rChild.GetComponent <HierarchicalPrefabInstance>();

        if (rHierarchicalPrefabInstance != null)
        {
            return(rHierarchicalPrefabInstance.HierarchicalPrefab != null);
        }
        else
        {
            Object rPrefabOfChild = PrefabUtility.GetPrefabObject(a_rChild);
            Object rPrefabOfRoot  = PrefabUtility.GetPrefabObject(a_rRoot);
            return(a_rChild.transform.parent != null && rPrefabOfChild != null && rPrefabOfChild != rPrefabOfRoot);
        }
    }
コード例 #9
0
 // Force the intern prefab update to avoid instance override to get in the way
 private void ForcePrefabInformationUpdate()
 {
     GameObject rHierarchicalPrefab = HierarchicalPrefab;
     if(rHierarchicalPrefab != null)
     {
         HierarchicalPrefabInstance rHierarchicalPrefabInstanceModel = rHierarchicalPrefab.GetComponent<HierarchicalPrefabInstance>();
         if(rHierarchicalPrefabInstanceModel != null)
         {
             m_iHierarchicalPrefabVersionNumber = rHierarchicalPrefabInstanceModel.m_iHierarchicalPrefabVersionNumber;
             m_rPrefabObject = rHierarchicalPrefabInstanceModel.m_rPrefabObject;
             m_rCompiledHierarchicalPrefab = rHierarchicalPrefabInstanceModel.m_rCompiledHierarchicalPrefab;
             m_bSceneInstance = true;
         }
     }
 }
コード例 #10
0
    // Trim the hierarchical prefab
    public static void TrimHierarchicalPrefab(Transform a_rTreeToTrimRoot)
    {
        // Begin by the Hierarchical prefab instance leaf
        // Go all the way down first, then climb and trim recursively
        foreach (Transform rChildTransform in a_rTreeToTrimRoot)
        {
            // Wait to be at the hierarchy trim to actualy execute the trim
            TrimHierarchicalPrefab(rChildTransform);
        }

        // If we are on a hierarchical prefab transform it
        HierarchicalPrefabInstance rHierarchicalPrefabInstance = a_rTreeToTrimRoot.GetComponent <HierarchicalPrefabInstance>();

        if (rHierarchicalPrefabInstance != null)
        {
            // Clear the hierarchy from the prefab and add instantiator to respawn them when needed
            ReplacePrefabInHierarchyByInstantiator(rHierarchicalPrefabInstance.gameObject);
        }
    }
コード例 #11
0
    // Summary : Instantiate a Prefab GameObject
    // Note : Same as the GameObject.Instantiate (You can use this method as replacement)
    // But add the capability to instantiate the compiled version of a Hierarchical Prefab
    // Return : The created instance
    public static GameObject Instantiate(GameObject a_rPrefabGameObject, Vector3 a_f3Position, Quaternion a_oRotation)
    {
        DisplayCompilationNotUpToDateWarningIfNeeded();

        // Try to get the hierarchical component of the prefab game object
        HierarchicalPrefabInstance rHierarchicalPrefabInstanceModel = a_rPrefabGameObject.GetComponent <HierarchicalPrefabInstance>();

        // If it's a hierarchical prefab
        if (rHierarchicalPrefabInstanceModel != null)
        {
            // Instantiate the compiled hierarchic prefab
            return(rHierarchicalPrefabInstanceModel.InstantiateCompiledVersion(a_f3Position, a_oRotation));
        }
        // If it's a normal prefab
        else
        {
            // Instantiate the prefab
            return(GameObject.Instantiate(a_rPrefabGameObject, a_f3Position, a_oRotation) as GameObject);
        }
    }
コード例 #12
0
    // Has prefab changed?
    private bool HasPrefabChanged()
    {
        // If the resource has changed
        GameObject rHierarchicalPrefab = HierarchicalPrefab;
        if(rHierarchicalPrefab != null)
        {
            HierarchicalPrefabInstance rHierarchicalPrefabInstanceModel = rHierarchicalPrefab.GetComponent<HierarchicalPrefabInstance>();

            if(rHierarchicalPrefabInstanceModel != null && m_iHierarchicalPrefabVersionNumber != rHierarchicalPrefabInstanceModel.m_iHierarchicalPrefabVersionNumber)
            {
                return true;
            }
        }
        else
        {
            // The resource can have been overrided
            return true;
        }

        return false;
    }
コード例 #13
0
    // Compile the hierarchical prefab
    public void Compile()
    {
        // Instantiate a copy of us
        GameObject rHierarchicalPrefabToBeCompiledGameObject = PrefabUtility.InstantiatePrefab(gameObject) as GameObject;

        // Force the hierarchy to deploy
        HierarchicalPrefabInstance rHierarchicalPrefabToBeCompiled = rHierarchicalPrefabToBeCompiledGameObject.GetComponent <HierarchicalPrefabInstance>();

        rHierarchicalPrefabToBeCompiled.DeployHierarchy();

        // Disconnect from the hierarchical prefab world
        NestedPrefabEditorUtility.DisconnectFromHierarchicalPrefab(rHierarchicalPrefabToBeCompiledGameObject);

        // Ensure the compilation directory exist
        Directory.CreateDirectory(Application.dataPath.Replace("Assets", "") + mc_oCompiledHierarchicalPrefabFolderPath);

        // Prefab object into which to save
        Object rPrefabObject;

        if (m_rCompiledHierarchicalPrefab == null)
        {
            // Ensure we have a unique save path
            string oSavingPath = mc_oCompiledHierarchicalPrefabFolderPath + "/" + rHierarchicalPrefabToBeCompiledGameObject.name + ".prefab";
            oSavingPath = AssetDatabase.GenerateUniqueAssetPath(oSavingPath);

            // Save it into a prefab
            rPrefabObject = PrefabUtility.CreateEmptyPrefab(oSavingPath);
        }
        else
        {
            rPrefabObject = PrefabUtility.GetPrefabObject(m_rCompiledHierarchicalPrefab);
        }
        GameObject rPrefabGameObject = PrefabUtility.ReplacePrefab(rHierarchicalPrefabToBeCompiledGameObject, rPrefabObject);

        // Link the instance model to the prefab
        m_rCompiledHierarchicalPrefab = rPrefabGameObject;

        // Destroy the instance
        Editor.DestroyImmediate(rHierarchicalPrefabToBeCompiledGameObject);
    }
コード例 #14
0
    // On save
    public void OnSaveModelInstanceBeforePrefabReplacement(Object a_rPrefabObject)
    {
        // Save the prefab object for recuperation (mainly to react after an other object override our prefab)
        m_rPrefabObject = a_rPrefabObject;

        // Increment version
        IncrementHierarchicalPrefabVersion();

        // Clear the scene instance flag
        m_bSceneInstance = false;

        // Conserve the compiled prefab
        GameObject rPrefabGameObject = HierarchicalPrefab;
        if(rPrefabGameObject)
        {
            HierarchicalPrefabInstance rHierarchicalPrefabInstance = rPrefabGameObject.GetComponent<HierarchicalPrefabInstance>();
            if(rHierarchicalPrefabInstance != null)
            {
                m_rCompiledHierarchicalPrefab = rHierarchicalPrefabInstance.m_rCompiledHierarchicalPrefab;
            }
        }
    }
コード例 #15
0
    // Is the instance nested (directly or not) on an other instance of the same prefab?
    private bool IsNestedInHierarchicalInstanceOfSamePrefab()
    {
        // Climb up the hierarchy and test if there is a hierarchical instance of the same prefab
        Transform rCurrentParent = transform.parent;
        while(rCurrentParent != null)
        {
            // Is the parent a hierarchical instance?
            HierarchicalPrefabInstance rParentHierarchicalPrefabInstance = rCurrentParent.GetComponent<HierarchicalPrefabInstance>();
            if(rParentHierarchicalPrefabInstance != null)
            {
                // Is it an instance of the same prefab
                if(rParentHierarchicalPrefabInstance.PrefabObject == PrefabObject)
                {
                    return true;
                }
            }

            // Climb up one level
            rCurrentParent = rCurrentParent.parent;
        }

        return false;
    }
コード例 #16
0
    // Get all selected hierarchical prefabs
    public static List <HierarchicalPrefabInstance> GetSelectedHierarchicalPrefabInstanceModels()
    {
        // The selected hierarchical prefab
        List <HierarchicalPrefabInstance> oSelectedHierarchicalPrefabInstanceModels = new List <HierarchicalPrefabInstance>();

        // loop through the selected game object
        foreach (GameObject rSelectedGameObject in Selection.gameObjects)
        {
            // Try to get the prefab game object
            GameObject rPrefabGameObject;
            if (EditorUtility.IsPersistent(rSelectedGameObject))
            {
                rPrefabGameObject = rSelectedGameObject;
            }
            else
            {
                rPrefabGameObject = PrefabUtility.GetPrefabParent(rSelectedGameObject) as GameObject;
            }
            rPrefabGameObject = PrefabUtility.FindPrefabRoot(rPrefabGameObject);
            if (rPrefabGameObject != null)
            {
                // If it's a hierarchical prefab
                HierarchicalPrefabInstance rHierarchicalPrefabInstanceModel = rPrefabGameObject.GetComponent <HierarchicalPrefabInstance>();
                if (rHierarchicalPrefabInstanceModel != null)
                {
                    // Avoid duplicate
                    if (oSelectedHierarchicalPrefabInstanceModels.Contains(rHierarchicalPrefabInstanceModel) == false)
                    {
                        oSelectedHierarchicalPrefabInstanceModels.Add(rHierarchicalPrefabInstanceModel);
                    }
                }
            }
        }

        return(oSelectedHierarchicalPrefabInstanceModels);
    }
コード例 #17
0
    // Update selection
    private bool UpdateSelection()
    {
        // Save the current selection
        ESelectionMode             eSelectionModeLast      = m_eSelectionMode;
        GameObject                 rSelectedGameObjectLast = m_rSelectedGameObject;
        HierarchicalPrefabInstance rSelectedHierarchicalPrefabInstanceLast = m_rSelectedHierarchicalPrefabInstance;

        // Update the selected game object
        m_rSelectedGameObject = Selection.activeGameObject;

        // Update the selection mode
        if (Application.isPlaying)
        {
            m_eSelectionMode      = ESelectionMode.InPlayMode;
            m_rSelectedGameObject = null;
        }
        else if (m_rSelectedGameObject == null)
        {
            m_eSelectionMode = ESelectionMode.None;
        }
        else if (EditorUtility.IsPersistent(m_rSelectedGameObject))
        {
            m_rSelectedHierarchicalPrefabInstance = m_rSelectedGameObject.GetComponent <HierarchicalPrefabInstance>();

            if (m_rSelectedHierarchicalPrefabInstance == null)
            {
                m_eSelectionMode = ESelectionMode.IsAResourceButNotAHierarchicalPrefab;
            }
            else
            {
                m_eSelectionMode = ESelectionMode.IsAHierarchicalPrefabResource;
            }
        }
        else
        {
            m_rSelectedHierarchicalPrefabInstance = m_rSelectedGameObject.GetComponent <HierarchicalPrefabInstance>();

            if (m_rSelectedHierarchicalPrefabInstance == null)
            {
                m_eSelectionMode = ESelectionMode.IsNotAHierarchicalPrefabInstance;
            }
            else
            {
                if (m_rSelectedHierarchicalPrefabInstance.HierarchicalPrefab == null)
                {
                    m_eSelectionMode = ESelectionMode.IsAHierarchicalInstancePrefabWithoutResource;
                }
                else
                {
                    m_eSelectionMode = ESelectionMode.IsAConnectedHierarchicalInstancePrefab;
                }
            }
        }

        bool bMustCompileLast = m_bMustCompile;

        m_bMustCompile = NestedPrefabEditorSettings.MustCompile;

        // Check if there was change
        if (eSelectionModeLast != m_eSelectionMode ||
            rSelectedGameObjectLast != m_rSelectedGameObject ||
            rSelectedHierarchicalPrefabInstanceLast != m_rSelectedHierarchicalPrefabInstance ||
            bMustCompileLast != m_bMustCompile)
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
コード例 #18
0
 // Is Cyclic?
 public static bool IsHierarchicalPrefabInstanceCyclic(HierarchicalPrefabInstance a_rTestedHierarchicalPrefabInstance, Object a_rPrefabToSaveInto)
 {
     return(IsHierarchicalPrefabTreeContainAnInstantiatorOf(a_rTestedHierarchicalPrefabInstance.transform, PrefabUtility.GetPrefabObject(a_rPrefabToSaveInto)));
 }
コード例 #19
0
 // Notify the other instances of update
 public static void NotifyInstancesOfHierarchicalPrefabUpdate(Object a_rHierarchicalPrefab, HierarchicalPrefabInstance a_rHierarchicalInstanceCaller)
 {
     // Loop through the instances of this prefab and notify them
     foreach (HierarchicalPrefabInstance rHierarchicalPrefabInstance in GetAllInstancesOfHierarchicalPrefab(a_rHierarchicalPrefab))
     {
         rHierarchicalPrefabInstance.OnHierarchicalPrefabUpdate(a_rHierarchicalInstanceCaller);
     }
 }
コード例 #20
0
 // Copy version number
 public void CopyVersionNumber(HierarchicalPrefabInstance a_rHierarchicalPrefabInstanceToCopy)
 {
     m_iHierarchicalPrefabVersionNumber = a_rHierarchicalPrefabInstanceToCopy.m_iHierarchicalPrefabVersionNumber;
 }
コード例 #21
0
 // Clean project button action
 private void CleanProjectButtonAction()
 {
     HierarchicalPrefabInstance.ClearAllCompiledHierarchicalPrefabs();
 }
コード例 #22
0
 // Compile All button action
 private void CompileAllButtonAction()
 {
     HierarchicalPrefabInstance.CompileAllHierarchicalPrefabs();
 }
コード例 #23
0
 // Compile Selected button action
 private void CompileSelectedButtonAction()
 {
     HierarchicalPrefabInstance.CompileSelectedHierarchicalPrefabs();
 }