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,238 @@
using System;
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
using UnityEngine.ProBuilder.Stl;
using UnityEngine.ProBuilder;
using Object = UnityEngine.Object;
namespace UnityEditor.ProBuilder.Actions
{
sealed class Export : MenuAction
{
public override ToolbarGroup group { get { return ToolbarGroup.Object; } }
public override string iconPath => "Toolbar/Object_Export";
public override Texture2D icon => IconUtility.GetIcon(iconPath);
public override TooltipContent tooltip { get { return m_Tooltip; } }
protected override internal bool hasFileMenuEntry { get { return false; } }
GUIContent gc_ExportFormat = new GUIContent("Export Format", "The type of file to export the current selection as.");
GUIContent gc_ExportRecursive = new GUIContent("Include Children", "Should the exporter include children of the current selection when searching for meshes to export?");
GUIContent gc_ObjExportRightHanded = new GUIContent("Right Handed", "Unity coordinate space is left handed, where most other major 3D modeling softwares are right handed. Usually this option should be left enabled.");
GUIContent gc_ExportAsGroup = new GUIContent("Export As Group", "If enabled all selected meshes will be combined to a single model. If not, each mesh will be exported individually.");
GUIContent gc_ObjApplyTransform = new GUIContent("Apply Transforms", "If enabled each mesh will have it's Transform applied prior to export. This is useful when you want to retain the correct placement of objects when re-importing to Unity (just set the imported mesh to { 0, 0, 0 }). If not enabled meshes are exported in local space.");
GUIContent gc_ObjExportCopyTextures = new GUIContent("Copy Textures", "With Copy Textures enabled the exporter will copy material textures to the destination directory. If false the material library will point to the texture path within the Unity project. If you're exporting models with the intention of editing in an external 3D modeler then re-importing, disable this option to avoid duplicate textures in your project.");
GUIContent gc_ObjExportVertexColors = new GUIContent("Vertex Colors", "Some 3D modeling applications will read and write vertex colors as an unofficial extension to the OBJ format.\n\nWarning! Enabling this can break compatibility with some other 3D modeling applications.");
GUIContent gc_ObjTextureOffsetScale = new GUIContent("Texture Offset, Scale", "Write texture map offset and scale to the material library. Not all 3D modeling applications support this specificiation, and some will fail to load materials that define these values.");
GUIContent gc_ObjQuads = new GUIContent("Export Quads", "Where possible, faces will be exported as quads instead of triangles. Note that this can result in a larger exported mesh (ProBuilder will not merge shared vertices with this option enabled).");
GUIContent gc_ExportAssetInPlace = new GUIContent("Replace Source", "Remove the ProBuilder component and replace the MeshFilter mesh with the exported asset.");
Pref<ExportFormat> m_ExportFormat = new Pref<ExportFormat>("export.format", k_DefaultFormat);
Pref<bool> m_ExportRecursive = new Pref<bool>("export.exportRecursive", false);
Pref<bool> m_ExportAsGroup = new Pref<bool>("export.exportAsGroup", false);
// obj specific
Pref<bool> m_ObjExportRightHanded = new Pref<bool>("export.objExportRightHanded", true);
Pref<bool> m_ObjExportCopyTextures = new Pref<bool>("export.objExportCopyTextures", true);
Pref<bool> m_ObjApplyTransform = new Pref<bool>("export.objApplyTransform", false);
Pref<bool> m_ObjExportVertexColors = new Pref<bool>("export.objExportVertexColors", false);
Pref<bool> m_ObjTextureOffsetScale = new Pref<bool>("export.objTextureOffsetScale", false);
Pref<bool> m_ObjQuads = new Pref<bool>("export.objQuads", true);
// stl specific
Pref<FileType> m_StlExportFormat = new Pref<FileType>("export.stlExportFormat", FileType.Ascii);
// ply specific
Pref<bool> m_PlyExportIsRightHanded = new Pref<bool>("export.plyExportIsRightHanded", true);
Pref<bool> m_PlyApplyTransform = new Pref<bool>("export.plyApplyTransform", true);
Pref<bool> m_PlyQuads = new Pref<bool>("export.plyQuads", true);
Pref<bool> m_PlyNGons = new Pref<bool>("export.plyNGons", false);
public enum ExportFormat
{
Obj,
Stl,
Ply,
Asset,
Prefab
}
const ExportFormat k_DefaultFormat = ExportFormat.Obj;
static readonly TooltipContent m_Tooltip = new TooltipContent
(
"Export",
"Export the selected ProBuilder objects as a model file."
);
public override bool hidden
{
get { return false; }
}
public override bool enabled
{
get { return MeshSelection.selectedObjectCount > 0; }
}
protected override MenuActionState optionsMenuState
{
get { return MenuActionState.VisibleAndEnabled; }
}
protected override void OnSettingsGUI()
{
GUILayout.Label("Export Settings", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
EditorGUI.BeginChangeCheck();
m_ExportFormat.value = (ExportFormat)EditorGUILayout.EnumPopup(gc_ExportFormat, m_ExportFormat);
if (EditorGUI.EndChangeCheck())
{
if (m_ExportFormat.value == ExportFormat.Asset || m_ExportFormat.value == ExportFormat.Prefab)
{
var opt = ExportAsset.s_ExportAssetOptions.value;
opt.makePrefab = m_ExportFormat.value == ExportFormat.Prefab;
ExportAsset.s_ExportAssetOptions.SetValue(opt);
}
}
m_ExportRecursive.value = EditorGUILayout.Toggle(gc_ExportRecursive, m_ExportRecursive);
if (m_ExportFormat != ExportFormat.Asset
&& m_ExportFormat != ExportFormat.Prefab
&& m_ExportFormat != ExportFormat.Stl)
{
m_ExportAsGroup.value = EditorGUILayout.Toggle(gc_ExportAsGroup, m_ExportAsGroup);
}
if (m_ExportFormat == ExportFormat.Obj)
ObjExportOptions();
else if (m_ExportFormat == ExportFormat.Stl)
StlExportOptions();
else if (m_ExportFormat == ExportFormat.Ply)
PlyExportOptions();
else if (m_ExportFormat == ExportFormat.Asset || m_ExportFormat == ExportFormat.Prefab)
AssetExportOptions();
if (EditorGUI.EndChangeCheck())
ProBuilderSettings.Save();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Export"))
EditorUtility.ShowNotification(PerformAction().notification);
}
void ObjExportOptions()
{
EditorGUI.BeginDisabledGroup(m_ExportAsGroup);
if (m_ExportAsGroup)
EditorGUILayout.Toggle("Apply Transforms", true);
else
m_ObjApplyTransform.value = EditorGUILayout.Toggle(gc_ObjApplyTransform, m_ObjApplyTransform);
EditorGUI.EndDisabledGroup();
m_ObjExportRightHanded.value = EditorGUILayout.Toggle(gc_ObjExportRightHanded, m_ObjExportRightHanded);
m_ObjExportCopyTextures.value = EditorGUILayout.Toggle(gc_ObjExportCopyTextures, m_ObjExportCopyTextures);
m_ObjExportVertexColors.value = EditorGUILayout.Toggle(gc_ObjExportVertexColors, m_ObjExportVertexColors);
m_ObjTextureOffsetScale.value = EditorGUILayout.Toggle(gc_ObjTextureOffsetScale, m_ObjTextureOffsetScale);
m_ObjQuads.value = EditorGUILayout.Toggle(gc_ObjQuads, m_ObjQuads);
}
void StlExportOptions()
{
m_StlExportFormat.value = (UnityEngine.ProBuilder.Stl.FileType)EditorGUILayout.EnumPopup("Stl Format", m_StlExportFormat);
}
void PlyExportOptions()
{
EditorGUI.BeginDisabledGroup(m_ExportAsGroup);
if (m_ExportAsGroup)
EditorGUILayout.Toggle("Apply Transforms", true);
else
m_PlyApplyTransform.value = EditorGUILayout.Toggle(gc_ObjApplyTransform, m_PlyApplyTransform);
EditorGUI.EndDisabledGroup();
m_PlyExportIsRightHanded.value = EditorGUILayout.Toggle("Right Handed", m_PlyExportIsRightHanded);
m_PlyQuads.value = EditorGUILayout.Toggle("Quads", m_PlyQuads);
}
void AssetExportOptions()
{
var options = ExportAsset.s_ExportAssetOptions.value;
EditorGUI.BeginChangeCheck();
options.replaceOriginal = EditorGUILayout.Toggle(gc_ExportAssetInPlace, options.replaceOriginal);
if(EditorGUI.EndChangeCheck())
ExportAsset.s_ExportAssetOptions.SetValue(options);
}
protected override ActionResult PerformActionImplementation()
{
string res = null;
List<ProBuilderMesh> meshes = m_ExportRecursive ? MeshSelection.deep.ToList() : MeshSelection.topInternal;
if (meshes == null || meshes.Count == 0)
return new ActionResult(ActionResult.Status.Canceled, "No ProBuilder Mesh");
if (m_ExportFormat == ExportFormat.Obj)
{
res = ExportObj.ExportWithFileDialog(meshes,
m_ExportAsGroup,
m_ObjQuads,
new ObjOptions() {
handedness = m_ObjExportRightHanded ? ObjOptions.Handedness.Right : ObjOptions.Handedness.Left,
copyTextures = m_ObjExportCopyTextures,
applyTransforms = m_ExportAsGroup || m_ObjApplyTransform.value,
vertexColors = m_ObjExportVertexColors,
textureOffsetScale = m_ObjTextureOffsetScale
});
}
else if (m_ExportFormat == ExportFormat.Stl)
{
res = ExportStlAscii.ExportWithFileDialog(meshes.Select(x => x.gameObject).ToArray(), m_StlExportFormat);
}
else if (m_ExportFormat == ExportFormat.Ply)
{
res = ExportPly.ExportWithFileDialog(meshes, m_ExportAsGroup, new PlyOptions() {
isRightHanded = m_PlyExportIsRightHanded,
applyTransforms = m_PlyApplyTransform,
quads = m_PlyQuads,
ngons = m_PlyNGons
});
}
else if (m_ExportFormat == ExportFormat.Asset || m_ExportFormat == ExportFormat.Prefab)
{
res = ExportAsset.ExportWithFileDialog(meshes, ExportAsset.s_ExportAssetOptions.value);
}
if (string.IsNullOrEmpty(res))
return new ActionResult(ActionResult.Status.Canceled, "Canceled");
PingExportedModel(res);
return new ActionResult(ActionResult.Status.Success, "Exported " + m_ExportFormat.value);
}
internal static void PingExportedModel(string path)
{
var local = path.Replace("\\", "/");
var dataPath = Application.dataPath.Replace("\\", "/");
if (local.Contains(dataPath))
{
AssetDatabase.Refresh();
var assetPath = "Assets" + local.Replace(dataPath, "");
var o = AssetDatabase.LoadAssetAtPath<Object>(assetPath);
if (o != null)
EditorGUIUtility.PingObject(o);
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 736319124efd40fda31c36ae2599181a
timeCreated: 1496775583
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,319 @@
using System;
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using UnityEngine.ProBuilder;
using UnityEngine.ProBuilder.Shapes;
using Object = UnityEngine.Object;
namespace UnityEditor.ProBuilder.Actions
{
[Serializable]
struct ExportAssetOptions
{
public bool makePrefab;
public bool replaceOriginal;
public static readonly ExportAssetOptions defaults = new ExportAssetOptions()
{
makePrefab = false,
replaceOriginal = false
};
}
sealed class ExportAsset : MenuAction
{
public override ToolbarGroup group { get { return ToolbarGroup.Export; } }
public override string iconPath => string.Empty;
public override Texture2D icon => null;
public override TooltipContent tooltip { get { return s_Tooltip; } }
internal static Pref<ExportAssetOptions> s_ExportAssetOptions =new Pref<ExportAssetOptions>("export.assetOptions", ExportAssetOptions.defaults);
static readonly TooltipContent s_Tooltip = new TooltipContent
(
"Export Asset",
"Export a Unity mesh asset file."
);
public override bool enabled
{
get { return MeshSelection.selectedObjectCount > 0; }
}
public override bool hidden
{
get { return true; }
}
protected override ActionResult PerformActionImplementation()
{
var opt = s_ExportAssetOptions.value;
var res = ExportWithFileDialog(MeshSelection.topInternal, opt);
Export.PingExportedModel(res);
return new ActionResult(ActionResult.Status.Success, opt.makePrefab ? "Make Prefab" : "Make Asset");
}
/// <summary>
/// Export meshes to a Unity asset.
/// </summary>
/// <param name="meshes"></param>
/// <returns></returns>
public static string ExportWithFileDialog(IList<ProBuilderMesh> meshes, ExportAssetOptions options)
{
if (meshes == null || meshes.Count == 0)
return "";
string res = null;
if (meshes.Count < 2)
{
ProBuilderMesh first = meshes.FirstOrDefault();
if (first == null)
return null;
res = options.makePrefab
? ExportPrefab(first, options.replaceOriginal)
: ExportMesh(first, options.replaceOriginal);
}
else
{
string path = UnityEditor.EditorUtility.SaveFolderPanel("Export to Asset", "Assets", "");
if (string.IsNullOrEmpty(path) || !Directory.Exists(path))
return null;
meshes = meshes.ToList();
for (int i = 0, c = meshes.Count; i < c; i++)
{
var pb = meshes[i];
var assetPath = string.Format("{0}/{1}.asset", path, pb.name);
if (options.makePrefab)
{
res = ExportPrefab(assetPath, pb, options.replaceOriginal, true);
}
else
{
res = ExportMesh(assetPath, pb, options.replaceOriginal, true);
if (options.replaceOriginal)
StripProBuilderScripts.DestroyProBuilderMeshAndDependencies(pb.gameObject, pb, true, true);
}
}
}
ProBuilderEditor.Refresh();
AssetDatabase.Refresh();
return res;
}
static string AssetPathFromFullPath(string path, string extension)
{
if (string.IsNullOrEmpty(path)) return null;
string directory = Path.GetDirectoryName(path).Replace("\\", "/");
string name = Path.GetFileNameWithoutExtension(path);
string relativeDirectory = string.Format("Assets{0}", directory.Replace(Application.dataPath, ""));
return !string.IsNullOrEmpty(extension)
? string.Format("{0}/{1}.{2}", relativeDirectory, name, extension)
: string.Format("{0}/{1}", relativeDirectory, name);
}
static string AskForPath(string fileName, string extension)
{
return UnityEditor.EditorUtility.SaveFilePanel("Export to Asset", "Assets", fileName, extension);
}
static string AskForAssetPath(string fileName, string extension)
{
return AssetPathFromFullPath(AskForPath(fileName, extension), extension);
}
static string PickDifferentAssetPath(string previousAssetPath)
{
var extension = Path.GetExtension(previousAssetPath);
if (extension != null && extension.StartsWith("."))
{
extension = extension.Substring(1);
}
var newPath = AskForAssetPath(
Path.GetFileNameWithoutExtension(previousAssetPath),
extension
);
return !string.IsNullOrEmpty(newPath)
? newPath
: AssetDatabase.GenerateUniqueAssetPath(previousAssetPath);
}
static string ExportPrefab(ProBuilderMesh mesh, bool replaceOriginal)
{
string path = AskForPath(mesh.name, "prefab");
if (string.IsNullOrEmpty(path))
return null;
return ExportPrefab(path, mesh, replaceOriginal, false);
}
static string ExportMesh(ProBuilderMesh mesh, bool replaceOriginal)
{
string path = AskForPath(mesh.name, "asset");
if (string.IsNullOrEmpty(path))
return null;
ExportMesh(path, mesh, replaceOriginal, false);
if (replaceOriginal)
{
StripProBuilderScripts.DestroyProBuilderMeshAndDependencies(mesh.gameObject, mesh, true, true);
}
else
{
mesh.mesh = null;
EditorUtility.SynchronizeWithMeshFilter(mesh);
}
return path;
}
static string ExportPrefab(string path, ProBuilderMesh pb, bool replaceOriginal, bool batchExport)
{
string name = Path.GetFileNameWithoutExtension(path);
string basePath = AssetPathFromFullPath(path, null);
pb.ToMesh();
pb.Refresh();
pb.Optimize();
string meshPath = string.Format("{0}.asset", basePath);
string prefabPath = string.Format("{0}.prefab", basePath);
if (batchExport)
{
// Never overwrite during batch export.
meshPath = AssetDatabase.GenerateUniqueAssetPath(meshPath);
prefabPath = AssetDatabase.GenerateUniqueAssetPath(prefabPath);
}
else
{
var existingMesh = AssetDatabase.LoadAssetAtPath<Mesh>(meshPath);
if (existingMesh)
{
// Overwriting mesh.
var existingPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
if (existingPrefab)
{
// Overwriting prefab as well.
var meshFilter = existingPrefab.GetComponent<MeshFilter>();
if (!meshFilter || meshFilter.sharedMesh != existingMesh)
{
// Prefab and mesh being overwritten are not related, pick different path.
meshPath = PickDifferentAssetPath(meshPath);
}
// Else allow overwrite both as they are related.
}
else
{
// Unrelated mesh is being overriden, pick different path.
meshPath = PickDifferentAssetPath(meshPath);
}
}
}
Mesh meshAsset = pb.mesh;
meshAsset.name = name;
meshAsset = CreateOrReplaceAsset(meshAsset, meshPath);
var go = replaceOriginal ? pb.gameObject : Object.Instantiate(pb.gameObject);
var component = go.GetComponent<ProBuilderMesh>();
Undo.RecordObject(component, "Export ProBuilderMesh as Replacement");
StripProBuilderScripts.DestroyProBuilderMeshAndDependencies(go, component, true, true);
go.GetComponent<MeshFilter>().sharedMesh = meshAsset;
var meshCollider = go.GetComponent<MeshCollider>();
if (meshCollider)
meshCollider.sharedMesh = meshAsset;
if (replaceOriginal)
PrefabUtility.SaveAsPrefabAssetAndConnect(go, prefabPath, InteractionMode.UserAction);
else
{
// if we're about to overwrite the prefab asset of the source mesh, first disconnect it so that we're not
// overwriting the instance
if (PrefabUtility.IsPartOfAnyPrefab(pb)
&& PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(pb) == prefabPath)
PrefabUtility.UnpackPrefabInstance(pb.gameObject, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction);
PrefabUtility.SaveAsPrefabAsset(go, prefabPath);
}
if (!replaceOriginal)
{
pb.mesh = null;
EditorUtility.SynchronizeWithMeshFilter(pb);
Object.DestroyImmediate(go);
}
return meshPath;
}
static string ExportMesh(string path, ProBuilderMesh mesh, bool replaceOriginal, bool batchExport)
{
var existing = AssetDatabase.GetAssetPath(mesh.mesh);
if (!string.IsNullOrEmpty(existing))
return existing;
string name = Path.GetFileNameWithoutExtension(path);
string meshPath = AssetPathFromFullPath(path, "asset");
if (batchExport)
{
// Never replace assets during batch export.
meshPath = AssetDatabase.GenerateUniqueAssetPath(meshPath);
}
mesh.ToMesh();
mesh.Refresh();
mesh.Optimize();
var meshAsset = mesh.mesh;
meshAsset.name = name;
meshAsset = CreateOrReplaceAsset(meshAsset, meshPath);
if (replaceOriginal)
{
mesh.GetComponent<MeshFilter>().sharedMesh = meshAsset;
var meshCollider = mesh.GetComponent<MeshCollider>();
if (meshCollider)
{
meshCollider.sharedMesh = meshAsset;
}
}
return meshPath;
}
static T CreateOrReplaceAsset<T>(T asset, string path) where T : Object
{
T existingAsset = AssetDatabase.LoadAssetAtPath<T>(path);
if (existingAsset == null)
{
AssetDatabase.CreateAsset(asset, path);
return asset;
}
var tempPath = AssetDatabase.GenerateUniqueAssetPath(path);
AssetDatabase.CreateAsset(asset, tempPath);
FileUtil.ReplaceFile(tempPath, path);
AssetDatabase.DeleteAsset(tempPath);
return existingAsset;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cc401b52b64c4b7b87078d8ae3e29b68
timeCreated: 1472836657
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,132 @@
using UnityEngine;
using UnityEditor;
using UnityEditor.ProBuilder.UI;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using UnityEngine.ProBuilder;
namespace UnityEditor.ProBuilder.Actions
{
sealed class ExportObj : MenuAction
{
public override ToolbarGroup group { get { return ToolbarGroup.Export; } }
public override string iconPath => string.Empty;
public override Texture2D icon => null;
public override TooltipContent tooltip { get { return _tooltip; } }
static readonly TooltipContent _tooltip = new TooltipContent
(
"Export Obj",
"Export a Wavefront OBJ file."
);
public override bool hidden
{
get { return true; }
}
public override bool enabled
{
get { return MeshSelection.selectedObjectCount > 0; }
}
protected override ActionResult PerformActionImplementation()
{
string res = ExportWithFileDialog(MeshSelection.topInternal);
if (string.IsNullOrEmpty(res))
return new ActionResult(ActionResult.Status.Canceled, "User Canceled");
Export.PingExportedModel(res);
return new ActionResult(ActionResult.Status.Success, "Export OBJ");
}
// Prompt user for a save file location and export meshes as Obj.
public static string ExportWithFileDialog(IEnumerable<ProBuilderMesh> meshes, bool asGroup = true, bool allowQuads = true, ObjOptions options = null)
{
if (meshes == null || !meshes.Any())
return null;
IEnumerable<Model> models = allowQuads
? meshes.Select(x => new Model(x.gameObject.name, x))
: meshes.Select(x => new Model(x.gameObject.name, x.mesh, x.GetComponent<MeshRenderer>().sharedMaterials, x.transform.localToWorldMatrix));
string path = null, res = null;
if (asGroup || models.Count() < 2)
{
ProBuilderMesh first = meshes.FirstOrDefault();
string name = first != null ? first.name : "ProBuilderModel";
path = UnityEditor.EditorUtility.SaveFilePanel("Export to Obj", "Assets", name, "obj");
if (string.IsNullOrEmpty(path))
return null;
res = DoExport(path, models, options);
}
else
{
path = UnityEditor.EditorUtility.SaveFolderPanel("Export to Obj", "Assets", "");
if (string.IsNullOrEmpty(path) || !Directory.Exists(path))
return null;
foreach (Model model in models)
res = DoExport(string.Format("{0}/{1}.obj", path, model.name), new List<Model>() { model }, options);
}
return res;
}
internal static string DoExport(string path, IEnumerable<Model> models, ObjOptions options)
{
string name = Path.GetFileNameWithoutExtension(path);
string directory = Path.GetDirectoryName(path);
List<string> textures = null;
string obj, mat;
if (ObjExporter.Export(name, models, out obj, out mat, out textures, options))
{
try
{
FileUtility.WriteAllText(string.Format("{0}/{1}.obj", directory, name), obj);
FileUtility.WriteAllText(string.Format("{0}/{1}.mtl", directory, name.Replace(" ", "_")), mat);
CopyTextures(textures, directory);
}
catch (System.Exception e)
{
Debug.LogWarning(string.Format("Failed writing obj to path: {0}\n{1}", string.Format("{0}/{1}.obj", path, name), e.ToString()));
return null;
}
}
else
{
Debug.LogWarning("No meshes selected.");
return null;
}
return path;
}
// Copy files from their path to a destination directory.
static void CopyTextures(List<string> textures, string destination)
{
foreach (string path in textures)
{
string dest = string.Format("{0}/{1}", destination, Path.GetFileName(path));
if (!File.Exists(path))
{
Log.Warning("OBJ Export: Could not find texture \"" + path + ",\" it will not be copied.");
continue;
}
if (!File.Exists(dest))
File.Copy(path, dest);
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 23fb6d4a102f4c2188ef8afe61eb58e4
timeCreated: 1472833007
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,112 @@
using UnityEngine;
using UnityEditor;
using UnityEditor.ProBuilder.UI;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using UnityEngine.ProBuilder.Stl;
using UnityEngine.ProBuilder;
using UnityEditor.ProBuilder;
using EditorUtility = UnityEditor.EditorUtility;
namespace UnityEditor.ProBuilder.Actions
{
sealed class ExportPly : MenuAction
{
public override ToolbarGroup group { get { return ToolbarGroup.Export; } }
public override string iconPath => string.Empty;
public override Texture2D icon => null;
public override TooltipContent tooltip { get { return _tooltip; } }
static readonly TooltipContent _tooltip = new TooltipContent
(
"Export Ply",
"Export a Stanford PLY file."
);
public override bool hidden
{
get { return true; }
}
public override bool enabled
{
get { return MeshSelection.selectedObjectCount > 0; }
}
protected override ActionResult PerformActionImplementation()
{
string res = ExportWithFileDialog(MeshSelection.topInternal);
if (string.IsNullOrEmpty(res))
return new ActionResult(ActionResult.Status.Canceled, "User Canceled");
Export.PingExportedModel(res);
return new ActionResult(ActionResult.Status.Success, "Export PLY");
}
/**
* Prompt user for a save file location and export meshes as Obj.
*/
public static string ExportWithFileDialog(IEnumerable<ProBuilderMesh> meshes, bool asGroup = true, PlyOptions options = null)
{
if (meshes == null || meshes.Count() < 1)
return null;
string path = null, res = null;
if (asGroup || meshes.Count() < 2)
{
ProBuilderMesh first = meshes.FirstOrDefault();
string name = first != null ? first.name : "ProBuilderModel";
path = UnityEditor.EditorUtility.SaveFilePanel("Export as PLY", "Assets", name, "ply");
if (string.IsNullOrEmpty(path))
return null;
res = DoExport(path, meshes, options);
}
else
{
path = UnityEditor.EditorUtility.SaveFolderPanel("Export to PLY", "Assets", "");
if (string.IsNullOrEmpty(path) || !Directory.Exists(path))
return null;
foreach (ProBuilderMesh model in meshes)
res = DoExport(string.Format("{0}/{1}.ply", path, model.name), new List<ProBuilderMesh>() { model }, options);
}
return res;
}
static string DoExport(string path, IEnumerable<ProBuilderMesh> models, PlyOptions options)
{
string name = Path.GetFileNameWithoutExtension(path);
string directory = Path.GetDirectoryName(path);
string ply;
if (PlyExporter.Export(models, out ply, options))
{
try
{
FileUtility.WriteAllText(string.Format("{0}/{1}.ply", directory, name), ply);
}
catch (System.Exception e)
{
Debug.LogWarning(string.Format("Failed writing PLY to path: {0}\n{1}", string.Format("{0}/{1}.ply", path, name), e.ToString()));
return null;
}
}
else
{
Debug.LogWarning("No meshes selected.");
return null;
}
return path;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ac7a7f49f26f45b29857e71b0d156fff
timeCreated: 1497030443
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,91 @@
using System;
using System.Globalization;
using UnityEngine;
using UnityEditor;
using System.Linq;
using System.Threading;
using UnityEngine.ProBuilder.Stl;
using UnityEngine.ProBuilder;
using UnityEditor.ProBuilder;
using EditorUtility = UnityEditor.EditorUtility;
using Object = UnityEngine.Object;
namespace UnityEditor.ProBuilder.Actions
{
sealed class ExportStlAscii : MenuAction
{
public override ToolbarGroup group { get { return ToolbarGroup.Export; } }
public override string iconPath => string.Empty;
public override Texture2D icon => null;
public override TooltipContent tooltip { get { return _tooltip; } }
static readonly TooltipContent _tooltip = new TooltipContent
(
"Export Stl",
@"Export an Stl model file."
);
public override bool hidden
{
get { return true; }
}
public override bool enabled
{
get { return MeshSelection.selectedObjectCount > 0; }
}
protected override ActionResult PerformActionImplementation()
{
var res = ExportWithFileDialog(Selection.gameObjects, FileType.Ascii);
if (string.IsNullOrEmpty(res))
return new ActionResult(ActionResult.Status.Canceled, "User Canceled");
Export.PingExportedModel(res);
return new ActionResult(ActionResult.Status.Success, "Export STL");
}
public static string ExportWithFileDialog(GameObject[] gameObjects, FileType type)
{
GameObject first = gameObjects.FirstOrDefault(x => x.GetComponent<ProBuilderMesh>() != null);
string name = first != null ? first.name : "Mesh";
string path = UnityEditor.EditorUtility.SaveFilePanel("Save Mesh to STL", "", name, "stl");
var res = false;
var currentCulture = Thread.CurrentThread.CurrentCulture;
try
{
// pb_Stl is an external lib
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
res = pb_Stl_Exporter.Export(path, gameObjects, type);
}
finally
{
Thread.CurrentThread.CurrentCulture = currentCulture;
}
if (res)
{
string full = path.Replace("\\", "/");
// if the file was saved in project, ping it
if (full.Contains(Application.dataPath))
{
string relative = full.Replace(Application.dataPath, "Assets");
Object o = AssetDatabase.LoadAssetAtPath(relative, typeof(Object));
if (o != null)
EditorGUIUtility.PingObject(o);
AssetDatabase.Refresh();
}
return path;
}
return null;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 48b3897a5481441a8c9468e28fd54c53
timeCreated: 1472831854
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,46 @@
using UnityEngine;
using UnityEditor;
using UnityEditor.ProBuilder.UI;
using System.Linq;
using UnityEngine.ProBuilder.Stl;
using UnityEngine.ProBuilder;
using UnityEditor.ProBuilder;
namespace UnityEditor.ProBuilder.Actions
{
sealed class ExportStlBinary : MenuAction
{
public override ToolbarGroup group { get { return ToolbarGroup.Export; } }
public override string iconPath => string.Empty;
public override Texture2D icon => null;
public override TooltipContent tooltip { get { return _tooltip; } }
static readonly TooltipContent _tooltip = new TooltipContent
(
"Export Stl",
@"Export an Stl model file."
);
public override bool hidden
{
get { return true; }
}
public override bool enabled
{
get { return MeshSelection.selectedObjectCount > 0; }
}
protected override ActionResult PerformActionImplementation()
{
var res = ExportStlAscii.ExportWithFileDialog(Selection.gameObjects, FileType.Binary);
if (string.IsNullOrEmpty(res))
return new ActionResult(ActionResult.Status.Canceled, "User Canceled");
Export.PingExportedModel(res);
return new ActionResult(ActionResult.Status.Success, "Export STL");
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b04279a9fe7348798c260ea6516c1a4c
timeCreated: 1472832591
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: