Added player character and step in/out of dialogue in scene 101
This commit is contained in:
+61
@@ -0,0 +1,61 @@
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEngine;
|
||||
using UnityEngine.ProBuilder.MeshOperations;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class CenterPivot : MenuAction
|
||||
{
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Object; }
|
||||
}
|
||||
|
||||
public override string iconPath => "Toolbar/Pivot_CenterOnObject";
|
||||
public override Texture2D icon => IconUtility.GetIcon(iconPath);
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return s_Tooltip; }
|
||||
}
|
||||
|
||||
static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"Center Pivot",
|
||||
@"Set the pivot point of this object to the center of its bounds."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && MeshSelection.selectedObjectCount > 0; }
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
if (MeshSelection.selectedObjectCount < 1)
|
||||
return ActionResult.NoSelection;
|
||||
|
||||
Object[] objects = new Object[MeshSelection.selectedObjectCount * 2];
|
||||
|
||||
for (int i = 0, c = MeshSelection.selectedObjectCount; i < c; i++)
|
||||
{
|
||||
objects[i] = MeshSelection.topInternal[i];
|
||||
objects[i + c] = MeshSelection.topInternal[i].transform;
|
||||
}
|
||||
|
||||
UndoUtility.RegisterCompleteObjectUndo(objects, "Center Pivot");
|
||||
|
||||
foreach (var mesh in MeshSelection.topInternal)
|
||||
{
|
||||
TransformUtility.UnparentChildren(mesh.transform);
|
||||
mesh.CenterPivot(null);
|
||||
mesh.Optimize();
|
||||
TransformUtility.ReparentChildren(mesh.transform);
|
||||
}
|
||||
|
||||
ProBuilderEditor.Refresh();
|
||||
|
||||
return new ActionResult(ActionResult.Status.Success, "Center Pivot");
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 460d1e5b4c054bfc8d012b87f9960bb9
|
||||
timeCreated: 1461861662
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class ConformObjectNormals : MenuAction
|
||||
{
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Object; }
|
||||
}
|
||||
|
||||
public override string iconPath => "Toolbar/Object_ConformNormals";
|
||||
public override Texture2D icon => IconUtility.GetIcon(iconPath);
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return s_Tooltip; }
|
||||
}
|
||||
|
||||
public override string menuTitle
|
||||
{
|
||||
get { return "Conform Normals"; }
|
||||
}
|
||||
|
||||
static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"Conform Object Normals",
|
||||
@"Check the object for faces that are flipped in the opposite direction of most other faces, then reverses any dissenters."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && MeshSelection.selectedObjectCount > 0; }
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
UndoUtility.RecordSelection("Conform Object Normals");
|
||||
|
||||
ActionResult res = ActionResult.NoSelection;
|
||||
|
||||
foreach (ProBuilderMesh pb in MeshSelection.topInternal)
|
||||
{
|
||||
res = UnityEngine.ProBuilder.MeshOperations.SurfaceTopology.ConformNormals(pb, pb.faces);
|
||||
|
||||
pb.ToMesh();
|
||||
pb.Refresh();
|
||||
pb.Optimize();
|
||||
}
|
||||
|
||||
ProBuilderEditor.Refresh();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 916d519062254e79b6adc87200d2c142
|
||||
timeCreated: 1457563051
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class FlipObjectNormals : MenuAction
|
||||
{
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Object; }
|
||||
}
|
||||
public override string iconPath => "Toolbar/Object_FlipNormals";
|
||||
public override Texture2D icon => IconUtility.GetIcon(iconPath);
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return s_Tooltip; }
|
||||
}
|
||||
|
||||
public override string menuTitle
|
||||
{
|
||||
get { return "Flip Normals"; }
|
||||
}
|
||||
|
||||
static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"Flip Object Normals",
|
||||
@"Reverse the direction of all faces on the selected objects."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && MeshSelection.selectedObjectCount > 0; }
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
if (MeshSelection.selectedObjectCount < 1)
|
||||
return ActionResult.NoSelection;
|
||||
|
||||
UndoUtility.RecordSelection("Flip Object Normals");
|
||||
|
||||
foreach (ProBuilderMesh pb in MeshSelection.topInternal)
|
||||
{
|
||||
foreach (var face in pb.facesInternal)
|
||||
face.Reverse();
|
||||
pb.ToMesh();
|
||||
pb.Refresh();
|
||||
pb.Optimize();
|
||||
}
|
||||
|
||||
ProBuilderEditor.Refresh();
|
||||
return new ActionResult(ActionResult.Status.Success, "Flip Object Normals");
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: add8532bafe747b88ea53556bd2e74e8
|
||||
timeCreated: 1457563051
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class FreezeTransform : MenuAction
|
||||
{
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Object; }
|
||||
}
|
||||
public override string iconPath => "Toolbar/Pivot_FreezeTransform";
|
||||
public override Texture2D icon => IconUtility.GetIcon(iconPath);
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return s_Tooltip; }
|
||||
}
|
||||
|
||||
static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"Freeze Transform",
|
||||
@"Set the pivot point to world coordinates (0,0,0) and clear all Transform values while keeping the mesh in place."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && MeshSelection.selectedObjectCount > 0; }
|
||||
}
|
||||
|
||||
public bool ShouldFlipFaces(Vector3 scale)
|
||||
{
|
||||
var globalSign = Mathf.Sign(scale.x) * Mathf.Sign(scale.y) * Mathf.Sign(scale.z);
|
||||
return globalSign < 0;
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
if (MeshSelection.selectedObjectCount < 1)
|
||||
return ActionResult.NoSelection;
|
||||
|
||||
UndoUtility.RecordMeshAndTransformSelection("Freeze Transforms");
|
||||
|
||||
var selection = MeshSelection.topInternal;
|
||||
Vector3[][] positions = new Vector3[selection.Count][];
|
||||
|
||||
for (int i = 0, c = selection.Count; i < c; i++)
|
||||
positions[i] = selection[i].VerticesInWorldSpace();
|
||||
|
||||
for (int i = 0, c = selection.Count; i < c; i++)
|
||||
{
|
||||
ProBuilderMesh pb = selection[i];
|
||||
bool flipFaces = ShouldFlipFaces(pb.transform.localScale);
|
||||
|
||||
pb.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
pb.transform.localScale = Vector3.one;
|
||||
|
||||
foreach(Face face in pb.facesInternal)
|
||||
{
|
||||
face.manualUV = true;
|
||||
if(flipFaces)
|
||||
face.Reverse();
|
||||
}
|
||||
|
||||
pb.positions = positions[i];
|
||||
|
||||
pb.ToMesh();
|
||||
pb.Refresh();
|
||||
pb.Optimize();
|
||||
}
|
||||
|
||||
ProBuilderEditor.Refresh();
|
||||
SceneView.RepaintAll();
|
||||
|
||||
return new ActionResult(ActionResult.Status.Success, "Freeze Transforms");
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc6c734d87394ef99cf62171eb6fe416
|
||||
timeCreated: 1457563050
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class GenerateUV2 : MenuAction
|
||||
{
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Object; }
|
||||
}
|
||||
public override string iconPath => "Toolbar/Object_GenerateUV2";
|
||||
public override Texture2D icon => IconUtility.GetIcon(iconPath);
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return s_Tooltip; }
|
||||
}
|
||||
|
||||
protected internal override bool hasFileMenuEntry
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"Lightmap UVs",
|
||||
@"Generate Lightmap UVs for any meshes in the open scenes that are missing them."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
protected override MenuActionState optionsMenuState
|
||||
{
|
||||
get { return MenuActionState.VisibleAndEnabled; }
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
var res = Lightmapping.RebuildMissingLightmapUVs(EditorUtility.FindObjectsByType<ProBuilderMesh>(), true);
|
||||
|
||||
if (res < 1)
|
||||
return new ActionResult(ActionResult.Status.Success, "No Missing Lightmap UVs Found");
|
||||
|
||||
return new ActionResult(ActionResult.Status.Success, "Generate Lightmap UVs\n" +
|
||||
(res > 1 ? string.Format("for {0} objects", res) : "for 1 object"));
|
||||
}
|
||||
|
||||
protected override void DoAlternateAction()
|
||||
{
|
||||
EditorWindow.GetWindow<LightmapUVEditor>(true, "Lightmap UV Editor", true).position = LightmapUVEditor.desiredPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 752d48e9eaa76c54ba0ff161eff2a3f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEditor.ProBuilder;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ProBuilder.UI;
|
||||
using UnityEngine.ProBuilder.MeshOperations;
|
||||
using UnityEngine.ProBuilder.Shapes;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class MergeObjects : MenuAction
|
||||
{
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Object; }
|
||||
}
|
||||
public override string iconPath => "Toolbar/Object_Merge";
|
||||
public override Texture2D icon => IconUtility.GetIcon(iconPath);
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return s_Tooltip; }
|
||||
}
|
||||
|
||||
static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"Merge Objects",
|
||||
@"Merges all selected ProBuilder objects to a single mesh."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && MeshSelection.selectedObjectCount > 1 && MeshSelection.activeMesh != null; }
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
if (MeshSelection.selectedObjectCount < 2)
|
||||
return new ActionResult(ActionResult.Status.Canceled, "Must Select 2+ Objects");
|
||||
|
||||
DoMergeObjectsAction();
|
||||
return new ActionResult(ActionResult.Status.Success, "Merged Objects");
|
||||
}
|
||||
|
||||
internal List<ProBuilderMesh> DoMergeObjectsAction()
|
||||
{
|
||||
var selected = MeshSelection.top.ToArray();
|
||||
ProBuilderMesh currentMesh = MeshSelection.activeMesh;
|
||||
UndoUtility.RecordObject(currentMesh, "Merge Objects");
|
||||
List<ProBuilderMesh> res = CombineMeshes.Combine(MeshSelection.topInternal, currentMesh);
|
||||
|
||||
if (res != null)
|
||||
{
|
||||
foreach (var mesh in res)
|
||||
{
|
||||
mesh.Optimize();
|
||||
if (mesh != currentMesh)
|
||||
{
|
||||
mesh.gameObject.name = Selection.activeGameObject.name + "-Merged";
|
||||
UndoUtility.RegisterCreatedObjectUndo(mesh.gameObject, "Merge Objects");
|
||||
|
||||
Selection.objects = res.Select(x => x.gameObject).ToArray();
|
||||
}
|
||||
|
||||
// Remove PolyShape and ProBuilderShape components if any are present post-merge
|
||||
var polyShapeComp = mesh.gameObject.GetComponent<PolyShape>();
|
||||
if (polyShapeComp != null )
|
||||
UndoUtility.DestroyImmediate(polyShapeComp);
|
||||
|
||||
var proBuilderShape = mesh.gameObject.GetComponent<ProBuilderShape>();
|
||||
if (proBuilderShape != null )
|
||||
UndoUtility.DestroyImmediate(proBuilderShape);
|
||||
}
|
||||
|
||||
// Delete donor objects if they are not part of the result
|
||||
for (int i = 0; i < selected.Length; i++)
|
||||
{
|
||||
if (selected[i] != null && res.Contains(selected[i]) == false)
|
||||
UndoUtility.DestroyImmediate(selected[i].gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffab696c539c4041848596918dd4590f
|
||||
timeCreated: 1457563050
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEngine.ProBuilder.MeshOperations;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class MirrorObjects : MenuAction
|
||||
{
|
||||
Pref<MirrorSettings> m_MirrorAxes = new Pref<MirrorSettings>("MirrorObjects.mirrorAxes", MirrorSettings.X);
|
||||
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Object; }
|
||||
}
|
||||
public override string iconPath => "Toolbar/Object_Mirror";
|
||||
public override Texture2D icon => IconUtility.GetIcon(iconPath);
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return s_Tooltip; }
|
||||
}
|
||||
|
||||
[System.Flags]
|
||||
enum MirrorSettings
|
||||
{
|
||||
X = 0x1,
|
||||
Y = 0x2,
|
||||
Z = 0x4,
|
||||
Duplicate = 0x8
|
||||
}
|
||||
|
||||
static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"Mirror Objects",
|
||||
@"Mirroring objects will duplicate and flip objects on the specified axes."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && MeshSelection.selectedObjectCount > 0; }
|
||||
}
|
||||
|
||||
protected override MenuActionState optionsMenuState
|
||||
{
|
||||
get { return MenuActionState.VisibleAndEnabled; }
|
||||
}
|
||||
|
||||
public override VisualElement CreateSettingsContent()
|
||||
{
|
||||
var root = new VisualElement();
|
||||
|
||||
MirrorSettings scale = m_MirrorAxes;
|
||||
bool x = (scale & MirrorSettings.X) != 0;
|
||||
bool y = (scale & MirrorSettings.Y) != 0;
|
||||
bool z = (scale & MirrorSettings.Z) != 0;
|
||||
bool d = (scale & MirrorSettings.Duplicate) != 0;
|
||||
|
||||
var tooltip = "Mirror objects on the selected axes";
|
||||
var toggle = new Toggle("X");
|
||||
toggle.tooltip = tooltip;
|
||||
toggle.SetValueWithoutNotify(x);
|
||||
toggle.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
m_MirrorAxes.SetValue((evt.newValue ? MirrorSettings.X : 0) | m_MirrorAxes & MirrorSettings.Y | m_MirrorAxes & MirrorSettings.Z | m_MirrorAxes & MirrorSettings.Duplicate);
|
||||
PreviewActionManager.UpdatePreview();
|
||||
});
|
||||
root.Add(toggle);
|
||||
|
||||
toggle = new Toggle("Y");
|
||||
toggle.tooltip = tooltip;
|
||||
toggle.SetValueWithoutNotify(y);
|
||||
toggle.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
m_MirrorAxes.SetValue(m_MirrorAxes & MirrorSettings.X | (evt.newValue ? MirrorSettings.Y : 0) | m_MirrorAxes & MirrorSettings.Z | m_MirrorAxes & MirrorSettings.Duplicate);
|
||||
PreviewActionManager.UpdatePreview();
|
||||
});
|
||||
root.Add(toggle);
|
||||
|
||||
toggle = new Toggle("Z");
|
||||
toggle.tooltip = tooltip;
|
||||
toggle.SetValueWithoutNotify(z);
|
||||
toggle.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
m_MirrorAxes.SetValue(m_MirrorAxes & MirrorSettings.X | m_MirrorAxes & MirrorSettings.Y | (evt.newValue ? MirrorSettings.Z : 0) | m_MirrorAxes & MirrorSettings.Duplicate);
|
||||
PreviewActionManager.UpdatePreview();
|
||||
});
|
||||
root.Add(toggle);
|
||||
|
||||
toggle = new Toggle("Duplicate");
|
||||
toggle.tooltip = "If Duplicate is toggled a new object will be instantiated from the selection and mirrored, or if disabled the selection will be moved.";
|
||||
toggle.SetValueWithoutNotify(d);
|
||||
toggle.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
m_MirrorAxes.SetValue(m_MirrorAxes & MirrorSettings.X | m_MirrorAxes & MirrorSettings.Y | m_MirrorAxes & MirrorSettings.Z | (evt.newValue ? MirrorSettings.Duplicate : 0));
|
||||
PreviewActionManager.UpdatePreview();
|
||||
});
|
||||
root.Add(toggle);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
protected override void OnSettingsGUI()
|
||||
{
|
||||
GUILayout.Label("Mirror Settings", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.HelpBox("Mirror objects on the selected axes.\n\nIf Duplicate is toggled a new object will be instantiated from the selection and mirrored, or if disabled the selection will be moved.", MessageType.Info);
|
||||
|
||||
MirrorSettings scale = m_MirrorAxes;
|
||||
|
||||
bool x = (scale & MirrorSettings.X) != 0;
|
||||
bool y = (scale & MirrorSettings.Y) != 0;
|
||||
bool z = (scale & MirrorSettings.Z) != 0;
|
||||
bool d = (scale & MirrorSettings.Duplicate) != 0;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
x = EditorGUILayout.Toggle("X", x);
|
||||
y = EditorGUILayout.Toggle("Y", y);
|
||||
z = EditorGUILayout.Toggle("Z", z);
|
||||
d = EditorGUILayout.Toggle("Duplicate", d);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
m_MirrorAxes.SetValue((MirrorSettings)
|
||||
(x ? MirrorSettings.X : 0) |
|
||||
(y ? MirrorSettings.Y : 0) |
|
||||
(z ? MirrorSettings.Z : 0) |
|
||||
(d ? MirrorSettings.Duplicate : 0));
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button("Mirror"))
|
||||
EditorUtility.ShowNotification(PerformAction().notification);
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
Vector3 scale = new Vector3(
|
||||
(m_MirrorAxes & MirrorSettings.X) > 0 ? -1f : 1f,
|
||||
(m_MirrorAxes & MirrorSettings.Y) > 0 ? -1f : 1f,
|
||||
(m_MirrorAxes & MirrorSettings.Z) > 0 ? -1f : 1f);
|
||||
|
||||
bool duplicate = (m_MirrorAxes & MirrorSettings.Duplicate) != 0;
|
||||
List<GameObject> res = new List<GameObject>();
|
||||
|
||||
foreach (ProBuilderMesh pb in MeshSelection.topInternal)
|
||||
res.Add(Mirror(pb, scale, duplicate).gameObject);
|
||||
|
||||
MeshSelection.SetSelection(res);
|
||||
PreviewActionManager.selectionUpdateDisabled = true;
|
||||
ProBuilderEditor.Refresh();
|
||||
|
||||
return res.Count > 0 ?
|
||||
new ActionResult(ActionResult.Status.Success, string.Format("Mirror {0} {1}", res.Count, res.Count > 1 ? "Objects" : "Object")) :
|
||||
new ActionResult(ActionResult.Status.NoChange, "No Objects Selected");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Duplicates and mirrors the passed pb_Object.
|
||||
* @param pb The donor pb_Object.
|
||||
* @param axe The axis to mirror the object on.
|
||||
* \returns The newly duplicated pb_Object.
|
||||
* \sa ProBuilder.Axis
|
||||
*/
|
||||
public static ProBuilderMesh Mirror(ProBuilderMesh pb, Vector3 scale, bool duplicate = true)
|
||||
{
|
||||
ProBuilderMesh mirroredObject;
|
||||
|
||||
if (duplicate)
|
||||
{
|
||||
mirroredObject = Object.Instantiate(pb.gameObject, pb.transform.parent, false).GetComponent<ProBuilderMesh>();
|
||||
mirroredObject.MakeUnique();
|
||||
mirroredObject.transform.parent = pb.transform.parent;
|
||||
mirroredObject.transform.localRotation = pb.transform.localRotation;
|
||||
Undo.RegisterCreatedObjectUndo(mirroredObject.gameObject, "Mirror Object");
|
||||
}
|
||||
else
|
||||
{
|
||||
UndoUtility.RecordObject(pb, "Mirror");
|
||||
mirroredObject = pb;
|
||||
}
|
||||
|
||||
Vector3 lScale = mirroredObject.gameObject.transform.localScale;
|
||||
mirroredObject.transform.localScale = scale;
|
||||
|
||||
// if flipping on an odd number of axes, flip winding order
|
||||
if ((scale.x * scale.y * scale.z) < 0)
|
||||
{
|
||||
foreach (var face in mirroredObject.facesInternal)
|
||||
face.Reverse();
|
||||
}
|
||||
|
||||
mirroredObject.FreezeScaleTransform();
|
||||
mirroredObject.transform.localScale = lScale;
|
||||
|
||||
mirroredObject.ToMesh();
|
||||
mirroredObject.Refresh();
|
||||
mirroredObject.Optimize();
|
||||
|
||||
return mirroredObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5cf10ee5e4b44eaca6e769bf235f7f5a
|
||||
timeCreated: 1470064051
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+294
@@ -0,0 +1,294 @@
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEngine.ProBuilder.MeshOperations;
|
||||
using UnityEditor.Actions;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class ProBuilderize : MenuAction
|
||||
{
|
||||
bool m_Enabled;
|
||||
Pref<bool> m_Quads = new Pref<bool>("meshImporter.quads", true);
|
||||
Pref<bool> m_Smoothing = new Pref<bool>("meshImporter.smoothing", true);
|
||||
Pref<float> m_SmoothingAngle = new Pref<float>("meshImporter.smoothingAngle", 1f);
|
||||
|
||||
public ProBuilderize()
|
||||
{
|
||||
MeshSelection.objectSelectionChanged += OnObjectSelectionChanged;
|
||||
|
||||
OnObjectSelectionChanged(); // invoke once as we might already have a selection in Hierarchy
|
||||
}
|
||||
|
||||
private void OnObjectSelectionChanged()
|
||||
{
|
||||
// can't just check if any MeshFilter is present because we need to know whether or not it's already a
|
||||
// probuilder mesh
|
||||
int meshCount = Selection.transforms.SelectMany(x => x.GetComponentsInChildren<MeshFilter>()).Count();
|
||||
m_Enabled = meshCount > 0 && meshCount != MeshSelection.selectedObjectCount;
|
||||
}
|
||||
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Object; }
|
||||
}
|
||||
public override string iconPath => "Toolbar/Object_ProBuilderize";
|
||||
public override Texture2D icon => IconUtility.GetIcon(iconPath);
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return s_Tooltip; }
|
||||
}
|
||||
|
||||
GUIContent m_QuadsTooltip = new GUIContent("Import Quads", "Create ProBuilder mesh using quads where " +
|
||||
"possible instead of triangles.");
|
||||
GUIContent m_SmoothingTooltip = new GUIContent("Import Smoothing", "Import smoothing groups by " +
|
||||
"testing adjacent faces against an angle threshold.");
|
||||
GUIContent m_SmoothingThresholdTooltip = new GUIContent("Smoothing Threshold", "When importing " +
|
||||
"smoothing groups any adjacent faces with an adjoining angle difference of less than this value will be " +
|
||||
"grouped together in a smoothing group.");
|
||||
|
||||
private static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"ProBuilderize",
|
||||
@"Creates ProBuilder-modifiable objects from meshes."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && m_Enabled; }
|
||||
}
|
||||
|
||||
protected override MenuActionState optionsMenuState
|
||||
{
|
||||
get { return MenuActionState.VisibleAndEnabled; }
|
||||
}
|
||||
|
||||
// This boolean allows to call the action only once in case of multi-selection as PB actions
|
||||
// are called on the entire selection and not per element.
|
||||
static bool s_ActionAlreadyTriggered = false;
|
||||
|
||||
[InitializeOnEnterPlayMode]
|
||||
static void ResetStaticsOnLoad()
|
||||
{
|
||||
s_ActionAlreadyTriggered = false;
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/MeshFilter/ProBuilderize", true, 11)]
|
||||
static bool ProBuilderizeMeshAction_Validate(MenuCommand command)
|
||||
{
|
||||
return !MenuActionSettings.IsCurrentAction(new ProBuilderize());
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/MeshFilter/ProBuilderize", false, 11)]
|
||||
static void ProBuilderizeMeshAction(MenuCommand command)
|
||||
{
|
||||
if (!s_ActionAlreadyTriggered)
|
||||
{
|
||||
var filter = (MeshFilter)command.context;
|
||||
//Check if we are not trying to Probuilderize a PB mesh
|
||||
if (filter.GetComponent<ProBuilderMesh>() != null)
|
||||
return;
|
||||
|
||||
s_ActionAlreadyTriggered = true;
|
||||
//Once again, delayCall is necessary to prevent multiple call in case of multi-selection
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
EditorAction.Start(new MenuActionSettings(new ProBuilderize()));
|
||||
s_ActionAlreadyTriggered = false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public override VisualElement CreateSettingsContent()
|
||||
{
|
||||
var root = new VisualElement();
|
||||
|
||||
var quadsToggle = new Toggle(m_QuadsTooltip.text);
|
||||
quadsToggle.tooltip = m_QuadsTooltip.tooltip;
|
||||
quadsToggle.SetValueWithoutNotify(m_Quads);
|
||||
root.Add(quadsToggle);
|
||||
|
||||
var smoothingToggle = new Toggle(m_SmoothingTooltip.text);
|
||||
smoothingToggle.tooltip = m_SmoothingTooltip.tooltip;
|
||||
smoothingToggle.SetValueWithoutNotify(m_Smoothing);
|
||||
root.Add(smoothingToggle);
|
||||
|
||||
var line = new VisualElement();
|
||||
line.style.flexDirection = FlexDirection.Row;
|
||||
root.Add(line);
|
||||
|
||||
var smoothingSlider = new Slider(m_SmoothingThresholdTooltip.text, 0.0001f, 45f);
|
||||
smoothingSlider.tooltip = m_SmoothingThresholdTooltip.tooltip;
|
||||
smoothingSlider.SetValueWithoutNotify(m_SmoothingAngle);
|
||||
smoothingSlider.style.flexGrow = 1;
|
||||
smoothingSlider.SetEnabled(m_Smoothing);
|
||||
line.Add(smoothingSlider);
|
||||
|
||||
var smoothingSliderValue = new FloatField();
|
||||
smoothingSliderValue.SetValueWithoutNotify(m_SmoothingAngle);
|
||||
smoothingSliderValue.isDelayed = true;
|
||||
smoothingSliderValue.style.width = 50;
|
||||
line.Add(smoothingSliderValue);
|
||||
|
||||
quadsToggle.RegisterCallback<ChangeEvent<bool>>(evt =>
|
||||
{
|
||||
m_Quads.SetValue(evt.newValue);
|
||||
});
|
||||
smoothingToggle.RegisterCallback<ChangeEvent<bool>>(evt =>
|
||||
{
|
||||
m_Smoothing.SetValue(evt.newValue);
|
||||
smoothingSlider.SetEnabled(m_Smoothing);
|
||||
});
|
||||
smoothingSlider.RegisterCallback<ChangeEvent<float>>(evt =>
|
||||
{
|
||||
m_SmoothingAngle.SetValue(evt.newValue);
|
||||
smoothingSliderValue.SetValueWithoutNotify(m_SmoothingAngle);
|
||||
});
|
||||
smoothingSliderValue.RegisterCallback<ChangeEvent<float>>(evt =>
|
||||
{
|
||||
m_SmoothingAngle.SetValue(evt.newValue);
|
||||
smoothingSlider.SetValueWithoutNotify(m_SmoothingAngle);
|
||||
});
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
protected override void OnSettingsGUI()
|
||||
{
|
||||
GUILayout.Label("ProBuilderize Options", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.HelpBox("When Preserve Faces is enabled ProBuilder will try to group adjacent triangles into faces.", MessageType.Info);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
m_Quads.value = EditorGUILayout.Toggle(m_QuadsTooltip, m_Quads);
|
||||
m_Smoothing.value = EditorGUILayout.Toggle(m_SmoothingTooltip, m_Smoothing);
|
||||
GUI.enabled = m_Smoothing;
|
||||
EditorGUILayout.PrefixLabel(m_SmoothingThresholdTooltip);
|
||||
m_SmoothingAngle.value = EditorGUILayout.Slider(m_SmoothingAngle, 0.0001f, 45f);
|
||||
|
||||
GUI.enabled = true;
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
ProBuilderSettings.Save();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUI.enabled = enabled;
|
||||
|
||||
if (GUILayout.Button("ProBuilderize"))
|
||||
EditorUtility.ShowNotification(PerformAction().notification);
|
||||
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
IEnumerable<MeshFilter> top = Selection.transforms.Select(x => x.GetComponent<MeshFilter>()).Where(y => y != null);
|
||||
IEnumerable<MeshFilter> all = Selection.gameObjects.SelectMany(x => x.GetComponentsInChildren<MeshFilter>()).Where(x => x != null);
|
||||
|
||||
MeshImportSettings settings = new MeshImportSettings()
|
||||
{
|
||||
quads = m_Quads,
|
||||
smoothing = m_Smoothing,
|
||||
smoothingAngle = m_SmoothingAngle
|
||||
};
|
||||
|
||||
if (top.Count() != all.Count())
|
||||
{
|
||||
int result = UnityEditor.EditorUtility.DisplayDialogComplex("ProBuilderize Selection",
|
||||
"ProBuilderize children of selection?",
|
||||
"Yes",
|
||||
"No",
|
||||
"Cancel");
|
||||
|
||||
if (result == 0)
|
||||
return DoProBuilderize(all, settings);
|
||||
else if (result == 1)
|
||||
return DoProBuilderize(top, settings);
|
||||
else
|
||||
return ActionResult.UserCanceled;
|
||||
}
|
||||
|
||||
return DoProBuilderize(all, settings);
|
||||
}
|
||||
|
||||
[System.Obsolete("Please use DoProBuilderize(IEnumerable<MeshFilter>, pb_MeshImporter.Settings")]
|
||||
public static ActionResult DoProBuilderize(
|
||||
IEnumerable<MeshFilter> selected,
|
||||
bool preserveFaces)
|
||||
{
|
||||
return DoProBuilderize(selected, new MeshImportSettings()
|
||||
{
|
||||
quads = preserveFaces,
|
||||
smoothing = false,
|
||||
smoothingAngle = 1f
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds pb_Object component without duplicating the objcet. Is undo-able.
|
||||
/// </summary>
|
||||
/// <param name="selected"></param>
|
||||
/// <param name="settings"></param>
|
||||
/// <returns></returns>
|
||||
public static ActionResult DoProBuilderize(
|
||||
IEnumerable<MeshFilter> selected,
|
||||
MeshImportSettings settings)
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
float count = selected.Count();
|
||||
|
||||
// Return immediately from the action so that the GUI can resolve. Displaying a progress bar interrupts the
|
||||
// event loop causing a layoutting error.
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
foreach (var mf in selected)
|
||||
{
|
||||
if (mf.sharedMesh == null)
|
||||
continue;
|
||||
|
||||
GameObject go = mf.gameObject;
|
||||
var renderer = go.GetComponent<MeshRenderer>();
|
||||
if (renderer.isPartOfStaticBatch)
|
||||
{
|
||||
Debug.LogError($"Probuilderize is not supported for renderers that have `IsPartOfStaticBatch` set.\n{go.name} will not probuilderize.");
|
||||
continue;
|
||||
}
|
||||
Mesh sourceMesh = mf.sharedMesh;
|
||||
Material[] sourceMaterials = go.GetComponent<MeshRenderer>()?.sharedMaterials;
|
||||
|
||||
try
|
||||
{
|
||||
var destination = Undo.AddComponent<ProBuilderMesh>(go);
|
||||
var meshImporter = new MeshImporter(sourceMesh, sourceMaterials, destination);
|
||||
meshImporter.Import(settings);
|
||||
|
||||
destination.Rebuild();
|
||||
destination.Optimize();
|
||||
|
||||
i++;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogWarning("Failed ProBuilderizing: " + go.name + "\n" + e.ToString());
|
||||
}
|
||||
|
||||
UnityEditor.EditorUtility.DisplayProgressBar("ProBuilderizing", mf.gameObject.name, i / count);
|
||||
}
|
||||
|
||||
UnityEditor.EditorUtility.ClearProgressBar();
|
||||
MeshSelection.OnObjectSelectionChanged();
|
||||
ProBuilderEditor.Refresh();
|
||||
};
|
||||
|
||||
if (i < 1)
|
||||
return new ActionResult(ActionResult.Status.Canceled, "Nothing Selected");
|
||||
return new ActionResult(ActionResult.Status.Success, "ProBuilderize " + i + (i > 1 ? " Objects" : " Object").ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0b5cffbc2ad41cb84067b39dedada94
|
||||
timeCreated: 1471369223
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class SetCollider : MenuAction
|
||||
{
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Entity; }
|
||||
}
|
||||
|
||||
public override string iconPath => string.Empty;
|
||||
public override Texture2D icon => null;
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return s_Tooltip; }
|
||||
}
|
||||
|
||||
static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"Set Collider",
|
||||
"Apply the Collider material and adds a mesh collider (if no collider is present). The MeshRenderer will be automatically turned off on entering play mode."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && MeshSelection.selectedObjectCount > 0; }
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
foreach (ProBuilderMesh pb in MeshSelection.topInternal)
|
||||
{
|
||||
var existing = pb.GetComponents<EntityBehaviour>();
|
||||
|
||||
// For now just nuke any existing entity types (since there are only two). In the future we should be
|
||||
// smarter about conflicting entity types.
|
||||
for (int i = 0, c = existing.Length; i < c; i++)
|
||||
Undo.DestroyObjectImmediate(existing[i]);
|
||||
|
||||
if (pb.TryGetComponent<Entity>(out var entity))
|
||||
Undo.DestroyObjectImmediate(entity);
|
||||
|
||||
if (!pb.GetComponent<Collider>())
|
||||
Undo.AddComponent<MeshCollider>(pb.gameObject);
|
||||
|
||||
if (!pb.GetComponent<Renderer>())
|
||||
Undo.AddComponent<MeshRenderer>(pb.gameObject);
|
||||
|
||||
UndoUtility.RegisterCompleteObjectUndo(pb, "Set Collider");
|
||||
|
||||
Undo.AddComponent<ColliderBehaviour>(pb.gameObject).Initialize();
|
||||
}
|
||||
|
||||
int selectionCount = MeshSelection.selectedObjectCount;
|
||||
|
||||
if (selectionCount < 1)
|
||||
return new ActionResult(ActionResult.Status.NoChange, "Set Collider\nNo objects selected");
|
||||
|
||||
return new ActionResult(ActionResult.Status.Success, "Set Collider\nSet " + selectionCount + " Objects");
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1376ed33245911e48ab91c560798f510
|
||||
timeCreated: 1457563050
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEditor.ProBuilder;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class SetTrigger : MenuAction
|
||||
{
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Entity; }
|
||||
}
|
||||
|
||||
public override string iconPath => string.Empty;
|
||||
public override Texture2D icon => null;
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return _tooltip; }
|
||||
}
|
||||
|
||||
static readonly TooltipContent _tooltip = new TooltipContent
|
||||
(
|
||||
"Set Trigger",
|
||||
"Apply the Trigger material and adds a collider marked as a trigger. The MeshRenderer will be automatically turned off on entering play mode."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && MeshSelection.selectedObjectCount > 0; }
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
foreach (ProBuilderMesh pb in MeshSelection.topInternal)
|
||||
{
|
||||
var existing = pb.GetComponents<EntityBehaviour>();
|
||||
|
||||
// For now just nuke any existing entity types (since there are only two). In the future we should be
|
||||
// smarter about conflicting entity types.
|
||||
for (int i = 0, c = existing.Length; i < c; i++)
|
||||
Undo.DestroyObjectImmediate(existing[i]);
|
||||
|
||||
if (pb.TryGetComponent<Entity>(out var entity))
|
||||
Undo.DestroyObjectImmediate(entity);
|
||||
|
||||
if (!pb.GetComponent<Collider>())
|
||||
Undo.AddComponent<MeshCollider>(pb.gameObject);
|
||||
|
||||
if (!pb.GetComponent<Renderer>())
|
||||
Undo.AddComponent<MeshRenderer>(pb.gameObject);
|
||||
|
||||
UndoUtility.RegisterCompleteObjectUndo(pb, "Set Trigger");
|
||||
|
||||
Undo.AddComponent<TriggerBehaviour>(pb.gameObject).Initialize();
|
||||
}
|
||||
|
||||
int selectionCount = MeshSelection.selectedObjectCount;
|
||||
if (selectionCount < 1)
|
||||
return new ActionResult(ActionResult.Status.NoChange, "Set Trigger\nNo objects selected");
|
||||
|
||||
return new ActionResult(ActionResult.Status.Success, "Set Trigger\nSet " + selectionCount + " Objects");
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ce00895d9eb2924f8f0c484eb3879ce
|
||||
timeCreated: 1457563050
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEngine.ProBuilder.MeshOperations;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class SubdivideObject : MenuAction
|
||||
{
|
||||
public override ToolbarGroup group
|
||||
{
|
||||
get { return ToolbarGroup.Object; }
|
||||
}
|
||||
public override string iconPath => "Toolbar/Object_Subdivide";
|
||||
public override Texture2D icon => IconUtility.GetIcon(iconPath);
|
||||
|
||||
public override TooltipContent tooltip
|
||||
{
|
||||
get { return s_Tooltip; }
|
||||
}
|
||||
|
||||
static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"Subdivide Object",
|
||||
"Increase the number of edges and vertices on this object by creating 4 new quads in every face."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && MeshSelection.selectedObjectCount > 0; }
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
if (MeshSelection.selectedObjectCount < 1)
|
||||
return ActionResult.NoSelection;
|
||||
|
||||
UndoUtility.RecordSelection("Subdivide Selection");
|
||||
|
||||
int success = 0;
|
||||
|
||||
foreach (ProBuilderMesh pb in MeshSelection.topInternal)
|
||||
{
|
||||
pb.ToMesh();
|
||||
|
||||
if (pb.Subdivide())
|
||||
success++;
|
||||
else
|
||||
Debug.LogError($"Subidivision of [{pb.name}] failed, complex concave objects are not supported");
|
||||
|
||||
pb.Refresh();
|
||||
pb.Optimize();
|
||||
|
||||
pb.SetSelectedVertices(new int[0]);
|
||||
}
|
||||
|
||||
ProBuilderEditor.Refresh();
|
||||
return new ActionResult(ActionResult.Status.Success, "Subdivide " + success + " Objects");
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6f7622c6d6346cca3539de7b00556a7
|
||||
timeCreated: 1457563050
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
using UnityEngine.ProBuilder;
|
||||
using UnityEngine;
|
||||
using UnityEngine.ProBuilder.MeshOperations;
|
||||
|
||||
namespace UnityEditor.ProBuilder.Actions
|
||||
{
|
||||
sealed class TriangulateObject : MenuAction
|
||||
{
|
||||
public override ToolbarGroup group { get { return ToolbarGroup.Object; } }
|
||||
public override string iconPath => "Toolbar/Object_Triangulate";
|
||||
public override Texture2D icon => IconUtility.GetIcon(iconPath);
|
||||
public override TooltipContent tooltip { get { return s_Tooltip; } }
|
||||
public override string menuTitle { get { return "Triangulate"; } }
|
||||
|
||||
static readonly TooltipContent s_Tooltip = new TooltipContent
|
||||
(
|
||||
"Triangulate Objects",
|
||||
@"Removes all quads and n-gons on the mesh and inserts triangles instead. Use this and a hard smoothing group to achieve a low-poly facetized look."
|
||||
);
|
||||
|
||||
public override bool enabled
|
||||
{
|
||||
get { return base.enabled && MeshSelection.selectedObjectCount > 0; }
|
||||
}
|
||||
|
||||
protected override ActionResult PerformActionImplementation()
|
||||
{
|
||||
if (MeshSelection.selectedObjectCount < 1)
|
||||
return ActionResult.NoSelection;
|
||||
|
||||
UndoUtility.RecordSelection("Triangulate Objects");
|
||||
|
||||
foreach (var mesh in MeshSelection.topInternal)
|
||||
{
|
||||
mesh.ToMesh();
|
||||
mesh.ToTriangles(mesh.facesInternal);
|
||||
mesh.Refresh();
|
||||
mesh.Optimize();
|
||||
mesh.ClearSelection();
|
||||
}
|
||||
|
||||
ProBuilderEditor.Refresh();
|
||||
|
||||
var c = MeshSelection.selectedObjectCount;
|
||||
return new ActionResult(ActionResult.Status.Success, "Triangulate " + c + (c > 1 ? " Objects" : " Object"));
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3983d7c6b954ee69e23e75009a8b81d
|
||||
timeCreated: 1457563051
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user