Added player character and step in/out of dialogue in scene 101

This commit is contained in:
2026-08-15 15:22:47 +02:00
parent a42f25d5fa
commit 38ba2b0eff
2019 changed files with 181227 additions and 265 deletions
@@ -0,0 +1,222 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.ProBuilder;
using UnityEngine.ProBuilder.MeshOperations;
namespace UnityEditor.ProBuilder.Actions
{
sealed class GrowSelection : MenuAction
{
Pref<bool> m_GrowSelectionWithAngle = new Pref<bool>("GrowSelection.useAngle", true);
Pref<bool> m_GrowSelectionAngleIterative = new Pref<bool>("GrowSelection.iterativeGrow", false);
Pref<float> m_GrowSelectionAngleValue = new Pref<float>("GrowSelection.angleValue", 15f);
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => "Toolbar/Selection_Grow";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Grow Selection",
@"Adds adjacent elements to the current selection, optionally testing to see if they are within a specified angle.
Grow by angle is enabled by Option + Clicking the <b>Grow Selection</b> button.",
keyCommandAlt, 'G'
);
public override SelectMode validSelectModes
{
get { return SelectMode.Vertex | SelectMode.Edge | SelectMode.Face | SelectMode.TextureFace; }
}
public override bool enabled
{
get { return base.enabled && VerifyGrowSelection(); }
}
protected override MenuActionState optionsMenuState => MenuActionState.VisibleAndEnabled;
public override VisualElement CreateSettingsContent()
{
var root = new VisualElement();
root.enabledSelf = enabled && ProBuilderEditor.selectMode == SelectMode.Face;
var angleToggle = new Toggle("Restrict to Angle");
angleToggle.SetValueWithoutNotify(m_GrowSelectionWithAngle);
root.Add(angleToggle);
var floatField = new FloatField("Max Angle");
floatField.SetValueWithoutNotify(m_GrowSelectionAngleValue);
floatField.isDelayed = PreviewActionManager.delayedPreview;
floatField.SetEnabled(m_GrowSelectionWithAngle);
root.Add(floatField);
var iterativeToggle = new Toggle("Iterative");
iterativeToggle.SetValueWithoutNotify(m_GrowSelectionWithAngle ? m_GrowSelectionAngleIterative : true);
iterativeToggle.SetEnabled(m_GrowSelectionWithAngle);
root.Add(iterativeToggle);
angleToggle.RegisterCallback<ChangeEvent<bool>>(evt =>
{
m_GrowSelectionWithAngle.SetValue(evt.newValue);
floatField.SetEnabled(m_GrowSelectionWithAngle);
iterativeToggle.SetValueWithoutNotify(m_GrowSelectionWithAngle ? m_GrowSelectionAngleIterative : true);
iterativeToggle.SetEnabled(m_GrowSelectionWithAngle);
PreviewActionManager.UpdatePreview();
});
floatField.RegisterValueChangedCallback(evt =>
{
m_GrowSelectionAngleValue.SetValue(evt.newValue);
PreviewActionManager.UpdatePreview();
});
iterativeToggle.RegisterCallback<ChangeEvent<bool>>(evt =>
{
m_GrowSelectionAngleIterative.SetValue(evt.newValue);
PreviewActionManager.UpdatePreview();
});
System.Action onDelayedPreviewChanged = () =>
{
floatField.isDelayed = PreviewActionManager.delayedPreview;
};
PreviewActionManager.delayedPreviewChanged += onDelayedPreviewChanged;
root.RegisterCallback<DetachFromPanelEvent>(evt =>
{
PreviewActionManager.delayedPreviewChanged -= onDelayedPreviewChanged;
});
return root;
}
protected override void OnSettingsGUI()
{
GUILayout.Label("Grow Selection Options", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
m_GrowSelectionWithAngle.value = EditorGUILayout.Toggle("Restrict to Angle", m_GrowSelectionWithAngle.value);
GUI.enabled = m_GrowSelectionWithAngle;
m_GrowSelectionAngleValue.value = EditorGUILayout.FloatField("Max Angle", m_GrowSelectionAngleValue);
GUI.enabled = m_GrowSelectionWithAngle;
bool iterative = m_GrowSelectionWithAngle ? m_GrowSelectionAngleIterative : true;
EditorGUI.BeginChangeCheck();
iterative = EditorGUILayout.Toggle("Iterative", iterative);
if (EditorGUI.EndChangeCheck())
{
m_GrowSelectionAngleIterative.value = iterative;
}
GUI.enabled = true;
if (EditorGUI.EndChangeCheck())
ProBuilderSettings.Save();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Grow Selection"))
PerformAction();
}
protected override ActionResult PerformActionImplementation()
{
if (MeshSelection.selectedObjectCount < 1)
return ActionResult.NoSelection;
UndoUtility.RecordSelection("Grow Selection");
int grown = 0;
bool angleGrow = m_GrowSelectionWithAngle;
bool iterative = m_GrowSelectionAngleIterative;
float growSelectionAngle = m_GrowSelectionAngleValue;
if (!angleGrow && !iterative)
iterative = true;
foreach (ProBuilderMesh pb in InternalUtility.GetComponents<ProBuilderMesh>(Selection.transforms))
{
int previousTriCount = pb.selectedVertexCount;
switch (ProBuilderEditor.selectMode)
{
case SelectMode.Vertex:
pb.SetSelectedEdges(ElementSelection.GetConnectedEdges(pb, pb.selectedIndexesInternal));
break;
case SelectMode.Edge:
pb.SetSelectedEdges(ElementSelection.GetConnectedEdges(pb, pb.selectedIndexesInternal));
break;
case SelectMode.TextureFace:
case SelectMode.Face:
Face[] selectedFaces = pb.GetSelectedFaces();
HashSet<Face> sel;
if (iterative)
{
sel = ElementSelection.GrowSelection(pb, selectedFaces, angleGrow ? growSelectionAngle : -1f);
sel.UnionWith(selectedFaces);
}
else
{
sel = ElementSelection.FloodSelection(pb, selectedFaces, angleGrow ? growSelectionAngle : -1f);
}
pb.SetSelectedFaces(sel.ToArray());
break;
}
grown += pb.selectedVertexCount - previousTriCount;
}
ProBuilderEditor.Refresh();
SceneView.RepaintAll();
if (grown > 0)
return new ActionResult(ActionResult.Status.Success, "Grow Selection");
return new ActionResult(ActionResult.Status.Failure, "Nothing to Grow");
}
static bool VerifyGrowSelection()
{
int sel, max;
switch (ProBuilderEditor.selectMode)
{
case SelectMode.Face:
sel = MeshSelection.selectedFaceCount;
max = MeshSelection.totalFaceCount;
break;
case SelectMode.Edge:
sel = MeshSelection.selectedEdgeCount;
max = MeshSelection.totalEdgeCount;
break;
default:
sel = MeshSelection.selectedVertexCount;
max = MeshSelection.totalVertexCount;
break;
}
return sel > 0 && sel < max;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 77b34bf9fb2a49f6a5d0d0117bcc4c46
timeCreated: 1457452380
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,138 @@
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.ProBuilder;
using UnityEngine.ProBuilder.MeshOperations;
namespace UnityEditor.ProBuilder.Actions
{
sealed class SelectEdgeLoop : MenuAction
{
Pref<bool> m_SelectIterative = new Pref<bool>("SelectEdgeLoop.selectIterative", false);
GUIContent gc_selectIterative = new GUIContent("Iterative Selection", "Optionally restrict the selection to neighbors edges on the loop.");
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => "Toolbar/Selection_Loop_Edge";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
public override int toolbarPriority
{
get { return 1; }
}
protected internal override bool hasFileMenuEntry
{
get { return false; }
}
private static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Select Edge Loop",
"Selects a loop of connected edges.\n\n<b>Shortcut</b>: Double-Click on Edge",
keyCommandAlt, 'L'
);
public override SelectMode validSelectModes
{
get { return SelectMode.Edge; }
}
protected override MenuActionState optionsMenuState
{
get {
if (enabled && ProBuilderEditor.selectMode == SelectMode.Edge)
return MenuActionState.VisibleAndEnabled;
return MenuActionState.Hidden;
}
}
public override bool enabled
{
get { return base.enabled && MeshSelection.selectedEdgeCount > 0; }
}
protected override ActionResult PerformActionImplementation()
{
if (MeshSelection.selectedObjectCount < 1)
return ActionResult.NoSelection;
UndoUtility.RecordSelection("Select Edge Loop");
bool foundLoop = false;
foreach (ProBuilderMesh pb in MeshSelection.topInternal)
{
Edge[] loop;
bool success = false;
if (m_SelectIterative)
success = ElementSelection.GetEdgeLoopIterative(pb, pb.selectedEdges, out loop);
else
success = ElementSelection.GetEdgeLoop(pb, pb.selectedEdges, out loop);
if (success)
{
if (loop.Length > pb.selectedEdgeCount)
foundLoop = true;
pb.SetSelectedEdges(loop);
}
}
ProBuilderEditor.Refresh();
SceneView.RepaintAll();
if (foundLoop)
return new ActionResult(ActionResult.Status.Success, "Select Edge Loop");
else
return new ActionResult(ActionResult.Status.Failure, "Nothing to Loop");
}
public override VisualElement CreateSettingsContent()
{
var root = new VisualElement();
var toggle = new Toggle(gc_selectIterative.text);
toggle.tooltip = gc_selectIterative.tooltip;
toggle.SetValueWithoutNotify(m_SelectIterative);
toggle.RegisterCallback<ChangeEvent<bool>>(evt =>
{
m_SelectIterative.SetValue(evt.newValue);
PreviewActionManager.UpdatePreview();
});
root.Add(toggle);
return root;
}
protected override void OnSettingsGUI()
{
GUILayout.Label("Select Loop Edge Options", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
m_SelectIterative.value = EditorGUILayout.Toggle(gc_selectIterative, m_SelectIterative);
if (EditorGUI.EndChangeCheck())
ProBuilderSettings.Save();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Select Edge Loop"))
{
PerformAction();
SceneView.RepaintAll();
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5f3c839e57094cf6b2e99af5515b2ca0
timeCreated: 1457452380
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,139 @@
using UnityEngine;
using System.Linq;
using UnityEngine.UIElements;
using UnityEngine.ProBuilder;
using UnityEngine.ProBuilder.MeshOperations;
namespace UnityEditor.ProBuilder.Actions
{
sealed class SelectEdgeRing : MenuAction
{
Pref<bool> m_SelectIterative = new Pref<bool>("SelectEdgeRing.selectIterative", false);
GUIContent gc_selectIterative = new GUIContent("Iterative Selection", "Optionally restrict the selection to neighbors edges on the ring.");
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => "Toolbar/Selection_Ring_Edge";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
public override int toolbarPriority
{
get { return 2; }
}
protected internal override bool hasFileMenuEntry
{
get { return false; }
}
protected override MenuActionState optionsMenuState
{
get {
if (enabled && ProBuilderEditor.selectMode == SelectMode.Edge)
return MenuActionState.VisibleAndEnabled;
return MenuActionState.Hidden;
}
}
private static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Select Edge Ring",
"Selects a ring of edges. Ringed edges are opposite the selected edge.\n\n<b>Shortcut</b>: Shift + Double-Click on Edge",
keyCommandAlt, 'R'
);
public override SelectMode validSelectModes
{
get { return SelectMode.Edge; }
}
public override bool enabled
{
get { return base.enabled && MeshSelection.selectedEdgeCount > 0; }
}
protected override ActionResult PerformActionImplementation()
{
if (MeshSelection.selectedObjectCount < 1)
return ActionResult.NoSelection;
UndoUtility.RecordSelection("Select Edge Ring");
bool success = false;
foreach (var mesh in MeshSelection.topInternal)
{
Edge[] edges;
if (m_SelectIterative)
{
edges = ElementSelection.GetEdgeRingIterative(mesh, mesh.selectedEdges).ToArray();
}
else
{
edges = ElementSelection.GetEdgeRing(mesh, mesh.selectedEdges).ToArray();
}
if (edges.Length > mesh.selectedEdgeCount)
success = true;
mesh.SetSelectedEdges(edges);
}
ProBuilderEditor.Refresh();
SceneView.RepaintAll();
if (success)
return new ActionResult(ActionResult.Status.Success, "Select Edge Ring");
return new ActionResult(ActionResult.Status.Failure, "Nothing to Ring");
}
public override VisualElement CreateSettingsContent()
{
var root = new VisualElement();
var toggle = new Toggle(gc_selectIterative.text);
toggle.tooltip = gc_selectIterative.tooltip;
toggle.SetValueWithoutNotify(m_SelectIterative);
toggle.RegisterCallback<ChangeEvent<bool>>(evt =>
{
m_SelectIterative.SetValue(evt.newValue);
PreviewActionManager.UpdatePreview();
});
root.Add(toggle);
return root;
}
protected override void OnSettingsGUI()
{
GUILayout.Label("Select Ring Edge Options", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
m_SelectIterative.value = EditorGUILayout.Toggle(gc_selectIterative, m_SelectIterative);
if (EditorGUI.EndChangeCheck())
ProBuilderSettings.Save();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Select Edge Ring"))
{
PerformAction();
SceneView.RepaintAll();
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a49dc64944b24efab4e8dda777a3211a
timeCreated: 1457452380
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,66 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.ProBuilder;
using UnityEngine.ProBuilder.MeshOperations;
namespace UnityEditor.ProBuilder.Actions
{
sealed class SelectFaceLoop : MenuAction
{
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => "Toolbar/Selection_Loop_Face";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
public override int toolbarPriority
{
get { return 1; }
}
protected internal override bool hasFileMenuEntry
{
get { return false; }
}
private static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Select Face Loop",
"Selects a loop of connected faces.\n\n<b>Shortcut</b>: Shift + Double Click on Face."
);
public override SelectMode validSelectModes
{
get { return SelectMode.Face | SelectMode.TextureFace; }
}
public override bool enabled
{
get { return base.enabled && MeshSelection.selectedFaceCount > 0; }
}
protected override ActionResult PerformActionImplementation()
{
var selection = MeshSelection.topInternal;
UndoUtility.RecordSelection("Select Face Loop");
foreach (ProBuilderMesh pb in selection)
{
HashSet<Face> loop = ElementSelection.GetFaceLoop(pb, pb.selectedFacesInternal);
pb.SetSelectedFaces(loop);
}
ProBuilderEditor.Refresh();
return new ActionResult(ActionResult.Status.Success, "Select Face Loop");
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: df1c6ba8c6074cd4872ff79d66cc49f5
timeCreated: 1508178490
@@ -0,0 +1,81 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.ProBuilder;
using UnityEngine.ProBuilder.MeshOperations;
namespace UnityEditor.ProBuilder.Actions
{
sealed class SelectFaceRing : MenuAction
{
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => "Toolbar/Selection_Ring_Face";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
public override int toolbarPriority
{
get { return 2; }
}
protected internal override bool hasFileMenuEntry
{
get { return false; }
}
private static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Select Face Ring",
"Selects a ring of connected faces.\n\n<b>Shortcut</b>: Control + Double Click on Face."
);
public override SelectMode validSelectModes
{
get { return SelectMode.Face | SelectMode.TextureFace; }
}
public override bool enabled
{
get { return base.enabled && MeshSelection.selectedFaceCount > 0; }
}
protected override ActionResult PerformActionImplementation()
{
var selection = MeshSelection.topInternal;
UndoUtility.RecordSelection("Select Face Ring");
foreach (ProBuilderMesh pb in selection)
{
HashSet<Face> loop = ElementSelection.GetFaceLoop(pb, pb.selectedFacesInternal, true);
pb.SetSelectedFaces(loop);
}
ProBuilderEditor.Refresh();
return new ActionResult(ActionResult.Status.Success, "Select Face Ring");
}
public static ActionResult MenuRingAndLoopFaces(IEnumerable<ProBuilderMesh> selection)
{
UndoUtility.RecordSelection(selection.ToArray(), "Select Face Ring and Loop");
foreach (ProBuilderMesh pb in selection)
{
HashSet<Face> loop = ElementSelection.GetFaceRingAndLoop(pb, pb.selectedFacesInternal);
pb.SetSelectedFaces(loop);
}
ProBuilderEditor.Refresh();
return new ActionResult(ActionResult.Status.Success, "Select Face Ring and Loop");
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8459d3ed1cc648cba5015df2ff4850cb
timeCreated: 1508178355
@@ -0,0 +1,63 @@
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
using UnityEngine.ProBuilder;
using UnityEngine.ProBuilder.MeshOperations;
namespace UnityEditor.ProBuilder.Actions
{
sealed class SelectHole : MenuAction
{
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => "Toolbar/Selection_SelectHole";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
private static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Select Hole",
"Selects holes on the mesh.\n\nUses the current element selection, or tests the whole mesh if no edges or vertices are selected."
);
public override SelectMode validSelectModes
{
get { return SelectMode.Vertex | SelectMode.Edge; }
}
public override bool enabled
{
get { return base.enabled && MeshSelection.selectedObjectCount > 0; }
}
protected override ActionResult PerformActionImplementation()
{
UndoUtility.RecordSelection("Select Hole");
ActionResult res = ActionResult.NoSelection;
foreach (ProBuilderMesh pb in MeshSelection.topInternal)
{
bool selectAll = pb.selectedIndexesInternal == null || pb.selectedIndexesInternal.Length < 1;
IEnumerable<int> indexes = selectAll ? pb.facesInternal.SelectMany(x => x.indexes) : pb.selectedIndexesInternal;
List<List<Edge>> holes = ElementSelection.FindHoles(pb, indexes);
res = new ActionResult(ActionResult.Status.Success, holes.Count > 0 ? string.Format("{0} holes found", holes.Count) : "No Holes in Selection");
pb.SetSelectedEdges(holes.SelectMany(x => x));
}
ProBuilderEditor.Refresh();
return res;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6f435ddc17924dd18782195e161766ae
timeCreated: 1467039697
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,74 @@
using UnityEngine;
using UnityEngine.ProBuilder;
namespace UnityEditor.ProBuilder.Actions
{
// Menu item entry
sealed class SelectLoop : MenuAction
{
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => string.Empty;
public override Texture2D icon => null;
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
public override int toolbarPriority
{
get { return 2; }
}
static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Select Loop",
"",
keyCommandAlt, 'L'
);
public override SelectMode validSelectModes
{
get { return SelectMode.Edge | SelectMode.Face | SelectMode.TextureFace; }
}
public override bool enabled
{
get
{
if (ProBuilderEditor.selectMode == SelectMode.Edge)
return EditorToolbarLoader.GetInstance<SelectEdgeLoop>().enabled;
else if (ProBuilderEditor.selectMode == SelectMode.Face)
return EditorToolbarLoader.GetInstance<SelectFaceLoop>().enabled;
else
return false;
}
}
protected override ActionResult PerformActionImplementation()
{
if (ProBuilderEditor.selectMode == SelectMode.Edge)
return EditorToolbarLoader.GetInstance<SelectEdgeLoop>().PerformAction();
else if (ProBuilderEditor.selectMode == SelectMode.Face)
return EditorToolbarLoader.GetInstance<SelectFaceLoop>().PerformAction();
return ActionResult.NoSelection;
}
internal override string GetMenuItemOverride()
{
return @" switch (ProBuilderEditor.selectMode)
{
case SelectMode.Edge:
EditorAction.Start(new MenuActionSettings(EditorToolbarLoader.GetInstance<SelectEdgeLoop>(), true));
break;
case SelectMode.Face:
EditorToolbarLoader.GetInstance<SelectFaceLoop>().PerformAction();
break;
}";
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 924ccbaae96a57b438f256c6e54c1df8
timeCreated: 1457452380
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,137 @@
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.ProBuilder;
using UnityEngine.UIElements;
namespace UnityEditor.ProBuilder.Actions
{
sealed class SelectMaterial : MenuAction
{
GUIContent gc_restrictToSelection = new GUIContent("Current Selection", "Optionally restrict the matches to only those faces on currently selected objects.");
internal Pref<bool> m_RestrictToSelectedObjects = new Pref<bool>("SelectMaterial.restrictToSelectedObjects", false, SettingsScope.Project);
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => "Toolbar/Selection_SelectByMaterial";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Select Material",
"Selects all faces matching the selected materials."
);
public override SelectMode validSelectModes
{
get { return SelectMode.Face | SelectMode.TextureFace; }
}
public override bool enabled
{
get { return base.enabled && MeshSelection.selectedFaceCount > 0; }
}
protected override MenuActionState optionsMenuState
{
get { return MenuActionState.VisibleAndEnabled; }
}
public override VisualElement CreateSettingsContent()
{
var root = new VisualElement();
var toggle = new Toggle(gc_restrictToSelection.text);
toggle.tooltip = gc_restrictToSelection.tooltip;
toggle.SetValueWithoutNotify(m_RestrictToSelectedObjects);
toggle.RegisterCallback<ChangeEvent<bool>>(evt =>
{
m_RestrictToSelectedObjects.SetValue(evt.newValue);
PreviewActionManager.UpdatePreview();
});
root.Add(toggle);
return root;
}
protected override void OnSettingsGUI()
{
GUILayout.Label("Select Material Options", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
m_RestrictToSelectedObjects.value = EditorGUILayout.Toggle(gc_restrictToSelection, m_RestrictToSelectedObjects);
if (EditorGUI.EndChangeCheck())
ProBuilderSettings.Save();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Select Faces with Material"))
{
PerformAction();
SceneView.RepaintAll();
}
}
protected override ActionResult PerformActionImplementation()
{
IEnumerable<ProBuilderMesh> selection;
if (m_RestrictToSelectedObjects)
selection = MeshSelection.topInternal;
else
selection = EditorUtility.FindObjectsByType<ProBuilderMesh>();
UndoUtility.RecordSelection("Select Faces with Material");
//Need to go from submesh index to material
HashSet<Material> selectedMaterials = new HashSet<Material>();
foreach(var pb in MeshSelection.topInternal)
{
HashSet<int> submeshIndex = new HashSet<int>(pb.selectedFacesInternal.Select(y => y.submeshIndex));
foreach (var index in submeshIndex)
{
selectedMaterials.Add(pb.renderer.sharedMaterials[index]);
}
}
List<GameObject> newSelection = new List<GameObject>();
foreach (var pb in selection)
{
List<int> subMeshIndices = new List<int>();
for (int matIndex = 0; matIndex < pb.renderer.sharedMaterials.Length; ++matIndex)
{
if(selectedMaterials.Contains(pb.renderer.sharedMaterials[matIndex]))
{
subMeshIndices.Add(matIndex);
}
}
if(subMeshIndices.Count > 0)
{
IEnumerable<Face> matches = pb.facesInternal.Where(x => subMeshIndices.Contains(x.submeshIndex));
if (matches.Any())
{
newSelection.Add(pb.gameObject);
pb.SetSelectedFaces(matches);
}
}
}
Selection.objects = newSelection.ToArray();
ProBuilderEditor.Refresh();
return new ActionResult(ActionResult.Status.Success, "Select Faces with Material");
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 51cb791f07b14fc08dd10dd56890d5c0
timeCreated: 1471368034
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,74 @@
using UnityEngine;
using UnityEngine.ProBuilder;
namespace UnityEditor.ProBuilder.Actions
{
// Menu item entry
sealed class SelectRing : MenuAction
{
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => string.Empty;
public override Texture2D icon => null;
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
public override int toolbarPriority
{
get { return 2; }
}
static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Select Ring",
"",
keyCommandAlt, 'R'
);
public override SelectMode validSelectModes
{
get { return SelectMode.Edge | SelectMode.Face | SelectMode.TextureFace; }
}
public override bool enabled
{
get
{
if (ProBuilderEditor.selectMode == SelectMode.Edge)
return EditorToolbarLoader.GetInstance<SelectEdgeRing>().enabled;
else if (ProBuilderEditor.selectMode == SelectMode.Face)
return EditorToolbarLoader.GetInstance<SelectFaceRing>().enabled;
else
return false;
}
}
protected override ActionResult PerformActionImplementation()
{
if (ProBuilderEditor.selectMode == SelectMode.Edge)
return EditorToolbarLoader.GetInstance<SelectEdgeRing>().PerformAction();
else if (ProBuilderEditor.selectMode == SelectMode.Face)
return EditorToolbarLoader.GetInstance<SelectFaceRing>().PerformAction();
return ActionResult.NoSelection;
}
internal override string GetMenuItemOverride()
{
return @" switch (ProBuilderEditor.selectMode)
{
case SelectMode.Edge:
EditorAction.Start(new MenuActionSettings(EditorToolbarLoader.GetInstance<SelectEdgeRing>(), true));
break;
case SelectMode.Face:
EditorToolbarLoader.GetInstance<SelectFaceRing>().PerformAction();
break;
}";
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8704e3cfa2526d34baf80d67fda2aa11
timeCreated: 1457452380
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,81 @@
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.ProBuilder;
namespace UnityEditor.ProBuilder.Actions
{
sealed class SelectSmoothingGroup : MenuAction
{
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => "Toolbar/Selection_SelectBySmoothingGroup";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Select Smoothing Group",
"Selects all faces matching the selected smoothing groups."
);
public override SelectMode validSelectModes
{
get { return SelectMode.Face | SelectMode.TextureFace; }
}
public override bool enabled
{
get { return base.enabled && MeshSelection.selectedFaceCount > 0; }
}
public override bool hidden
{
get { return true; }
}
protected override MenuActionState optionsMenuState
{
get
{
if (enabled && ProBuilderEditor.selectMode == SelectMode.Face)
return MenuActionState.VisibleAndEnabled;
return MenuActionState.Visible;
}
}
protected override ActionResult PerformActionImplementation()
{
UndoUtility.RecordSelection("Select Faces with Smoothing Group");
HashSet<int> selectedSmoothGroups = new HashSet<int>(MeshSelection.topInternal.SelectMany(x => x.selectedFacesInternal.Select(y => y.smoothingGroup)));
List<GameObject> newSelection = new List<GameObject>();
foreach (ProBuilderMesh pb in MeshSelection.topInternal)
{
IEnumerable<Face> matches = pb.facesInternal.Where(x => selectedSmoothGroups.Contains(x.smoothingGroup));
if (matches.Count() > 0)
{
newSelection.Add(pb.gameObject);
pb.SetSelectedFaces(matches);
}
}
Selection.objects = newSelection.ToArray();
ProBuilderEditor.Refresh();
return new ActionResult(ActionResult.Status.Success, "Select Faces with Smoothing Group");
}
}
}
@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: ffe60d522a0a4b0489a5bfe4bb6b4fb1
timeCreated: 1505081073
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,176 @@
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UIElements;
using UnityEngine.ProBuilder;
namespace UnityEditor.ProBuilder.Actions
{
sealed class SelectVertexColor : MenuAction
{
Pref<bool> m_SearchSelectedObjectsOnly = new Pref<bool>("SelectVertexColor.restrictToSelectedObjects", false);
GUIContent gc_restrictToSelection = new GUIContent("Current Selection", "Optionally restrict the matches to only those faces on currently selected objects.");
static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Select Vertex Color",
"Selects all faces matching the selected vertex colors."
);
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => "Toolbar/Selection_SelectByVertexColor";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
public override SelectMode validSelectModes
{
get { return SelectMode.Vertex | SelectMode.Edge | SelectMode.Face | SelectMode.TextureFace; }
}
public override bool enabled
{
get { return base.enabled && MeshSelection.selectedVertexCount > 0; }
}
protected override MenuActionState optionsMenuState
{
get
{
if (enabled)
return MenuActionState.VisibleAndEnabled;
return MenuActionState.Visible;
}
}
public override VisualElement CreateSettingsContent()
{
var root = new VisualElement();
var toggle = new Toggle(gc_restrictToSelection.text);
toggle.tooltip = gc_restrictToSelection.tooltip;
toggle.SetValueWithoutNotify(m_SearchSelectedObjectsOnly);
toggle.RegisterCallback<ChangeEvent<bool>>(evt =>
{
m_SearchSelectedObjectsOnly.SetValue(evt.newValue);
PreviewActionManager.UpdatePreview();
});
root.Add(toggle);
return root;
}
protected override void OnSettingsGUI()
{
GUILayout.Label("Select by Vertex Color Options", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
m_SearchSelectedObjectsOnly.value = EditorGUILayout.Toggle(gc_restrictToSelection, m_SearchSelectedObjectsOnly);
if (EditorGUI.EndChangeCheck())
ProBuilderSettings.Save();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Select Vertex Color"))
{
PerformAction();
SceneView.RepaintAll();
}
}
protected override ActionResult PerformActionImplementation()
{
UndoUtility.RecordSelection("Select Faces with Vertex Colors");
HashSet<Color32> colors = new HashSet<Color32>();
foreach (ProBuilderMesh pb in MeshSelection.topInternal)
{
Color[] mesh_colors = pb.colorsInternal;
if (mesh_colors == null || mesh_colors.Length != pb.vertexCount)
continue;
foreach (int i in pb.selectedIndexesInternal)
colors.Add(mesh_colors[i]);
}
List<GameObject> newSelection = new List<GameObject>();
bool selectionOnly = m_SearchSelectedObjectsOnly;
IEnumerable<ProBuilderMesh> pool;
if (selectionOnly)
pool = MeshSelection.topInternal;
else
pool = EditorUtility.FindObjectsByType<ProBuilderMesh>();
//If the original selection does not have colors assigned we will select faces without colors
if (colors.Count == 0)
{
foreach (ProBuilderMesh pb in pool)
{
if (pb.colorsInternal == null || pb.colorsInternal.Length < 1)
{
List<Face> matches = new List<Face>();
Face[] faces = pb.facesInternal;
matches.AddRange(faces);
if (matches.Count > 0)
{
newSelection.Add(pb.gameObject);
pb.SetSelectedFaces(matches);
}
}
}
}
else
{
foreach (ProBuilderMesh pb in pool)
{
Color[] mesh_colors = pb.colorsInternal;
if (mesh_colors == null || mesh_colors.Length != pb.vertexCount)
continue;
List<Face> matches = new List<Face>();
Face[] faces = pb.facesInternal;
for (int i = 0; i < faces.Length; i++)
{
int[] tris = faces[i].distinctIndexesInternal;
for (int n = 0; n < tris.Length; n++)
{
if (colors.Contains((Color32)mesh_colors[tris[n]]))
{
matches.Add(faces[i]);
break;
}
}
}
if (matches.Count > 0)
{
newSelection.Add(pb.gameObject);
pb.SetSelectedFaces(matches);
}
}
}
Selection.objects = newSelection.ToArray();
ProBuilderEditor.Refresh();
return new ActionResult(ActionResult.Status.Success, "Select Faces with Vertex Colors");
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: fdbc8889effe4c9e82971613ad25e182
timeCreated: 1471546412
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,116 @@
using System.Linq;
using UnityEngine.ProBuilder;
using UnityEngine;
using UnityEngine.ProBuilder.MeshOperations;
namespace UnityEditor.ProBuilder.Actions
{
sealed class ShrinkSelection : MenuAction
{
public override ToolbarGroup group
{
get { return ToolbarGroup.Selection; }
}
public override string iconPath => "Toolbar/Selection_Shrink";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip
{
get { return s_Tooltip; }
}
static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Shrink Selection",
@"Removes elements on the edge of the current selection.",
keyCommandAlt, keyCommandShift, 'G'
);
public override SelectMode validSelectModes
{
get { return SelectMode.Vertex | SelectMode.Edge | SelectMode.Face | SelectMode.TextureFace; }
}
public override bool enabled
{
get { return base.enabled && VerifyShrinkSelection(); }
}
protected override ActionResult PerformActionImplementation()
{
var selection = MeshSelection.topInternal;
var selectionCount = MeshSelection.selectedObjectCount;
UndoUtility.RecordSelection("Shrink Selection");
// find perimeter edges
int rc = 0;
for (int i = 0; i < selectionCount; i++)
{
ProBuilderMesh mesh = selection[i];
switch (ProBuilderEditor.selectMode)
{
case SelectMode.Edge:
{
int[] perimeter = ElementSelection.GetPerimeterEdges(mesh, mesh.selectedEdges);
mesh.SetSelectedEdges(mesh.selectedEdges.RemoveAt(perimeter));
rc += perimeter != null ? perimeter.Length : 0;
break;
}
case SelectMode.TextureFace:
case SelectMode.Face:
{
Face[] perimeter = ElementSelection.GetPerimeterFaces(mesh, mesh.selectedFacesInternal).ToArray();
mesh.SetSelectedFaces(mesh.selectedFacesInternal.Except(perimeter).ToArray());
rc += perimeter.Length;
break;
}
case SelectMode.Vertex:
{
var universalEdges = mesh.GetSharedVertexHandleEdges(mesh.facesInternal.SelectMany(x => x.edges)).ToArray();
int[] perimeter = ElementSelection.GetPerimeterVertices(mesh, mesh.selectedIndexesInternal, universalEdges);
mesh.SetSelectedVertices(mesh.selectedIndexesInternal.RemoveAt(perimeter));
rc += perimeter != null ? perimeter.Length : 0;
break;
}
}
}
ProBuilderEditor.Refresh();
if (rc > 0)
return new ActionResult(ActionResult.Status.Success, "Shrink Selection");
return new ActionResult(ActionResult.Status.Canceled, "Nothing to Shrink");
}
static bool VerifyShrinkSelection()
{
int sel, max;
switch (ProBuilderEditor.selectMode)
{
case SelectMode.Face:
sel = MeshSelection.selectedFaceCount;
max = MeshSelection.totalFaceCount;
break;
case SelectMode.Edge:
sel = MeshSelection.selectedEdgeCount;
max = MeshSelection.totalEdgeCount;
break;
default:
sel = MeshSelection.selectedVertexCount;
max = MeshSelection.totalVertexCount;
break;
}
return sel > 1 && sel < max;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a4bb8ac278d3433ca7313bb5f90a2c52
timeCreated: 1457452380
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: