¿Cómo actualizar todas las escenas en Unity con un solo clic? Automatizamos la rutina

Tanyushka es la autora del canal IT DIVA y de este artículo, adicta al café y amante de la rutina automatizada
Tanyushka es la autora del canal IT DIVA y de este artículo, adicta al café y amante de la rutina automatizada

Unity es uno de los motores de juegos más populares utilizado tanto por desarrolladores independientes para crear juegos y aplicaciones móviles, como por empresas cuyos productos utilizan tecnologías de realidad virtual y aumentada.





, , , . , .





, , .





, Unity- .





.





, 3 . , , 3D-. .





, , . 3 - .





, 10? 20? 50?





, , . - . . .





?

, ! .





. , , (, , ), , , . .





OnValidate() , . . , OnValidate(), , MonoBehaviour.





.





, . , .





, «Editor»:





Un ejemplo de una posible jerarquía para extensiones de motor

, , Unity . , "Editor" , Unity , , .





, , «Editor Window» ( «MonoBehaviour», ):





using UnityEngine;
using UnityEditor;

public class SceneUpdater : EditorWindow
{
    [MenuItem("Custom Tools/Scene Updater")]
    public static void ShowWindow()
    {
        GetWindow(typeof(SceneUpdater));
    }
    
    private void OnGUI()
    {
        if (GUILayout.Button("Update scenes"))
    				Debug.Log("Updating")
    }
}
      
      



[MenuItem("Custom Tools/Scene Updater")] . :





Nuevo elemento de menú a través del cual usaremos nuestra herramienta
,

, :





using UnityEngine;
using UnityEditor;

public class SceneUpdater : EditorWindow
{
    [MenuItem("Custom Tools/Scene Updater")]
    public static void ShowWindow()
    {
        GetWindow(typeof(SceneUpdater));
    }
    
    private void OnGUI()
    {
        if (GUILayout.Button("Update scenes"))
    				Debug.Log("Updating")
    }
}
      
      



, .





:





/// <summary>
///       
/// </summary>
/// <param name="objectName">   </param>
/// <typeparam name="T">   </typeparam>
private void AddComponentToObject<T>(string objectName) where T : Component
{
    GameObject.Find(objectName)?.gameObject.AddComponent<T>();
}
      
      



:





AddComponentToObject<BoxCollider>("Plane");
AddComponentToObject<SampleClass>("EventSystem");
      
      



, .





:





/// <summary>
///     
/// </summary>
/// <param name="objectName">   </param>
private void DestroyObjectWithName(string objectName)
{
    DestroyImmediate(GameObject.Find(objectName)?.gameObject);
}
      
      



:





DestroyObjectWithName("Sphere");
      
      



,

Transform RectTransform , , (, ):





/// <summary>
///  ,      Transform   
///      .
///      parent root     
/// </summary>
/// <param name="objectToCopyFrom"> ,      </param>
/// <param name="objectToPasteTo"> ,      </param>
/// <param name="copyPosition">    ,        </param>
/// <param name="copeRotation">    ,        </param>
/// <param name="copyScale">    ,        </param>
private static void CopyTransformPositionRotationScale(GameObject objectToCopyFrom, GameObject objectToPasteTo, 
    bool copyPosition = true, bool copeRotation = true, bool copyScale = true)
{
    var newTransform = objectToCopyFrom.GetComponent<Transform>();
    var currentTransform = objectToPasteTo.GetComponent<Transform>();
        
    if (copyPosition) currentTransform.localPosition = newTransform.localPosition;
    if (copeRotation) currentTransform.localRotation = newTransform.localRotation;
    if (copyScale) currentTransform.localScale = newTransform.localScale;
}
    
/// <summary>
///  ,      RectTransform  UI-  
///      .      (   sizeDelta)
///      parent root     
/// </summary>
/// <param name="objectToCopyFrom"> ,      </param>
/// <param name="objectToPasteTo"> ,      </param>
/// <param name="copyPosition">    ,        </param>
/// <param name="copeRotation">    ,        </param>
/// <param name="copyScale">    ,        </param>
private static void CopyRectTransformPositionRotationScale(GameObject objectToCopyFrom, GameObject objectToPasteTo,
    bool copyPosition = true, bool copeRotation = true, bool copyScale = true)
{
    var newTransform = objectToCopyFrom.GetComponent<RectTransform>();
    var currentTransform = objectToPasteTo.GetComponent<RectTransform>();
        
    if (copyPosition) currentTransform.localPosition = newTransform.localPosition;
    if (copeRotation) currentTransform.localRotation = newTransform.localRotation;
    if (copyScale) currentTransform.localScale = newTransform.localScale;
}
      
      



, , -, , :





var plane = GameObject.Find("Plane");
var cube = GameObject.Find("Cube");
CopyTransformPositionRotationScale(plane, cube, copyScale:false);
      
      



UI-

, Canvas, TextMeshPro RectTransform:





/// <summary>
///   Canvas
/// </summary>
/// <param name="canvasGameObject"> ,       </param>
/// <param name="renderMode">   </param>
/// <param name="scaleMode">    </param>
private void ChangeCanvasSettings(GameObject canvasGameObject, RenderMode renderMode, CanvasScaler.ScaleMode scaleMode)
{
    canvasGameObject.GetComponentInChildren<Canvas>().renderMode = renderMode;

    var canvasScaler = canvasGameObject.GetComponentInChildren<CanvasScaler>();
    canvasScaler.uiScaleMode = scaleMode;

    //   
    if (scaleMode == CanvasScaler.ScaleMode.ScaleWithScreenSize)
    {
        canvasScaler.referenceResolution = new Vector2(720f, 1280f);
        canvasScaler.matchWidthOrHeight = 1f;
    }
} 

/// <summary>
///    TextMeshPro
/// </summary>
/// <param name="textMeshPro">   </param>
/// <param name="fontSizeMin">    </param>
/// <param name="fontSizeMax">    </param>
/// <param name="textAlignmentOption">   </param>
private void ChangeTMPSettings(TextMeshProUGUI textMeshPro, int fontSizeMin, int fontSizeMax, TextAlignmentOptions textAlignmentOption = TextAlignmentOptions.Center)
{
    //   
    textMeshPro.font = (TMP_FontAsset) AssetDatabase.LoadAssetAtPath("Assets/TextMesh Pro/Resources/Fonts & Materials/LiberationSans SDF - Fallback.asset", typeof(TMP_FontAsset));
    textMeshPro.enableAutoSizing = true;
    textMeshPro.fontSizeMin = fontSizeMin;
    textMeshPro.fontSizeMax = fontSizeMax;
    textMeshPro.alignment = textAlignmentOption;
}

/// <summary>
///   RectTransform
/// </summary>
/// <param name="rectTransform">   </param>
/// <param name="alignment">  </param>
/// <param name="position">   3D- </param>
/// <param name="size">  </param>
private void ChangeRectTransformSettings(RectTransform rectTransform, AnchorPresets alignment, Vector3 position, Vector2 size)
{
    rectTransform.anchoredPosition3D = position;
    rectTransform.sizeDelta = size;
    rectTransform.SetAnchor(alignment);
}
      
      



, RectTransform , - Unity. Anchor Pivot. Utils:





Un ejemplo de una posible jerarquía para extensiones de clases estándar

:





RectTransformExtension.cs
using UnityEngine;

public enum AnchorPresets
{
    TopLeft,
    TopCenter,
    TopRight,

    MiddleLeft,
    MiddleCenter,
    MiddleRight,

    BottomLeft,
    BottomCenter,
    BottomRight,

    VertStretchLeft,
    VertStretchRight,
    VertStretchCenter,

    HorStretchTop,
    HorStretchMiddle,
    HorStretchBottom,

    StretchAll
}

public enum PivotPresets
{
    TopLeft,
    TopCenter,
    TopRight,

    MiddleLeft,
    MiddleCenter,
    MiddleRight,

    BottomLeft,
    BottomCenter,
    BottomRight,
}

/// <summary>
///     RectTransform
/// </summary>
public static class RectTransformExtension
{
    /// <summary>
    ///  
    /// </summary>
    /// <param name="source"> ,     </param>
    /// <param name="align">   </param>
    /// <param name="offsetX">    X </param>
    /// <param name="offsetY">    Y </param>
    public static void SetAnchor(this RectTransform source, AnchorPresets align, int offsetX = 0, int offsetY = 0)
    {
        source.anchoredPosition = new Vector3(offsetX, offsetY, 0);
        switch (align)
        {
            case (AnchorPresets.TopLeft):
            {
                source.anchorMin = new Vector2(0, 1);
                source.anchorMax = new Vector2(0, 1);
                break;
            }
            case (AnchorPresets.TopCenter):
            {
                source.anchorMin = new Vector2(0.5f, 1);
                source.anchorMax = new Vector2(0.5f, 1);
                break;
            }
            case (AnchorPresets.TopRight):
            {
                source.anchorMin = new Vector2(1, 1);
                source.anchorMax = new Vector2(1, 1);
                break;
            }

            case (AnchorPresets.MiddleLeft):
            {
                source.anchorMin = new Vector2(0, 0.5f);
                source.anchorMax = new Vector2(0, 0.5f);
                break;
            }
            case (AnchorPresets.MiddleCenter):
            {
                source.anchorMin = new Vector2(0.5f, 0.5f);
                source.anchorMax = new Vector2(0.5f, 0.5f);
                break;
            }
            case (AnchorPresets.MiddleRight):
            {
                source.anchorMin = new Vector2(1, 0.5f);
                source.anchorMax = new Vector2(1, 0.5f);
                break;
            }

            case (AnchorPresets.BottomLeft):
            {
                source.anchorMin = new Vector2(0, 0);
                source.anchorMax = new Vector2(0, 0);
                break;
            }
            case (AnchorPresets.BottomCenter):
            {
                source.anchorMin = new Vector2(0.5f, 0);
                source.anchorMax = new Vector2(0.5f, 0);
                break;
            }
            case (AnchorPresets.BottomRight):
            {
                source.anchorMin = new Vector2(1, 0);
                source.anchorMax = new Vector2(1, 0);
                break;
            }

            case (AnchorPresets.HorStretchTop):
            {
                source.anchorMin = new Vector2(0, 1);
                source.anchorMax = new Vector2(1, 1);
                break;
            }
            case (AnchorPresets.HorStretchMiddle):
            {
                source.anchorMin = new Vector2(0, 0.5f);
                source.anchorMax = new Vector2(1, 0.5f);
                break;
            }
            case (AnchorPresets.HorStretchBottom):
            {
                source.anchorMin = new Vector2(0, 0);
                source.anchorMax = new Vector2(1, 0);
                break;
            }

            case (AnchorPresets.VertStretchLeft):
            {
                source.anchorMin = new Vector2(0, 0);
                source.anchorMax = new Vector2(0, 1);
                break;
            }
            case (AnchorPresets.VertStretchCenter):
            {
                source.anchorMin = new Vector2(0.5f, 0);
                source.anchorMax = new Vector2(0.5f, 1);
                break;
            }
            case (AnchorPresets.VertStretchRight):
            {
                source.anchorMin = new Vector2(1, 0);
                source.anchorMax = new Vector2(1, 1);
                break;
            }

            case (AnchorPresets.StretchAll):
            {
                source.anchorMin = new Vector2(0, 0);
                source.anchorMax = new Vector2(1, 1);
                break;
            }
        }
    }

    /// <summary>
    ///  pivot
    /// </summary>
    /// <param name="source"> ,     </param>
    /// <param name="preset">   </param>
    public static void SetPivot(this RectTransform source, PivotPresets preset)
    {
        switch (preset)
        {
            case (PivotPresets.TopLeft):
            {
                source.pivot = new Vector2(0, 1);
                break;
            }
            case (PivotPresets.TopCenter):
            {
                source.pivot = new Vector2(0.5f, 1);
                break;
            }
            case (PivotPresets.TopRight):
            {
                source.pivot = new Vector2(1, 1);
                break;
            }

            case (PivotPresets.MiddleLeft):
            {
                source.pivot = new Vector2(0, 0.5f);
                break;
            }
            case (PivotPresets.MiddleCenter):
            {
                source.pivot = new Vector2(0.5f, 0.5f);
                break;
            }
            case (PivotPresets.MiddleRight):
            {
                source.pivot = new Vector2(1, 0.5f);
                break;
            }

            case (PivotPresets.BottomLeft):
            {
                source.pivot = new Vector2(0, 0);
                break;
            }
            case (PivotPresets.BottomCenter):
            {
                source.pivot = new Vector2(0.5f, 0);
                break;
            }
            case (PivotPresets.BottomRight):
            {
                source.pivot = new Vector2(1, 0);
                break;
            }
        }
    }
}
      
      



:





//    Canvas
var canvas = GameObject.Find("Canvas");
ChangeCanvasSettings(canvas, RenderMode.ScreenSpaceOverlay, CanvasScaler.ScaleMode.ScaleWithScreenSize);

//   
var tmp = canvas.GetComponentInChildren<TextMeshProUGUI>();
ChangeTMPSettings(tmp, 36, 72, TextAlignmentOptions.BottomRight);

//  RectTransform
ChangeRectTransformSettings(tmp.GetComponent<RectTransform>(), AnchorPresets.MiddleCenter, Vector3.zero, new Vector2(100f, 20f));
      
      



, Transform ( ):





TransformExtension.cs
using UnityEngine;

/// <summary>
///     Transform
/// </summary>
public static class TransformExtension
{
    /// <summary>
    ///       
    /// </summary>
    /// <param name="parent">   </param>
    /// <param name="childName">     </param>
    /// <returns> null -    ,
    ///           Transform ,   
    /// </returns>
    public static Transform FindChildWithName(this Transform parent, string childName)
    {
        foreach (Transform child in parent)
        {
            if (child.name == childName)
                return child;

            var result = child.FindChildWithName(childName);
            if (result)
                return result;
        }

        return null;
    }
}
      
      



, OnClick() - :





/// <summary>
///      (    )
/// </summary>
/// <param name="uiButton">  </param>
/// <param name="action">   </param>
private static void AddPersistentListenerToButton(Button uiButton, UnityAction action)
{
    try
    {
        // ,     
        if (uiButton.onClick.GetPersistentTarget(0) == null)
            UnityEventTools.RegisterPersistentListener(uiButton.onClick, 0, action);
    }
    catch (ArgumentException)
    {
        UnityEventTools.AddPersistentListener(uiButton.onClick, action);
    }
}
      
      



, :





//    
AddPersistentListenerToButton(canvas.GetComponentInChildren<Button>(), FindObjectOfType<SampleClass>().QuitApp);
      
      



:





El resultado de AddPersistentListener
AddPersistentListener

, , , :





/// <summary>
///      
/// </summary>
/// <param name="gameObject">  </param>
/// <param name="layerName">   </param>
private void ChangeObjectLayer(GameObject gameObject, string layerName)
{
    gameObject.layer = LayerMask.NameToLayer(layerName);
}

/// <summary>
///             
/// </summary>
/// <param name="prefabPath">    </param>
/// <param name="parentGameObject">   </param>
/// <param name="hierarchyIndex">      </param>
private void InstantiateNewGameObject(string prefabPath, GameObject parentGameObject, int hierarchyIndex = 0)
{
    if (parentGameObject)
    {
        var newGameObject = Instantiate((GameObject) AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)), parentGameObject.transform);    
        
        //        
        newGameObject.transform.SetSiblingIndex(hierarchyIndex);
    }
    else
        Instantiate((GameObject) AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)));
}
      
      



, :





//     
var cube = GameObject.Find("Cube");
cube.tag = "Player";
ChangeObjectLayer(cube, "MainLayer");
               
//            
InstantiateNewGameObject("Assets/Prefabs/Capsule.prefab", cube, 1);
      
      



, :





, - , -- , File ->Build Settings:





/// <summary>
///      Build Settings
/// </summary>
/// <param name="onSceneLoaded">     </param>
private void RunSceneUpdateCycle(UnityAction onSceneLoaded)
{
    //       
    var scenes = EditorBuildSettings.scenes.Select(scene => scene.path).ToList();
    foreach (var scene in scenes)
    {
        //  
        EditorSceneManager.OpenScene(scene);
            
        //   ,      
        EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
            
        //  
        onSceneLoaded?.Invoke();
            
        // 
        EditorApplication.SaveScene();
            
        Debug.Log($"UPDATED {scene}");
    }
}
      
      



, :





SceneUpdater.cs
#if UNITY_EDITOR
using System;
using UnityEditor.Events;
using TMPro;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using UnityEditor;
using UnityEditor.SceneManagement;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
///    ,    BuildSettings (  )
/// </summary>
public class SceneUpdater : EditorWindow
{
    [MenuItem("Custom Tools/Scene Updater")]
    public static void ShowWindow()
    {
        GetWindow(typeof(SceneUpdater));
    }

    private void OnGUI()
    {
        //  
        if (GUILayout.Button("Update scenes"))
            RunSceneUpdateCycle((() =>
            {
                //     
                var cube = GameObject.Find("Cube");
                cube.tag = "Player";
                ChangeObjectLayer(cube, "MainLayer");
                
                //       
                AddComponentToObject<BoxCollider>("Plane");
                
                //     
                DestroyObjectWithName("Sphere");
                
                //            
                InstantiateNewGameObject("Assets/Prefabs/Capsule.prefab", cube, 1);

                //    Canvas
                var canvas = GameObject.Find("Canvas");
                ChangeCanvasSettings(canvas, RenderMode.ScreenSpaceOverlay, CanvasScaler.ScaleMode.ScaleWithScreenSize);

                //   
                var tmp = canvas.GetComponentInChildren<TextMeshProUGUI>();
                ChangeTMPSettings(tmp, 36, 72, TextAlignmentOptions.BottomRight);

                //  RectTransform
                ChangeRectTransformSettings(tmp.GetComponent<RectTransform>(), AnchorPresets.MiddleCenter, Vector3.zero, new Vector2(100f, 20f));
                
                //    
                AddPersistentListenerToButton(canvas.GetComponentInChildren<Button>(), FindObjectOfType<SampleClass>().QuitApp);

                //   
                CopyTransformPositionRotationScale(GameObject.Find("Plane"), cube, copyScale:false);
            }));
    }

    /// <summary>
    ///      Build Settings
    /// </summary>
    /// <param name="onSceneLoaded">     </param>
    private void RunSceneUpdateCycle(UnityAction onSceneLoaded)
    {
        //       
        var scenes = EditorBuildSettings.scenes.Select(scene => scene.path).ToList();
        foreach (var scene in scenes)
        {
            //  
            EditorSceneManager.OpenScene(scene);
            
            //   ,      
            EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
            
            //  
            onSceneLoaded?.Invoke();
            
            // 
            EditorApplication.SaveScene();
            
            Debug.Log($"UPDATED {scene}");
        }
    }

    /// <summary>
    ///      (    )
    /// </summary>
    /// <param name="uiButton">  </param>
    /// <param name="action">   </param>
    private static void AddPersistentListenerToButton(Button uiButton, UnityAction action)
    {
        try
        {
            // ,     
            if (uiButton.onClick.GetPersistentTarget(0) == null)
                UnityEventTools.RegisterPersistentListener(uiButton.onClick, 0, action);
        }
        catch (ArgumentException)
        {
            UnityEventTools.AddPersistentListener(uiButton.onClick, action);
        }
    }

    /// <summary>
    ///   RectTransform
    /// </summary>
    /// <param name="rectTransform">   </param>
    /// <param name="alignment">  </param>
    /// <param name="position">   3D- </param>
    /// <param name="size">  </param>
    private void ChangeRectTransformSettings(RectTransform rectTransform, AnchorPresets alignment, Vector3 position, Vector2 size)
    {
        rectTransform.anchoredPosition3D = position;
        rectTransform.sizeDelta = size;
        rectTransform.SetAnchor(alignment);
    }

    /// <summary>
    ///    TextMeshPro
    /// </summary>
    /// <param name="textMeshPro">   </param>
    /// <param name="fontSizeMin">    </param>
    /// <param name="fontSizeMax">    </param>
    /// <param name="textAlignmentOption">   </param>
    private void ChangeTMPSettings(TextMeshProUGUI textMeshPro, int fontSizeMin, int fontSizeMax, TextAlignmentOptions textAlignmentOption = TextAlignmentOptions.Center)
    {
        //   
        textMeshPro.font = (TMP_FontAsset) AssetDatabase.LoadAssetAtPath("Assets/TextMesh Pro/Resources/Fonts & Materials/LiberationSans SDF - Fallback.asset", typeof(TMP_FontAsset));
        textMeshPro.enableAutoSizing = true;
        textMeshPro.fontSizeMin = fontSizeMin;
        textMeshPro.fontSizeMax = fontSizeMax;
        textMeshPro.alignment = textAlignmentOption;
    }

    /// <summary>
    ///   Canvas
    /// </summary>
    /// <param name="canvasGameObject"> ,       </param>
    /// <param name="renderMode">   </param>
    /// <param name="scaleMode">    </param>
    private void ChangeCanvasSettings(GameObject canvasGameObject, RenderMode renderMode, CanvasScaler.ScaleMode scaleMode)
    {
        canvasGameObject.GetComponentInChildren<Canvas>().renderMode = renderMode;

        var canvasScaler = canvasGameObject.GetComponentInChildren<CanvasScaler>();
        canvasScaler.uiScaleMode = scaleMode;

        //   
        if (scaleMode == CanvasScaler.ScaleMode.ScaleWithScreenSize)
        {
            canvasScaler.referenceResolution = new Vector2(720f, 1280f);
            canvasScaler.matchWidthOrHeight = 1f;
        }
    } 
    
    /// <summary>
    ///     
    /// </summary>
    /// <param name="parentGameObject">   </param>
    /// <returns>    </returns>
    private static List<GameObject> GetAllChildren(GameObject parentGameObject)
    {
        var children = new List<GameObject>();
        
        for (int i = 0; i< parentGameObject.transform.childCount; i++)
            children.Add(parentGameObject.transform.GetChild(i).gameObject);
        
        return children;
    }

    /// <summary>
    ///  ,      Transform   
    ///      .
    ///      parent root     
    /// </summary>
    /// <param name="objectToCopyFrom"> ,      </param>
    /// <param name="objectToPasteTo"> ,      </param>
    /// <param name="copyPosition">    ,        </param>
    /// <param name="copyRotation">    ,        </param>
    /// <param name="copyScale">    ,        </param>
    private static void CopyTransformPositionRotationScale(GameObject objectToCopyFrom, GameObject objectToPasteTo, 
        bool copyPosition = true, bool copyRotation = true, bool copyScale = true)
    {
        var newTransform = objectToCopyFrom.GetComponent<Transform>();
        var currentTransform = objectToPasteTo.GetComponent<Transform>();
        
        if (copyPosition) currentTransform.localPosition = newTransform.localPosition;
        if (copyRotation) currentTransform.localRotation = newTransform.localRotation;
        if (copyScale) currentTransform.localScale = newTransform.localScale;
    }
    
    /// <summary>
    ///  ,      RectTransform  UI-  
    ///      .      (   sizeDelta)
    ///      parent root     
    /// </summary>
    /// <param name="objectToCopyFrom"> ,      </param>
    /// <param name="objectToPasteTo"> ,      </param>
    /// <param name="copyPosition">    ,        </param>
    /// <param name="copyRotation">    ,        </param>
    /// <param name="copyScale">    ,        </param>
    private static void CopyRectTransformPositionRotationScale(GameObject objectToCopyFrom, GameObject objectToPasteTo,
        bool copyPosition = true, bool copyRotation = true, bool copyScale = true)
    {
        var newTransform = objectToCopyFrom.GetComponent<RectTransform>();
        var currentTransform = objectToPasteTo.GetComponent<RectTransform>();
        
        if (copyPosition) currentTransform.localPosition = newTransform.localPosition;
        if (copyRotation) currentTransform.localRotation = newTransform.localRotation;
        if (copyScale) currentTransform.localScale = newTransform.localScale;
    }

    /// <summary>
    ///     
    /// </summary>
    /// <param name="objectName">   </param>
    private void DestroyObjectWithName(string objectName)
    {
        DestroyImmediate(GameObject.Find(objectName)?.gameObject);
    }

    /// <summary>
    ///       
    /// </summary>
    /// <param name="objectName">   </param>
    /// <typeparam name="T">   </typeparam>
    private void AddComponentToObject<T>(string objectName) where T : Component
    {
        GameObject.Find(objectName)?.gameObject.AddComponent<T>();
    }

    /// <summary>
    ///      
    /// </summary>
    /// <param name="gameObject">  </param>
    /// <param name="layerName">   </param>
    private void ChangeObjectLayer(GameObject gameObject, string layerName)
    {
        gameObject.layer = LayerMask.NameToLayer(layerName);
    }

    /// <summary>
    ///             
    /// </summary>
    /// <param name="prefabPath">    </param>
    /// <param name="parentGameObject">   </param>
    /// <param name="hierarchyIndex">      </param>
    private void InstantiateNewGameObject(string prefabPath, GameObject parentGameObject, int hierarchyIndex = 0)
    {
        if (parentGameObject)
        {
            var newGameObject = Instantiate((GameObject) AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)), parentGameObject.transform);
            
            //        
            newGameObject.transform.SetSiblingIndex(hierarchyIndex);
        }
        else
            Instantiate((GameObject) AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)));
    }
}
#endif
      
      



, , :





Botón mágico

, , : , , Fuse/IClone/DAZ , Build Pipeline, - .





, (.. RunSceneUpdateCycle).





GitHub.





, , IT,    YouTube- IT DIVA. , GitHub, , , , ..





!








All Articles