Пример #1
0
        private static void AddVariation(LE_Object p_obj, EVariationType p_variationType, string p_variationName)
        {
            switch (p_variationType)
            {
            case EVariationType.REPLACE_MATERIALS:
            {
                List <LE_ObjectVariationMaterial> variations = new List <LE_ObjectVariationMaterial>(p_obj.VariationsMaterial);
                variations.Add(new LE_ObjectVariationMaterial(p_variationName));
                p_obj.VariationsMaterial = variations.ToArray();
                break;
            }

            case EVariationType.ACTIVE_DEACTIVATE_OBJECTS:
            {
                List <LE_ObjectVariationActivateDeactivate> variations = new List <LE_ObjectVariationActivateDeactivate>(p_obj.VariationsActivateDeactivate);
                variations.Add(new LE_ObjectVariationActivateDeactivate(p_variationName));
                p_obj.VariationsActivateDeactivate = variations.ToArray();
                break;
            }

            default:
                Debug.LogError("LE_ObjectInspector: AddVariation: " + p_variationType + " is unknown!");
                return;
            }
        }
Пример #2
0
        private void DrawVariationMaterial(LE_Object p_obj, LE_ObjectVariationMaterial p_variation)
        {
            if (p_variation.LoadNFixReferences(p_obj))
            {
                EditorUtility.SetDirty(p_obj);
            }
            p_variation.Name = EditorGUILayout.TextField(m_contentVariationName, p_variation.Name);
            if (p_variation.Renderers.Length > 0)
            {
                for (int rI = 0; rI < p_variation.Renderers.Length && rI < p_variation.RendererMaterials.Length; rI++)
                {
                    Renderer renderer = p_variation.Renderers[rI];
                    EditorGUILayout.LabelField(renderer.name, EditorStyles.boldLabel);

                    EditorGUI.indentLevel++;
                    LE_ObjectVariationMaterial.Materials materials = p_variation.RendererMaterials[rI];
                    for (int mI = 0; mI < materials.m_materials.Length; mI++)
                    {
                        materials.m_materials[mI] = (Material)EditorGUILayout.ObjectField(materials.m_materials[mI], typeof(Material), false);
                    }
                    EditorGUI.indentLevel--;
                }
            }
            else
            {
                EditorGUILayout.HelpBox("This object cannot have material variations, because it has no renderers with materials!", MessageType.Error);
            }
        }
Пример #3
0
        private static bool SnapToTerrain_MoveAxisCheck(LE_Object p_obj)
        {
            bool isChanged = false;

            if ((p_obj.SnapType == LE_Object.ESnapType.SNAP_TO_TERRAIN || p_obj.SnapType == LE_Object.ESnapType.SNAP_TO_2D_GRID_AND_TERRAIN) &&
                p_obj.IsMovable && p_obj.IsMovableOnY)
            {
                bool userDecision = EditorUtility.DisplayDialog(
                    "Conflict (Terrain Snap -!- Y Translation)",
                    "Cannot move on y axis with 'Snap To Terrain' enabled. " +
                    "Movement would be ignored, because object would snap back to terrain. Do you want to:\n" +
                    "A: disable y translation\n" +
                    "B: disable terrain snapping",
                    "A: No Y Move Axis",
                    "B: No Snap");
                if (userDecision)
                {
                    // user wants 'No Y Move Axis'
                    p_obj.IsMovableOnY = false;
                    EditorUtility.DisplayDialog("Conflict Solved", "Y move axis was disabled!", "ok");
                }
                else
                {
                    // user wants 'No Snap'
                    p_obj.SnapType = LE_Object.ESnapType.SNAP_DISABLED;
                    EditorUtility.DisplayDialog("Conflict Solved", "'Snap To Terrain' was disabled!", "ok");
                }
                isChanged = true;
            }
            return(isChanged);
        }
Пример #4
0
 private static void InitDefaultVariation(LE_Object p_obj, EVariationType p_variationType)
 {
     p_obj.VariationsDefaultIndex       = 0;
     p_obj.VariationsMaterial           = new LE_ObjectVariationMaterial[0];
     p_obj.VariationsActivateDeactivate = new LE_ObjectVariationActivateDeactivate[0];
     if (p_variationType != EVariationType.NONE)
     {
         AddVariation(p_obj, p_variationType, "Default");
     }
 }
Пример #5
0
 private static EVariationType GetVariationType(LE_Object p_obj)
 {
     if (p_obj.Variations.Length > 0)
     {
         if (p_obj.Variations[0] is LE_ObjectVariationMaterial)
         {
             return(EVariationType.REPLACE_MATERIALS);
         }
         if (p_obj.Variations[0] is LE_ObjectVariationActivateDeactivate)
         {
             return(EVariationType.ACTIVE_DEACTIVATE_OBJECTS);
         }
     }
     return(EVariationType.NONE);
 }
        public override void Apply(LE_Object p_object)
        {
            if (m_objs == null || m_objIsActivateStates == null || m_objs.Length != m_objIsActivateStates.Length)
            {
                Debug.LogWarning("LE_ObjectVariationActivateDeactivate: Apply: the 'Objs' array must be of same length as the 'ObjIsActivateStates' array! The active state of the game object at index i will be overwritten the 'ObjIsActivateStates' at index i!");
            }

            for (int i = 0; i < m_objs.Length && i < m_objIsActivateStates.Length; i++)
            {
                GameObject obj = m_objs[i];
                if (obj != null)
                {
                    obj.SetActive(m_objIsActivateStates[i]);
                }
            }
        }
Пример #7
0
 public ObjectData(string p_error)
 {
     if (p_error != null)
     {
         m_loadResult            = EResult.ERROR;
         m_instance              = null;
         m_streamedLevelObjectID = -1;
         m_error = p_error;
     }
     else
     {
         m_loadResult            = EResult.ERROR;
         m_instance              = null;
         m_streamedLevelObjectID = -1;
         m_error = "Internal Error (error message is null)";
         Debug.LogError("ObjectData: p_error is null!");
     }
 }
Пример #8
0
 public ObjectData(int p_streamedLevelObjectID)
 {
     if (p_streamedLevelObjectID != -1)
     {
         m_loadResult            = EResult.STREAMED;
         m_instance              = null;
         m_streamedLevelObjectID = p_streamedLevelObjectID;
         m_error = null;
     }
     else
     {
         m_loadResult            = EResult.ERROR;
         m_instance              = null;
         m_streamedLevelObjectID = -1;
         m_error = "Internal Error (streamed level object ID is -1)";
         Debug.LogError("ObjectData: p_streamedLevelObjectID is -1!");
     }
 }
Пример #9
0
 public ObjectData(LE_Object p_instance)
 {
     if (p_instance != null)
     {
         m_loadResult            = EResult.INSTANCE;
         m_instance              = p_instance;
         m_streamedLevelObjectID = -1;
         m_error = null;
     }
     else
     {
         m_loadResult            = EResult.ERROR;
         m_instance              = null;
         m_streamedLevelObjectID = -1;
         m_error = "Internal Error (instance is null)";
         Debug.LogError("ObjectData: p_instance is null!");
     }
 }
Пример #10
0
 private void DrawVariationActivateDeactivate(LE_Object p_obj, LE_ObjectVariationActivateDeactivate p_variation)
 {
     if (p_variation.LoadNFixReferences(p_obj))
     {
         EditorUtility.SetDirty(p_obj);
     }
     p_variation.Name = EditorGUILayout.TextField(m_contentVariationName, p_variation.Name);
     if (p_variation.Objs.Length > 0)
     {
         for (int i = 0; i < p_variation.Objs.Length && i < p_variation.ObjIsActivateStates.Length; i++)
         {
             GameObject obj = p_variation.Objs[i];
             p_variation.ObjIsActivateStates[i] = EditorGUILayout.ToggleLeft(obj.name, p_variation.ObjIsActivateStates[i], EditorStyles.boldLabel);
         }
     }
     else
     {
         EditorGUILayout.HelpBox("This object cannot have activate/deactivate sub object variations, because it has no sub objects!", MessageType.Error);
     }
 }
Пример #11
0
        private static bool SnapToTerrain_RotationAxisCheck(LE_Object p_obj)
        {
            bool isChanged = false;

            if ((p_obj.SnapType == LE_Object.ESnapType.SNAP_TO_TERRAIN || p_obj.SnapType == LE_Object.ESnapType.SNAP_TO_2D_GRID_AND_TERRAIN) &&
                p_obj.IsPlacementRotationByNormal && p_obj.IsRotatable && (p_obj.IsRotatableAroundX || p_obj.IsRotatableAroundZ))
            {
                int userDecision = EditorUtility.DisplayDialogComplex(
                    "Conflict (Terrain Snap -!- X/Z Rotation)",
                    "Cannot rotate around x/z axis with 'Snap To Terrain' and 'Normal Oriented Placement' enabled. " +
                    "Custom rotation would be overwritten every time the terrain is changed (even if the " +
                    "change does not affect this object). Do you want to:\n" +
                    "A: disable x/z rotation\n" +
                    "B: disable terrain snapping\n" +
                    "C: disable normal oriented placement",
                    "A: Snap + Y Rot.",
                    "B: No Snap",
                    "C: No Oriented Placement");
                if (userDecision == 0)
                {
                    // user wants 'Snap + Y Rot.'
                    p_obj.IsRotatableAroundX = false;
                    p_obj.IsRotatableAroundZ = false;
                    EditorUtility.DisplayDialog("Conflict Solved", "X/Z Rotation was disabled!", "ok");
                }
                else if (userDecision == 1)
                {
                    // user wants 'No Snap'
                    p_obj.SnapType = LE_Object.ESnapType.SNAP_DISABLED;
                    EditorUtility.DisplayDialog("Conflict Solved", "'Snap To Terrain' was disabled!", "ok");
                }
                else
                {
                    // user wants 'No Oriented Placement'
                    p_obj.IsPlacementRotationByNormal = false;
                    EditorUtility.DisplayDialog("Conflict Solved", "'Normal Oriented Placement' was disabled!", "ok");
                }
                isChanged = true;
            }
            return(isChanged);
        }
        public bool LoadNFixReferences(LE_Object p_object)
        {
            bool isChanged = false;

            Transform[] currTransforms = p_object.GetComponentsInChildren <Transform>(true);

            // check for nullpointers
            for (int i = m_objs.Length - 1; i >= 0; i--)
            {
                if (m_objs[i] == null)
                {
                    RemoveObjectAt(i);
                    isChanged = true;
                }
            }

            // check if renderers where removed
            for (int i = m_objs.Length - 1; i >= 0; i--)
            {
                if (System.Array.IndexOf(currTransforms, m_objs[i].transform) < 0)
                {
                    RemoveObjectAt(i);
                    isChanged = true;
                }
            }

            // check if renderers added
            for (int i = 0; i < currTransforms.Length; i++)
            {
                if (currTransforms[i] != p_object.transform &&                              // don't add self
                    System.Array.IndexOf(m_objs, currTransforms[i].gameObject) < 0 &&
                    currTransforms[i].GetComponentInParent <LE_ObjectEditHandle>() == null) // don't select edit handles
                {
                    AddObject(currTransforms[i].gameObject);
                    isChanged = true;
                }
            }

            return(isChanged);
        }
Пример #13
0
        public bool LoadNFixReferences(LE_Object p_object)
        {
            bool isChanged = false;

            Renderer[] currRenderers = p_object.GetComponentsInChildren <Renderer>(true);

            // check for nullpointers
            for (int i = m_renderers.Length - 1; i >= 0; i--)
            {
                if (m_renderers[i] == null)
                {
                    RemoveRendererAt(i);
                    isChanged = true;
                }
            }

            // check if renderers where removed
            for (int i = m_renderers.Length - 1; i >= 0; i--)
            {
                if (System.Array.IndexOf(currRenderers, m_renderers[i]) < 0)
                {
                    RemoveRendererAt(i);
                    isChanged = true;
                }
            }

            // check if renderers added
            for (int i = 0; i < currRenderers.Length; i++)
            {
                if (System.Array.IndexOf(m_renderers, currRenderers[i]) < 0 &&
                    currRenderers[i].GetComponentInParent <LE_ObjectEditHandle>() == null)                // don't select edit handles
                {
                    AddRenderer(currRenderers[i]);
                    isChanged = true;
                }
            }

            return(isChanged);
        }
Пример #14
0
 private static void Variation_ChangeTypeCheck(LE_Object p_obj, EVariationType p_variationType, EVariationType p_newVariationType)
 {
     if (p_variationType != p_newVariationType)
     {
         if (p_obj.Variations.Length > 0)
         {
             bool userDecision = EditorUtility.DisplayDialog(
                 "Change Variation Type",
                 "All variation data will be lost if you change the variation type.",
                 "Continue (clear current data)",
                 "Cancel");
             if (userDecision)
             {
                 InitDefaultVariation(p_obj, p_newVariationType);
             }
         }
         else
         {
             InitDefaultVariation(p_obj, p_newVariationType);
         }
     }
 }
Пример #15
0
        public override void Apply(LE_Object p_object)
        {
            if (m_renderers == null || m_rendererMaterials == null || m_renderers.Length != m_rendererMaterials.Length)
            {
                Debug.LogWarning("LE_ObjectVariationMaterial: Apply: the 'Renderers' array must be of same length as the 'RendererMaterials' array! The materials of the renderer at index i will be overwritten the 'RendererMaterials' at index i!");
            }

            // hide selection if there is any
            bool isSelected = p_object.IsSelected;

            if (isSelected)
            {
                p_object.IsSelected = false;
                // selection state would be applied at the end of the frame, but we need it right now
                p_object.ApplySelectionState();
            }

            // apply material changes
            for (int i = 0; i < m_renderers.Length && i < m_rendererMaterials.Length; i++)
            {
                Renderer  renderer  = m_renderers[i];
                Materials materials = m_rendererMaterials[i];
                if (renderer != null && materials != null && materials.m_materials != null)
                {
                    renderer.materials = materials.m_materials;
                }
            }

            // restore selection if there was any
            if (isSelected)
            {
                p_object.IsSelected = true;
                // selection state would be applied at the end of the frame, but we need it right now
                p_object.ApplySelectionState();
            }
        }
Пример #16
0
 /// <summary>
 /// Apply this variation to the object passed as parameter.
 /// Called when the user selects a variation.
 /// </summary>
 public abstract void Apply(LE_Object p_object);
Пример #17
0
        public override void OnInspectorGUI()
        {
            bool isChanged = false;

            serializedObject.Update();
            LE_Object obj = (LE_Object)target;

            Texture2D icon = (Texture2D)Resources.Load(obj.IconPath);

            if (icon != null)
            {
                EditorGUILayout.BeginHorizontal();
                GUILayout.Box(icon, GUILayout.Width(64), GUILayout.Height(64));
                EditorGUILayout.BeginVertical();
                GUILayout.Label(m_contentIconPath);
                obj.IconPath = EditorGUILayout.TextField(obj.IconPath);
                EditorGUILayout.EndVertical();
                EditorGUILayout.EndHorizontal();
            }
            else
            {
                obj.IconPath = EditorGUILayout.TextField(m_contentIconPath, obj.IconPath);
                EditorGUILayout.HelpBox("No icon found for resource path '" + obj.IconPath + "'!", MessageType.Error);
            }

            obj.MaxInstancesInLevel = EditorGUILayout.IntField(m_contentMaxInstancesInLevel, obj.MaxInstancesInLevel);

            EditorGUILayout.BeginHorizontal();
            obj.IsWithColorProperty = EditorGUILayout.ToggleLeft(m_contentIsWithColorProperty, obj.IsWithColorProperty);
            if (obj.IsWithColorProperty)
            {
                Color newColor = EditorGUILayout.ColorField(obj.ColorProperty);
                if (newColor != obj.ColorProperty)
                {
                    obj.ColorProperty = newColor;
                }
            }
            EditorGUILayout.EndHorizontal();

            string translationSummaryExtra = obj.IsSmartMove?"smart,":"";
            string translationSummary      = GetTransformationHandleSummary("Translation", "movable", translationSummaryExtra, obj.IsMovable, obj.IsMovableOnX, obj.IsMovableOnY, obj.IsMovableOnZ);

            s_isFoldoutTranslation = EditorGUILayout.Foldout(s_isFoldoutTranslation, translationSummary);
            if (s_isFoldoutTranslation)
            {
                obj.IsSmartMove = EditorGUILayout.ToggleLeft(m_contentIsSmartMove, obj.IsSmartMove);
                obj.IsMovable   = EditorGUILayout.ToggleLeft(m_contentIsMovable, obj.IsMovable);
                if (obj.IsMovable)
                {
                    EditorGUI.indentLevel++;
                    obj.IsMovableOnX = EditorGUILayout.ToggleLeft(m_contentIsMovableOnX, obj.IsMovableOnX);
                    obj.IsMovableOnY = EditorGUILayout.ToggleLeft(m_contentIsMovableOnY, obj.IsMovableOnY);
                    obj.IsMovableOnZ = EditorGUILayout.ToggleLeft(m_contentIsMovableOnZ, obj.IsMovableOnZ);
                    EditorGUI.indentLevel--;
                }
            }

            string rotationSummaryExtra = obj.IsPlacementRotationByNormal?"normal,":"";

            if (obj.RotationRndEulerX > 0f && !obj.IsPlacementRotationByNormal)
            {
                rotationSummaryExtra += "rndX[" + (-0.5f * obj.RotationRndEulerX) + "," + (0.5f * obj.RotationRndEulerX) + "],";
            }
            if (obj.RotationRndEulerY > 0f)
            {
                rotationSummaryExtra += "rndY[" + (-0.5f * obj.RotationRndEulerY) + "," + (0.5f * obj.RotationRndEulerY) + "],";
            }
            if (obj.RotationRndEulerZ > 0f && !obj.IsPlacementRotationByNormal)
            {
                rotationSummaryExtra += "rndZ[" + (-0.5f * obj.RotationRndEulerZ) + "," + (0.5f * obj.RotationRndEulerZ) + "],";
            }
            string rotationSummary = GetTransformationHandleSummary("Rotation", "rotatable", rotationSummaryExtra, obj.IsRotatable, obj.IsRotatableAroundX, obj.IsRotatableAroundY, obj.IsRotatableAroundZ);

            s_isFoldoutRotation = EditorGUILayout.Foldout(s_isFoldoutRotation, rotationSummary);
            if (s_isFoldoutRotation)
            {
                GUI.enabled = !obj.IsPlacementRotationByNormal;
                if (GUI.enabled)
                {
                    obj.RotationRndEulerX = Mathf.Min(360f, EditorGUILayout.FloatField(m_contentRotationRndEulerX, obj.RotationRndEulerX));
                }
                else
                {
                    EditorGUILayout.TextField(m_contentRotationRndEulerX, "Ignored with 'Is Normal Oriented Placement' enabled");
                }
                GUI.enabled           = true;
                obj.RotationRndEulerY = Mathf.Min(360f, EditorGUILayout.FloatField(m_contentRotationRndEulerY, obj.RotationRndEulerY));
                GUI.enabled           = !obj.IsPlacementRotationByNormal;
                if (GUI.enabled)
                {
                    obj.RotationRndEulerZ = Mathf.Min(360f, EditorGUILayout.FloatField(m_contentRotationRndEulerZ, obj.RotationRndEulerZ));
                }
                else
                {
                    EditorGUILayout.TextField(m_contentRotationRndEulerX, "Ignored with 'Is Normal Oriented Placement' enabled");
                }
                GUI.enabled = true;
                obj.IsPlacementRotationByNormal = EditorGUILayout.ToggleLeft(m_contentIsPlacementRotationByNormal, obj.IsPlacementRotationByNormal);
                obj.IsRotatable = EditorGUILayout.ToggleLeft(m_contentIsRotatable, obj.IsRotatable);
                if (obj.IsRotatable)
                {
                    EditorGUI.indentLevel++;
                    obj.IsRotatableAroundX = EditorGUILayout.ToggleLeft(m_contentIsRotatableAroundX, obj.IsRotatableAroundX);
                    obj.IsRotatableAroundY = EditorGUILayout.ToggleLeft(m_contentIsRotatableAroundY, obj.IsRotatableAroundY);
                    obj.IsRotatableAroundZ = EditorGUILayout.ToggleLeft(m_contentIsRotatableAroundZ, obj.IsRotatableAroundZ);
                    EditorGUI.indentLevel--;
                }
            }

            string scaleSummaryExtra = ((obj.IsScaleable && (obj.IsScaleableOnX || obj.IsScaleableOnY || obj.IsScaleableOnZ)) && obj.IsUniformScale)?"uniform,":"";

            if (obj.UniformScaleRnd != -1 && (obj.IsScaleableOnX || obj.IsScaleableOnY || obj.IsScaleableOnZ))
            {
                scaleSummaryExtra += "rnd";
                if (obj.IsScaleableOnX)
                {
                    scaleSummaryExtra += "X";
                }
                if (obj.IsScaleableOnY)
                {
                    scaleSummaryExtra += "Y";
                }
                if (obj.IsScaleableOnZ)
                {
                    scaleSummaryExtra += "Z";
                }
                scaleSummaryExtra += "[" + (-0.5f * obj.UniformScaleRnd) + "," + (0.5f * obj.UniformScaleRnd) + "],";
            }
            string scaleSummary = GetTransformationHandleSummary("Scale", "scaleable", scaleSummaryExtra, obj.IsScaleable, obj.IsScaleableOnX, obj.IsScaleableOnY, obj.IsScaleableOnZ);

            s_isFoldoutScale = EditorGUILayout.Foldout(s_isFoldoutScale, scaleSummary);
            if (s_isFoldoutScale)
            {
                obj.UniformScaleRnd = EditorGUILayout.FloatField(m_contentUniformScaleRnd, obj.UniformScaleRnd);
                obj.IsUniformScale  = EditorGUILayout.ToggleLeft(m_contentIsUniformScale, obj.IsUniformScale);
                obj.IsScaleable     = EditorGUILayout.ToggleLeft(m_contentIsScaleable, obj.IsScaleable);
                if (obj.IsScaleable)
                {
                    EditorGUI.indentLevel++;
                    obj.IsScaleableOnX = EditorGUILayout.ToggleLeft(m_contentIsScaleableOnX, obj.IsScaleableOnX);
                    obj.IsScaleableOnY = EditorGUILayout.ToggleLeft(m_contentIsScaleableOnY, obj.IsScaleableOnY);
                    obj.IsScaleableOnZ = EditorGUILayout.ToggleLeft(m_contentIsScaleableOnZ, obj.IsScaleableOnZ);
                    EditorGUI.indentLevel--;
                }
            }

            string physicsSummary = "Physics [" + (obj.IsRigidbodySleepingStart?"sleep on start":"awake on start") + " - " + (obj.IsRigidbodySleepingStartEditable?"editable":"fixed") + "]";

            s_isFoldoutPhysics = EditorGUILayout.Foldout(s_isFoldoutPhysics, physicsSummary);
            if (s_isFoldoutPhysics)
            {
                obj.IsRigidbodySleepingStart         = EditorGUILayout.ToggleLeft(m_contentIsRigidbodySleepingStart, obj.IsRigidbodySleepingStart);
                obj.IsRigidbodySleepingStartEditable = EditorGUILayout.ToggleLeft(m_contentIsRigidbodySleepingStartEditable, obj.IsRigidbodySleepingStartEditable);
            }

            string levelStreamingSummary = "Level Streaming [" + (obj.IsLevelStreaming?"game(" + obj.LevelStreamingInstantiateDistance + "," + obj.LevelStreamingDestroyDistance + ") editor(" + obj.LevelStreamingInstantiateDistanceInEditor + "," + obj.LevelStreamingDestroyDistanceInEditor + ")":"disabled") + "]";

            s_isFoldoutLevelStreaming = EditorGUILayout.Foldout(s_isFoldoutLevelStreaming, levelStreamingSummary);
            if (s_isFoldoutLevelStreaming)
            {
                obj.IsLevelStreaming = EditorGUILayout.ToggleLeft(m_contentIsLevelStreaming, obj.IsLevelStreaming);
                if (obj.IsLevelStreaming)
                {
                    EditorGUI.indentLevel++;
                    obj.LevelStreamingUpdateFrequency                     = EditorGUILayout.IntField(m_contentLevelStreamingUpdateFrequency, obj.LevelStreamingUpdateFrequency);
                    obj.LevelStreamingInstantiateDistance                 = EditorGUILayout.FloatField(m_contentLevelStreamingInstantiateDistance, obj.LevelStreamingInstantiateDistance);
                    obj.LevelStreamingDestroyDistance                     = EditorGUILayout.FloatField(m_contentLevelStreamingDestroyDistance, obj.LevelStreamingDestroyDistance);
                    obj.LevelStreamingInstantiateDistanceInEditor         = EditorGUILayout.FloatField(m_contentLevelStreamingInstantiateDistanceInEditor, obj.LevelStreamingInstantiateDistanceInEditor);
                    obj.LevelStreamingDestroyDistanceInEditor             = EditorGUILayout.FloatField(m_contentLevelStreamingDestroyDistanceInEditor, obj.LevelStreamingDestroyDistanceInEditor);
                    obj.IsTransformationCachedOnDestroyWhenLevelStreaming = EditorGUILayout.ToggleLeft(m_contentIsTransformationCachedOnDestroyWhenLevelStreaming, obj.IsTransformationCachedOnDestroyWhenLevelStreaming);
                    EditorGUI.indentLevel--;
                }
            }

            obj.SnapType = (LE_Object.ESnapType)EditorGUILayout.EnumPopup(m_contentSnapType, obj.SnapType);
            switch (obj.SnapType)
            {
            case LE_Object.ESnapType.SNAP_TO_TERRAIN:
                EditorGUILayout.HelpBox("SNAP_TO_TERRAIN: object will snap to terrain every time the terrain is changed or the object is . If normal oriented placement is active then the object's orientation will be changed accordingly after every terrain change or object's position change.", MessageType.Info);
                break;

            case LE_Object.ESnapType.SNAP_TO_OBJECT:
                EditorGUILayout.HelpBox("SNAP_TO_OBJECT: in this snap mode it is possible to snap other objects to this level object.", MessageType.Info);
                break;

            case LE_Object.ESnapType.SNAP_TO_3D_GRID:
                EditorGUILayout.HelpBox("SNAP_TO_3D_GRID: object can be placed only within the given grid on all axes.", MessageType.Info);
                break;

            case LE_Object.ESnapType.SNAP_TO_2D_GRID_AND_TERRAIN:
                EditorGUILayout.HelpBox("SNAP_TO_2D_GRID_AND_TERRAIN: object can be placed only within the given grid on the x and z axes. The y axis value is defined by the terrain.", MessageType.Info);
                break;
            }
            if (obj.SnapType == LE_Object.ESnapType.SNAP_TO_OBJECT)
            {
                // object snap definition
                EditorGUI.indentLevel++;
                EditorGUI.BeginChangeCheck();
                EditorGUILayout.PropertyField(serializedObject.FindProperty("m_objectSnapPoints"), m_contentObjectSnapPoints, true);
                if (EditorGUI.EndChangeCheck())
                {
                    serializedObject.ApplyModifiedProperties();
                }
                if (obj.ObjectSnapPoints.Length == 0)
                {
                    isChanged = true;
                    // init default values
                    LE_ObjectSnapPoint[] snapPoints = new LE_ObjectSnapPoint[1];
                    snapPoints[0]        = new LE_ObjectSnapPoint();
                    obj.ObjectSnapPoints = snapPoints;
                }
                // snap root point
                obj.RootSnapPointIndex = EditorGUILayout.IntField(m_contentRootSnapPointIndex, obj.RootSnapPointIndex);
                // snap to object UI
                obj.IsDrawSnapToObjectUI = EditorGUILayout.ToggleLeft(m_contentIsDrawSnapToObjectUI, obj.IsDrawSnapToObjectUI);
                EditorGUI.indentLevel--;
            }
            else if (obj.SnapType == LE_Object.ESnapType.SNAP_TO_3D_GRID)
            {
                obj.SnapGridOffset   = EditorGUILayout.Vector3Field(m_contentSnapGridOffset, obj.SnapGridOffset);
                obj.SnapGridCellSize = EditorGUILayout.Vector3Field(m_contentSnapGridCellSize, obj.SnapGridCellSize);
            }
            else if (obj.SnapType == LE_Object.ESnapType.SNAP_TO_2D_GRID_AND_TERRAIN)
            {
                Vector2    offset2d = new Vector2(obj.SnapGridOffset.x, obj.SnapGridOffset.z);
                GUIContent contentSnapGridOffsetX = new GUIContent(m_contentSnapGridOffset);
                contentSnapGridOffsetX.text += " X";
                offset2d.x = EditorGUILayout.FloatField(contentSnapGridOffsetX, offset2d.x);
                GUIContent contentSnapGridOffsetY = new GUIContent(m_contentSnapGridOffset);
                contentSnapGridOffsetY.text += " Z";
                offset2d.y         = EditorGUILayout.FloatField(contentSnapGridOffsetY, offset2d.y);
                obj.SnapGridOffset = new Vector3(offset2d.x, obj.SnapGridOffset.y, offset2d.y);

                Vector2    cellSize2d = new Vector2(obj.SnapGridCellSize.x, obj.SnapGridCellSize.z);
                GUIContent contentSnapGridCellSizeX = new GUIContent(m_contentSnapGridCellSize);
                contentSnapGridCellSizeX.text += " X";
                cellSize2d.x = EditorGUILayout.FloatField(contentSnapGridCellSizeX, cellSize2d.x);
                GUIContent contentSnapGridCellSizeY = new GUIContent(m_contentSnapGridCellSize);
                contentSnapGridCellSizeY.text += " Z";
                cellSize2d.y         = EditorGUILayout.FloatField(contentSnapGridCellSizeY, cellSize2d.y);
                obj.SnapGridCellSize = new Vector3(cellSize2d.x, obj.SnapGridCellSize.y, cellSize2d.y);
            }

            EVariationType variationType    = GetVariationType(obj);
            EVariationType newVariationType = (EVariationType)EditorGUILayout.EnumPopup(m_contentVariationType, variationType);

            Variation_ChangeTypeCheck(obj, variationType, newVariationType);
            switch (newVariationType)
            {
            case EVariationType.REPLACE_MATERIALS:
                EditorGUILayout.HelpBox("REPLACE_MATERIALS: will replace all materials of the selected renderers in this level objects. The player will be able to choose between these variations if he selects an instance of this level object in the scene.", MessageType.Info);
                break;

            case EVariationType.ACTIVE_DEACTIVATE_OBJECTS:
                EditorGUILayout.HelpBox("ACTIVE_DEACTIVATE_OBJECTS: will activate/deactivate sub objects of this level object. The player will be able to choose between these variations if he selects an instance of this level object in the scene.", MessageType.Info);
                break;
            }
            LE_ObjectVariationBase[]               VariationsGeneric            = obj.Variations;
            LE_ObjectVariationMaterial[]           VariationsMaterial           = obj.VariationsMaterial;
            LE_ObjectVariationActivateDeactivate[] VariationsActivateDeactivate = obj.VariationsActivateDeactivate;
            if (VariationsGeneric.Length > 1)
            {
                int newVariationIndex = Mathf.Clamp(EditorGUILayout.IntField(m_contentVariationsDefaultIndex, obj.VariationsDefaultIndex), 0, VariationsGeneric.Length - 1);
                if (newVariationIndex != obj.VariationsDefaultIndex)
                {
                    obj.VariationsDefaultIndex = newVariationIndex;
                    isChanged = true;
                }
            }
            EditorGUI.indentLevel++;
            for (int i = 0; i < VariationsGeneric.Length; i++)
            {
                LE_ObjectVariationBase variation = VariationsGeneric[i];
                if (variation == null)
                {
                    continue;
                }
                if (!s_isFoldoutVariation.ContainsKey(i))
                {
                    s_isFoldoutVariation[i] = false;
                }
                EditorGUILayout.BeginHorizontal();
                s_isFoldoutVariation[i] = EditorGUILayout.Foldout(s_isFoldoutVariation[i], "Variation: " + variation.GetName());
                if (GUILayout.Button("Remove"))
                {
                    if (newVariationType == EVariationType.REPLACE_MATERIALS && i < VariationsMaterial.Length)
                    {
                        List <LE_ObjectVariationMaterial> list = new List <LE_ObjectVariationMaterial>(VariationsMaterial);
                        list.RemoveAt(i);
                        obj.VariationsMaterial = list.ToArray();
                    }
                    else if (newVariationType == EVariationType.ACTIVE_DEACTIVATE_OBJECTS && i < VariationsActivateDeactivate.Length)
                    {
                        List <LE_ObjectVariationActivateDeactivate> list = new List <LE_ObjectVariationActivateDeactivate>(VariationsActivateDeactivate);
                        list.RemoveAt(i);
                        obj.VariationsActivateDeactivate = list.ToArray();
                    }
                }
                EditorGUILayout.EndHorizontal();
                if (s_isFoldoutVariation[i])
                {
                    if (newVariationType == EVariationType.REPLACE_MATERIALS && i < VariationsMaterial.Length)
                    {
                        DrawVariationMaterial(obj, VariationsMaterial[i]);
                    }
                    else if (newVariationType == EVariationType.ACTIVE_DEACTIVATE_OBJECTS && i < VariationsActivateDeactivate.Length)
                    {
                        DrawVariationActivateDeactivate(obj, VariationsActivateDeactivate[i]);
                    }
                }
            }
            if (newVariationType != EVariationType.NONE && GUILayout.Button("Add Variation"))
            {
                AddVariation(obj, newVariationType, "Variation " + VariationsGeneric.Length);
            }
            EditorGUI.indentLevel--;

            isChanged = SnapToTerrain_RotationAxisCheck(obj) || isChanged;
            isChanged = SnapToTerrain_MoveAxisCheck(obj) || isChanged;

            if (GUI.changed || isChanged)
            {
                EditorUtility.SetDirty(obj);
            }
        }