123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799 |
- using System;
- using System.Collections.Generic;
- using UnityEditor.IMGUI.Controls;
- using UnityEditor.ShortcutManagement;
- using UnityEditorInternal;
- using UnityEngine;
- using UnityEngine.Rendering.Universal;
- using static UnityEditorInternal.EditMode;
-
- namespace UnityEditor.Rendering.Universal
- {
- [CustomEditor(typeof(DecalProjector))]
- [CanEditMultipleObjects]
- partial class DecalProjectorEditor : Editor
- {
- const float k_Limit = 100000f;
- const float k_LimitInv = 1f / k_Limit;
-
- static Color fullColor
- {
- get
- {
- Color c = s_LastColor;
- c.a = 1f;
- return c;
- }
- }
- static Color s_LastColor;
- static void UpdateColorsInHandlesIfRequired()
- {
- Color c = DecalPreferences.decalGizmoColor;
- if (c != s_LastColor)
- {
- if (s_BoxHandle != null && !s_BoxHandle.Equals(null))
- s_BoxHandle = null;
-
- if (s_uvHandles != null && !s_uvHandles.Equals(null))
- s_uvHandles.baseColor = c;
-
- s_LastColor = c;
- }
- }
-
- MaterialEditor m_MaterialEditor = null;
- SerializedProperty m_MaterialProperty;
- SerializedProperty m_DrawDistanceProperty;
- SerializedProperty m_FadeScaleProperty;
- SerializedProperty m_StartAngleFadeProperty;
- SerializedProperty m_EndAngleFadeProperty;
- SerializedProperty m_UVScaleProperty;
- SerializedProperty m_UVBiasProperty;
- SerializedProperty m_ScaleMode;
- SerializedProperty m_Size;
- SerializedProperty[] m_SizeValues;
- SerializedProperty m_Offset;
- SerializedProperty[] m_OffsetValues;
- SerializedProperty m_FadeFactor;
- SerializedProperty m_RenderingLayerMask;
-
- int layerMask => (target as Component).gameObject.layer;
- bool layerMaskHasMultipleValues
- {
- get
- {
- if (targets.Length < 2)
- return false;
- int layerMask = (targets[0] as Component).gameObject.layer;
- for (int index = 1; index < targets.Length; ++index)
- {
- if ((targets[index] as Component).gameObject.layer != layerMask)
- return true;
- }
- return false;
- }
- }
-
- static HierarchicalBox s_BoxHandle;
- static HierarchicalBox boxHandle
- {
- get
- {
- if (s_BoxHandle == null || s_BoxHandle.Equals(null))
- {
- Color c = fullColor;
- s_BoxHandle = new HierarchicalBox(s_LastColor, new[] { c, c, c, c, c, c });
- s_BoxHandle.SetBaseColor(s_LastColor);
- s_BoxHandle.monoHandle = false;
- }
- return s_BoxHandle;
- }
- }
-
- static DisplacableRectHandles s_uvHandles;
- static DisplacableRectHandles uvHandles
- {
- get
- {
- if (s_uvHandles == null || s_uvHandles.Equals(null))
- s_uvHandles = new DisplacableRectHandles(s_LastColor);
- return s_uvHandles;
- }
- }
-
- static readonly BoxBoundsHandle s_AreaLightHandle =
- new BoxBoundsHandle { axes = PrimitiveBoundsHandle.Axes.X | PrimitiveBoundsHandle.Axes.Y };
-
- const SceneViewEditMode k_EditShapeWithoutPreservingUV = (SceneViewEditMode)90;
- const SceneViewEditMode k_EditShapePreservingUV = (SceneViewEditMode)91;
- const SceneViewEditMode k_EditUVAndPivot = (SceneViewEditMode)92;
- static readonly SceneViewEditMode[] k_EditVolumeModes = new SceneViewEditMode[]
- {
- k_EditShapeWithoutPreservingUV,
- k_EditShapePreservingUV,
- k_EditUVAndPivot,
- };
-
- static Func<Vector3, Quaternion, Vector3> s_DrawPivotHandle;
-
- static GUIContent[] k_EditVolumeLabels = null;
- static GUIContent[] editVolumeLabels => k_EditVolumeLabels ?? (k_EditVolumeLabels = new GUIContent[]
- {
- EditorGUIUtility.TrIconContent("d_ScaleTool", k_EditShapeWithoutPreservingUVTooltip),
- EditorGUIUtility.TrIconContent("d_RectTool", k_EditShapePreservingUVTooltip),
- EditorGUIUtility.TrIconContent("d_MoveTool", k_EditUVTooltip),
- });
-
- static List<DecalProjectorEditor> s_Instances = new List<DecalProjectorEditor>();
-
- static DecalProjectorEditor FindEditorFromSelection()
- {
- GameObject[] selection = Selection.gameObjects;
- DecalProjector[] selectionTargets = Selection.GetFiltered<DecalProjector>(SelectionMode.Unfiltered);
-
- foreach (DecalProjectorEditor editor in s_Instances)
- {
- if (selectionTargets.Length != editor.targets.Length)
- continue;
- bool allOk = true;
- foreach (DecalProjector selectionTarget in selectionTargets)
- {
- if (!Array.Find(editor.targets, t => t == selectionTarget))
- {
- allOk = false;
- break;
- }
- }
- if (!allOk)
- continue;
- return editor;
- }
- return null;
- }
-
- private void OnEnable()
- {
- s_Instances.Add(this);
-
- // Create an instance of the MaterialEditor
- UpdateMaterialEditor();
-
- // Fetch serialized properties
- m_MaterialProperty = serializedObject.FindProperty("m_Material");
- m_DrawDistanceProperty = serializedObject.FindProperty("m_DrawDistance");
- m_FadeScaleProperty = serializedObject.FindProperty("m_FadeScale");
- m_StartAngleFadeProperty = serializedObject.FindProperty("m_StartAngleFade");
- m_EndAngleFadeProperty = serializedObject.FindProperty("m_EndAngleFade");
- m_UVScaleProperty = serializedObject.FindProperty("m_UVScale");
- m_UVBiasProperty = serializedObject.FindProperty("m_UVBias");
- m_ScaleMode = serializedObject.FindProperty("m_ScaleMode");
- m_Size = serializedObject.FindProperty("m_Size");
- m_SizeValues = new[]
- {
- m_Size.FindPropertyRelative("x"),
- m_Size.FindPropertyRelative("y"),
- m_Size.FindPropertyRelative("z"),
- };
- m_Offset = serializedObject.FindProperty("m_Offset");
- m_OffsetValues = new[]
- {
- m_Offset.FindPropertyRelative("x"),
- m_Offset.FindPropertyRelative("y"),
- m_Offset.FindPropertyRelative("z"),
- };
- m_FadeFactor = serializedObject.FindProperty("m_FadeFactor");
- m_RenderingLayerMask = serializedObject.FindProperty("m_DecalLayerMask");
-
- ReinitSavedRatioSizePivotPosition();
- }
-
- private void OnDisable()
- {
- s_Instances.Remove(this);
- }
-
- private void OnDestroy() =>
- DestroyImmediate(m_MaterialEditor);
-
- public bool HasFrameBounds()
- {
- return true;
- }
-
- public Bounds OnGetFrameBounds()
- {
- DecalProjector decalProjector = target as DecalProjector;
-
- return new Bounds(decalProjector.transform.position, boxHandle.size);
- }
-
- public void UpdateMaterialEditor()
- {
- int validMaterialsCount = 0;
- for (int index = 0; index < targets.Length; ++index)
- {
- DecalProjector decalProjector = (targets[index] as DecalProjector);
- if ((decalProjector != null) && (decalProjector.material != null))
- validMaterialsCount++;
- }
- // Update material editor with the new material
- UnityEngine.Object[] materials = new UnityEngine.Object[validMaterialsCount];
- validMaterialsCount = 0;
- for (int index = 0; index < targets.Length; ++index)
- {
- DecalProjector decalProjector = (targets[index] as DecalProjector);
-
- if ((decalProjector != null) && (decalProjector.material != null))
- materials[validMaterialsCount++] = (targets[index] as DecalProjector).material;
- }
- m_MaterialEditor = (MaterialEditor)CreateEditor(materials);
- }
-
- void OnSceneGUI()
- {
- //called on each targets
- DrawHandles();
- }
-
- void DrawBoxTransformationHandles(DecalProjector decalProjector)
- {
- Vector3 scale = decalProjector.effectiveScale;
- using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, scale)))
- {
- Vector3 centerStart = decalProjector.pivot;
- boxHandle.center = centerStart;
- boxHandle.size = decalProjector.size;
-
- Vector3 boundsSizePreviousOS = boxHandle.size;
- Vector3 boundsMinPreviousOS = boxHandle.size * -0.5f + boxHandle.center;
-
- EditorGUI.BeginChangeCheck();
- boxHandle.DrawHandle();
- if (EditorGUI.EndChangeCheck())
- {
- // Adjust decal transform if handle changed.
- Undo.RecordObject(decalProjector, "Decal Projector Change");
-
- bool xChangeIsValid = scale.x != 0f;
- bool yChangeIsValid = scale.y != 0f;
- bool zChangeIsValid = scale.z != 0f;
-
- // Preserve serialized state for axes with scale 0.
- decalProjector.size = new Vector3(
- xChangeIsValid ? boxHandle.size.x : decalProjector.size.x,
- yChangeIsValid ? boxHandle.size.y : decalProjector.size.y,
- zChangeIsValid ? boxHandle.size.z : decalProjector.size.z);
- decalProjector.pivot = new Vector3(
- xChangeIsValid ? boxHandle.center.x : decalProjector.pivot.x,
- yChangeIsValid ? boxHandle.center.y : decalProjector.pivot.y,
- zChangeIsValid ? boxHandle.center.z : decalProjector.pivot.z);
-
- Vector3 boundsSizeCurrentOS = boxHandle.size;
- Vector3 boundsMinCurrentOS = boxHandle.size * -0.5f + boxHandle.center;
-
- if (editMode == k_EditShapePreservingUV)
- {
- // Treat decal projector bounds as a crop tool, rather than a scale tool.
- // Compute a new uv scale and bias terms to pin decal projection pixels in world space, irrespective of projector bounds.
- // Preserve serialized state for axes with scale 0.
- Vector2 uvScale = decalProjector.uvScale;
- Vector2 uvBias = decalProjector.uvBias;
- if (xChangeIsValid)
- {
- uvScale.x *= Mathf.Max(k_LimitInv, boundsSizeCurrentOS.x) / Mathf.Max(k_LimitInv, boundsSizePreviousOS.x);
- uvBias.x += (boundsMinCurrentOS.x - boundsMinPreviousOS.x) / Mathf.Max(k_LimitInv, boundsSizeCurrentOS.x) * uvScale.x;
- }
- if (yChangeIsValid)
- {
- uvScale.y *= Mathf.Max(k_LimitInv, boundsSizeCurrentOS.y) / Mathf.Max(k_LimitInv, boundsSizePreviousOS.y);
- uvBias.y += (boundsMinCurrentOS.y - boundsMinPreviousOS.y) / Mathf.Max(k_LimitInv, boundsSizeCurrentOS.y) * uvScale.y;
- }
- decalProjector.uvScale = uvScale;
- decalProjector.uvBias = uvBias;
- }
-
- if (PrefabUtility.IsPartOfNonAssetPrefabInstance(decalProjector))
- {
- PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector);
- }
- }
- }
- }
-
- void DrawPivotHandles(DecalProjector decalProjector)
- {
- Vector3 scale = decalProjector.effectiveScale;
- Vector3 scaledPivot = Vector3.Scale(decalProjector.pivot, scale);
- Vector3 scaledSize = Vector3.Scale(decalProjector.size, scale);
-
- using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one)))
- {
- EditorGUI.BeginChangeCheck();
- Vector3 newPosition = ProjectedTransform.DrawHandles(decalProjector.transform.position, .5f * scaledSize.z - scaledPivot.z, decalProjector.transform.rotation);
- if (EditorGUI.EndChangeCheck())
- {
- Undo.RecordObjects(new UnityEngine.Object[] { decalProjector, decalProjector.transform }, "Decal Projector Change");
-
- scaledPivot += Quaternion.Inverse(decalProjector.transform.rotation) * (decalProjector.transform.position - newPosition);
- decalProjector.pivot = new Vector3(
- scale.x != 0f ? scaledPivot.x / scale.x : decalProjector.pivot.x,
- scale.y != 0f ? scaledPivot.y / scale.y : decalProjector.pivot.y,
- scale.z != 0f ? scaledPivot.z / scale.z : decalProjector.pivot.z);
- decalProjector.transform.position = newPosition;
-
- ReinitSavedRatioSizePivotPosition();
- }
- }
- }
-
- void DrawUVHandles(DecalProjector decalProjector)
- {
- Vector3 scale = decalProjector.effectiveScale;
- Vector3 scaledPivot = Vector3.Scale(decalProjector.pivot, scale);
- Vector3 scaledSize = Vector3.Scale(decalProjector.size, scale);
-
- using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * (scaledPivot - .5f * scaledSize), decalProjector.transform.rotation, scale)))
- {
- Vector2 uvScale = decalProjector.uvScale;
- Vector2 uvBias = decalProjector.uvBias;
-
- Vector2 uvSize = new Vector2(
- (uvScale.x > k_Limit || uvScale.x < -k_Limit) ? 0f : decalProjector.size.x / uvScale.x,
- (uvScale.y > k_Limit || uvScale.y < -k_Limit) ? 0f : decalProjector.size.y / uvScale.y
- );
- Vector2 uvCenter = uvSize * .5f - new Vector2(uvBias.x * uvSize.x, uvBias.y * uvSize.y);
-
- uvHandles.center = uvCenter;
- uvHandles.size = uvSize;
-
- EditorGUI.BeginChangeCheck();
- uvHandles.DrawHandle();
- if (EditorGUI.EndChangeCheck())
- {
- Undo.RecordObject(decalProjector, "Decal Projector Change");
-
- for (int channel = 0; channel < 2; channel++)
- {
- // Preserve serialized state for axes with the scaled size 0.
- if (scaledSize[channel] != 0f)
- {
- float handleSize = uvHandles.size[channel];
- float minusNewUVStart = .5f * handleSize - uvHandles.center[channel];
- float decalSize = decalProjector.size[channel];
- float limit = k_LimitInv * decalSize;
- if (handleSize > limit || handleSize < -limit)
- {
- uvScale[channel] = decalSize / handleSize;
- uvBias[channel] = minusNewUVStart / handleSize;
- }
- else
- {
- // TODO: Decide if uvHandles.size should ever have negative value. It can't currently.
- uvScale[channel] = k_Limit * Mathf.Sign(handleSize);
- uvBias[channel] = k_Limit * minusNewUVStart / decalSize;
- }
- }
- }
-
- decalProjector.uvScale = uvScale;
- decalProjector.uvBias = uvBias;
- }
- }
- }
-
- void DrawHandles()
- {
- DecalProjector decalProjector = target as DecalProjector;
-
- if (editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV)
- DrawBoxTransformationHandles(decalProjector);
- else if (editMode == k_EditUVAndPivot)
- {
- DrawPivotHandles(decalProjector);
- DrawUVHandles(decalProjector);
- }
- }
-
- [DrawGizmo(GizmoType.Selected | GizmoType.Active)]
- static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoType)
- {
- float lod = Gizmos.CalculateLOD(decalProjector.transform.position, decalProjector.size.magnitude * 0.25f);
-
- // skip drawing anything if it will be too small or behind the camera on screen
- if (lod < 0.1f)
- return;
-
- UpdateColorsInHandlesIfRequired();
-
- const float k_DotLength = 5f;
-
- // Draw them with scale applied to size and pivot instead of the matrix to keep the proportions of the arrow and lines.
- using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one)))
- {
- Vector3 scale = decalProjector.effectiveScale;
- Vector3 scaledPivot = Vector3.Scale(decalProjector.pivot, scale);
- Vector3 scaledSize = Vector3.Scale(decalProjector.size, scale);
-
- boxHandle.center = scaledPivot;
- boxHandle.size = scaledSize;
- bool isVolumeEditMode = editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV;
- bool isPivotEditMode = editMode == k_EditUVAndPivot;
- if (lod > 0.5f)
- {
- boxHandle.DrawHull(isVolumeEditMode);
- }
- else
- Handles.DrawWireCube(scaledPivot, scaledSize); // simplify the drawing if too small on screen
-
- if (lod == 1.0f) // only draw when big enough on screen to be useable
- {
- Vector3 pivot = Vector3.zero;
- Vector3 projectedPivot = new Vector3(0, 0, scaledPivot.z - .5f * scaledSize.z);
-
- if (isPivotEditMode)
- {
- Handles.DrawDottedLines(new[] { projectedPivot, pivot }, k_DotLength);
- }
- else
- {
- float arrowSize = scaledSize.z * 0.25f;
- Handles.ArrowHandleCap(0, projectedPivot, Quaternion.identity, arrowSize, EventType.Repaint);
- }
-
- //draw UV and bolder edges
- using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * new Vector3(scaledPivot.x, scaledPivot.y, scaledPivot.z - .5f * scaledSize.z), decalProjector.transform.rotation, Vector3.one)))
- {
- Vector2 UVSize = new Vector2(
- (decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit) ? 0f : scaledSize.x / decalProjector.uvScale.x,
- (decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit) ? 0f : scaledSize.y / decalProjector.uvScale.y
- );
- Vector2 UVCenter = UVSize * .5f - new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y) - (Vector2)scaledSize * .5f;
-
- uvHandles.center = UVCenter;
- uvHandles.size = UVSize;
- uvHandles.DrawRect(dottedLine: true, screenSpaceSize: k_DotLength);
-
- uvHandles.center = default;
- uvHandles.size = scaledSize;
- uvHandles.DrawRect(dottedLine: false, thickness: 3f);
- }
- }
- }
- }
-
- static Func<Bounds> GetBoundsGetter(DecalProjector decalProjector)
- {
- return () =>
- {
- var bounds = new Bounds();
- var decalTransform = decalProjector.transform;
- bounds.Encapsulate(decalTransform.position);
- return bounds;
- };
- }
-
- // Temporarily save ratio between size and pivot position while editing in inspector.
- // null or NaN is used to say that there is no saved ratio.
- // Aim is to keep proportion while sliding the value to 0 in Inspector and then go back to something else.
- // Current solution only works for the life of this editor, but is enough in most cases.
- // Which means if you go to there, selection something else and go back on it, pivot position is thus null.
- Dictionary<DecalProjector, Vector3> ratioSizePivotPositionSaved = null;
-
- void ReinitSavedRatioSizePivotPosition()
- {
- ratioSizePivotPositionSaved = null;
- }
-
- void UpdateSize(int axe, float newSize)
- {
- void UpdateSizeOfOneTarget(DecalProjector currentTarget)
- {
- //lazy init on demand as targets array cannot be accessed from OnSceneGUI so in edit mode.
- if (ratioSizePivotPositionSaved == null)
- {
- ratioSizePivotPositionSaved = new Dictionary<DecalProjector, Vector3>();
- foreach (DecalProjector projector in targets)
- ratioSizePivotPositionSaved[projector] = new Vector3(float.NaN, float.NaN, float.NaN);
- }
-
- // Save old ratio if not registered
- // Either or are NaN or no one, check only first
- Vector3 saved = ratioSizePivotPositionSaved[currentTarget];
- if (float.IsNaN(saved[axe]))
- {
- float oldSize = currentTarget.m_Size[axe];
- saved[axe] = Mathf.Abs(oldSize) <= Mathf.Epsilon ? 0f : currentTarget.m_Offset[axe] / oldSize;
- ratioSizePivotPositionSaved[currentTarget] = saved;
- }
-
- currentTarget.m_Size[axe] = newSize;
- currentTarget.m_Offset[axe] = saved[axe] * newSize;
-
- // refresh DecalProjector to update projection
- currentTarget.OnValidate();
- }
-
- // Manually register Undo as we work directly on the target
- Undo.RecordObjects(targets, "Change DecalProjector Size or Depth");
-
- // Apply any change on target first
- serializedObject.ApplyModifiedProperties();
-
- // update each target
- foreach (DecalProjector decalProjector in targets)
- {
- UpdateSizeOfOneTarget(decalProjector);
-
- // Fix for UUM-29105 (Changes made to Decal Project Prefab in the Inspector are not saved)
- // This editor doesn't use serializedObject to modify the target objects, explicitly mark the prefab
- // asset dirty to ensure the new data is saved.
- if (PrefabUtility.IsPartOfPrefabAsset(decalProjector))
- EditorUtility.SetDirty(decalProjector);
- }
-
- // update again serialize object to register change in targets
- serializedObject.Update();
-
- // change was not tracked by SerializeReference so force repaint the scene views and game views
- UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
-
- // strange: we need to force it throu serialization to update multiple differente value state (value are right but still detected as different)
- if (m_SizeValues[axe].hasMultipleDifferentValues)
- m_SizeValues[axe].floatValue = newSize;
- }
-
- public override void OnInspectorGUI()
- {
- serializedObject.Update();
-
- bool materialChanged = false;
- bool isDefaultMaterial = false;
- bool isValidDecalMaterial = true;
-
- bool isDecalSupported = DecalProjector.isSupported;
- if (!isDecalSupported)
- EditorUtils.FeatureHelpBox("The current renderer has no Decal Renderer Feature added.", MessageType.Warning);
-
- EditorGUI.BeginChangeCheck();
- {
- EditorGUILayout.BeginHorizontal();
- GUILayout.FlexibleSpace();
- DoInspectorToolbar(k_EditVolumeModes, editVolumeLabels, GetBoundsGetter(target as DecalProjector), this);
- GUILayout.FlexibleSpace();
- EditorGUILayout.EndHorizontal();
-
- EditorGUILayout.Space();
-
- // Info box for tools
- GUIStyle style = new GUIStyle(EditorStyles.miniLabel);
- style.richText = true;
- GUILayout.BeginVertical(EditorStyles.helpBox);
- string helpText = k_BaseSceneEditingToolText;
- if (EditMode.editMode == k_EditShapeWithoutPreservingUV && EditMode.IsOwner(this))
- helpText = k_EditShapeWithoutPreservingUVName;
- if (EditMode.editMode == k_EditShapePreservingUV && EditMode.IsOwner(this))
- helpText = k_EditShapePreservingUVName;
- if (EditMode.editMode == k_EditUVAndPivot && EditMode.IsOwner(this))
- helpText = k_EditUVAndPivotName;
- GUILayout.Label(helpText, style);
- GUILayout.EndVertical();
- EditorGUILayout.Space();
-
- EditorGUILayout.PropertyField(m_ScaleMode, k_ScaleMode);
-
- bool negativeScale = false;
- foreach (var target in targets)
- {
- var decalProjector = target as DecalProjector;
-
- float combinedScale = decalProjector.transform.lossyScale.x * decalProjector.transform.lossyScale.y * decalProjector.transform.lossyScale.z;
- negativeScale |= combinedScale < 0 && decalProjector.scaleMode == DecalScaleMode.InheritFromHierarchy;
- }
- if (negativeScale)
- {
- EditorGUILayout.HelpBox("Does not work with negative odd scaling (When there are odd number of scale components)", MessageType.Warning);
- }
-
- var widthRect = EditorGUILayout.GetControlRect();
- EditorGUI.BeginProperty(widthRect, k_WidthContent, m_SizeValues[0]);
- EditorGUI.BeginChangeCheck();
- float newSizeX = EditorGUI.FloatField(widthRect, k_WidthContent, m_SizeValues[0].floatValue);
- if (EditorGUI.EndChangeCheck())
- UpdateSize(0, Mathf.Max(0, newSizeX));
- EditorGUI.EndProperty();
-
- var heightRect = EditorGUILayout.GetControlRect();
- EditorGUI.BeginProperty(heightRect, k_HeightContent, m_SizeValues[1]);
- EditorGUI.BeginChangeCheck();
- float newSizeY = EditorGUI.FloatField(heightRect, k_HeightContent, m_SizeValues[1].floatValue);
- if (EditorGUI.EndChangeCheck())
- UpdateSize(1, Mathf.Max(0, newSizeY));
- EditorGUI.EndProperty();
-
- var projectionRect = EditorGUILayout.GetControlRect();
- EditorGUI.BeginProperty(projectionRect, k_ProjectionDepthContent, m_SizeValues[2]);
- EditorGUI.BeginChangeCheck();
- float newSizeZ = EditorGUI.FloatField(projectionRect, k_ProjectionDepthContent, m_SizeValues[2].floatValue);
- if (EditorGUI.EndChangeCheck())
- UpdateSize(2, Mathf.Max(0, newSizeZ));
- EditorGUI.EndProperty();
-
- EditorGUI.BeginChangeCheck();
- EditorGUILayout.PropertyField(m_Offset, k_Offset);
- if (EditorGUI.EndChangeCheck())
- ReinitSavedRatioSizePivotPosition();
-
- EditorGUILayout.Space();
-
- EditorGUI.BeginChangeCheck();
- EditorGUILayout.PropertyField(m_MaterialProperty, k_MaterialContent);
- materialChanged = EditorGUI.EndChangeCheck();
-
- EditorUtils.DrawRenderingLayerMask(m_RenderingLayerMask, k_RenderingLayerMaskContent);
-
- foreach (var target in targets)
- {
- var decalProjector = target as DecalProjector;
- var mat = decalProjector.material;
-
- isDefaultMaterial |= decalProjector.material == DecalProjector.defaultMaterial;
- isValidDecalMaterial &= decalProjector.IsValid();
- }
-
- if (m_MaterialEditor && !isValidDecalMaterial)
- {
- CoreEditorUtils.DrawFixMeBox("Decal only work with Decal Material. Use default material or create from decal shader graph sub target.", () =>
- {
- m_MaterialProperty.objectReferenceValue = DecalProjector.defaultMaterial;
- materialChanged = true;
- });
- }
-
- EditorGUI.indentLevel++;
- EditorGUILayout.PropertyField(m_UVScaleProperty, k_UVScaleContent);
- EditorGUILayout.PropertyField(m_UVBiasProperty, k_UVBiasContent);
- EditorGUILayout.PropertyField(m_FadeFactor, k_OpacityContent);
- EditorGUI.indentLevel--;
-
- bool angleFadeSupport = false;
- foreach (var decalProjector in targets)
- {
- var mat = (decalProjector as DecalProjector).material;
- if (mat == null)
- continue;
- angleFadeSupport = mat.HasProperty("_DecalAngleFadeSupported");
- }
-
- EditorGUI.BeginChangeCheck();
- EditorGUILayout.PropertyField(m_DrawDistanceProperty, k_DistanceContent);
- if (EditorGUI.EndChangeCheck() && m_DrawDistanceProperty.floatValue < 0f)
- m_DrawDistanceProperty.floatValue = 0f;
-
- EditorGUI.indentLevel++;
- EditorGUILayout.PropertyField(m_FadeScaleProperty, k_FadeScaleContent);
- EditorGUI.indentLevel--;
-
- using (new EditorGUI.DisabledScope(!angleFadeSupport))
- {
- float angleFadeMinValue = m_StartAngleFadeProperty.floatValue;
- float angleFadeMaxValue = m_EndAngleFadeProperty.floatValue;
- EditorGUI.BeginChangeCheck();
- EditorGUILayout.MinMaxSlider(k_AngleFadeContent, ref angleFadeMinValue, ref angleFadeMaxValue, 0.0f, 180.0f);
- if (EditorGUI.EndChangeCheck())
- {
- m_StartAngleFadeProperty.floatValue = angleFadeMinValue;
- m_EndAngleFadeProperty.floatValue = angleFadeMaxValue;
- }
- }
-
- if (!angleFadeSupport && isValidDecalMaterial)
- {
- EditorGUILayout.HelpBox($"Decal Angle Fade is not enabled in Shader. In ShaderGraph enable Angle Fade option.", MessageType.Info);
- }
-
- EditorGUILayout.Space();
- }
- if (EditorGUI.EndChangeCheck())
- serializedObject.ApplyModifiedProperties();
-
- if (materialChanged)
- UpdateMaterialEditor();
-
- if (layerMaskHasMultipleValues || layerMask != (target as Component).gameObject.layer)
- {
- foreach (var decalProjector in targets)
- {
- (decalProjector as DecalProjector).OnValidate();
- }
- }
-
- if (m_MaterialEditor != null)
- {
- // We need to prevent the user to edit default decal materials
- if (isValidDecalMaterial)
- {
- using (new DecalProjectorScope())
- {
- using (new EditorGUI.DisabledGroupScope(isDefaultMaterial))
- {
- // Draw the material's foldout and the material shader field
- // Required to call m_MaterialEditor.OnInspectorGUI ();
- m_MaterialEditor.DrawHeader();
-
- // Draw the material properties
- // Works only if the foldout of m_MaterialEditor.DrawHeader () is open
- m_MaterialEditor.OnInspectorGUI();
- }
- }
- }
- }
- }
-
- [Shortcut("URP/Decal: Handle changing size stretching UV", typeof(SceneView), KeyCode.Keypad1, ShortcutModifiers.Action)]
- static void EnterEditModeWithoutPreservingUV(ShortcutArguments args)
- {
- //If editor is not there, then the selected GameObject does not contains a DecalProjector
- DecalProjector activeDecalProjector = Selection.activeGameObject?.GetComponent<DecalProjector>();
- if (activeDecalProjector == null || activeDecalProjector.Equals(null))
- return;
-
- ChangeEditMode(k_EditShapeWithoutPreservingUV, GetBoundsGetter(activeDecalProjector)(), FindEditorFromSelection());
- }
-
- [Shortcut("URP/Decal: Handle changing size cropping UV", typeof(SceneView), KeyCode.Keypad2, ShortcutModifiers.Action)]
- static void EnterEditModePreservingUV(ShortcutArguments args)
- {
- //If editor is not there, then the selected GameObject does not contains a DecalProjector
- DecalProjector activeDecalProjector = Selection.activeGameObject?.GetComponent<DecalProjector>();
- if (activeDecalProjector == null || activeDecalProjector.Equals(null))
- return;
-
- ChangeEditMode(k_EditShapePreservingUV, GetBoundsGetter(activeDecalProjector)(), FindEditorFromSelection());
- }
-
- [Shortcut("URP/Decal: Handle changing pivot position and UVs", typeof(SceneView), KeyCode.Keypad3, ShortcutModifiers.Action)]
- static void EnterEditModePivotPreservingUV(ShortcutArguments args)
- {
- //If editor is not there, then the selected GameObject does not contains a DecalProjector
- DecalProjector activeDecalProjector = Selection.activeGameObject?.GetComponent<DecalProjector>();
- if (activeDecalProjector == null || activeDecalProjector.Equals(null))
- return;
-
- ChangeEditMode(k_EditUVAndPivot, GetBoundsGetter(activeDecalProjector)(), FindEditorFromSelection());
- }
-
- [Shortcut("URP/Decal: Handle swap between cropping and stretching UV", typeof(SceneView), KeyCode.Keypad4, ShortcutModifiers.Action)]
- static void SwappingEditUVMode(ShortcutArguments args)
- {
- //If editor is not there, then the selected GameObject does not contains a DecalProjector
- DecalProjector activeDecalProjector = Selection.activeGameObject?.GetComponent<DecalProjector>();
- if (activeDecalProjector == null || activeDecalProjector.Equals(null))
- return;
-
- SceneViewEditMode targetMode = SceneViewEditMode.None;
- switch (editMode)
- {
- case k_EditShapePreservingUV:
- case k_EditUVAndPivot:
- targetMode = k_EditShapeWithoutPreservingUV;
- break;
- case k_EditShapeWithoutPreservingUV:
- targetMode = k_EditShapePreservingUV;
- break;
- }
- if (targetMode != SceneViewEditMode.None)
- ChangeEditMode(targetMode, GetBoundsGetter(activeDecalProjector)(), FindEditorFromSelection());
- }
-
- [Shortcut("URP/Decal: Stop Editing", typeof(SceneView), KeyCode.Keypad0, ShortcutModifiers.Action)]
- static void ExitEditMode(ShortcutArguments args)
- {
- //If editor is not there, then the selected GameObject does not contains a DecalProjector
- DecalProjector activeDecalProjector = Selection.activeGameObject?.GetComponent<DecalProjector>();
- if (activeDecalProjector == null || activeDecalProjector.Equals(null))
- return;
-
- QuitEditMode();
- }
- }
- }
|