Last active
July 22, 2019 19:21
-
-
Save sokuhatiku/7dd44c7de34d3c039acb647d5db42172 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if UNITY_EDITOR | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEditor; | |
namespace Sokuhatiku.TunnelShader | |
{ | |
public class TunnelMeshCompressor : EditorWindow | |
{ | |
private const string Name = "Tunnel Mesh Complesser"; | |
[MenuItem("Window/" + Name)] | |
public static void Open() | |
{ | |
var window = GetWindow<TunnelMeshCompressor>(); | |
window.titleContent = new GUIContent(Name); | |
} | |
private MeshFilter filter; | |
private void OnGUI() | |
{ | |
bool complessAction = false; | |
bool targetChanged = false; | |
EditorGUILayout.LabelField(Name, EditorStyles.largeLabel); | |
EditorGUILayout.Space(); | |
EditorGUI.BeginChangeCheck(); | |
{ | |
filter = EditorGUILayout.ObjectField("Target", filter, typeof(MeshFilter), true) as MeshFilter; | |
} | |
targetChanged = EditorGUI.EndChangeCheck(); | |
EditorGUILayout.Space(); | |
EditorGUI.BeginDisabledGroup(filter == null || EditorApplication.isPlayingOrWillChangePlaymode); | |
{ | |
complessAction = GUILayout.Button("Compless", GUILayout.Height(25)); | |
} | |
EditorGUI.EndDisabledGroup(); | |
if (targetChanged && filter != null) | |
{ | |
Selection.SetActiveObjectWithContext(filter.gameObject, filter); | |
} | |
if (complessAction && filter != null) | |
{ | |
Process(filter); | |
} | |
} | |
private void Process(MeshFilter filter) | |
{ | |
var savePath = EditorUtility.SaveFilePanelInProject("Save complessed mesh", "Complessed", "asset", ""); | |
if (string.IsNullOrEmpty(savePath)) | |
{ | |
return; | |
} | |
Undo.RecordObjects(new Object[] { filter, filter.transform }, "Tunnel Mesh Compless"); | |
var localToWorld = filter.transform.localToWorldMatrix; | |
filter.transform.rotation = Quaternion.identity; | |
var worldToLocal = filter.transform.worldToLocalMatrix; | |
Mesh mesh = ComplessMesh(filter.sharedMesh, localToWorld, worldToLocal); | |
AssetDatabase.CreateAsset(mesh, savePath); | |
filter.sharedMesh = mesh; | |
} | |
private static Mesh ComplessMesh(Mesh refMesh, Matrix4x4 localToWorld, Matrix4x4 worldToLocal) | |
{ | |
var bounds = new Bounds( | |
new Vector3(0, 2.5f, 0), | |
new Vector3(4, 5, 4)); | |
int positionUvChannel = 2; | |
var mesh = Instantiate(refMesh); | |
var refVertices = refMesh.vertices; | |
var vertices = new Vector3[refVertices.Length]; | |
var posUVs = new Vector3[refVertices.Length]; | |
for (int i = 0; i < vertices.Length; i++) | |
{ | |
var localVertex = localToWorld.MultiplyPoint3x4(refVertices[i]); | |
var clampedVertex = new Vector4( | |
Mathf.Clamp(localVertex.x, bounds.min.x, bounds.max.x), | |
Mathf.Clamp(localVertex.y, bounds.min.y, bounds.max.y), | |
Mathf.Clamp(localVertex.z, bounds.min.z, bounds.max.z)); | |
vertices[i] = worldToLocal.MultiplyPoint3x4(clampedVertex); | |
posUVs[i] = worldToLocal.MultiplyPoint(localVertex); | |
} | |
mesh.vertices = vertices; | |
mesh.SetUVs(positionUvChannel, new List<Vector3>(posUVs)); | |
mesh.bounds = bounds; | |
return mesh; | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
※これはTunnelShaderを使ったコンテンツをVケット3に提出するために、メッシュの頂点座標を指定範囲内に圧縮するスクリプトです。
使用前に必ずプロジェクトのバックアップを取って下さい。
こちらを右クリックしてダウンロードして下さい。
Unityプロジェクト内の適当な場所に配置してください。ただし、エディタ上でしか動かないスクリプトなので、ブースアセットには混ぜないで下さい。
使い方
正常にインストールが完了すると、以下のようにメニューに「Tunnel Mesh Complesser」という項目が出現します。

項目を選ぶと以下のようなUIが出ますので、画像のように圧縮を行いたいTunnelメッシュを含んだオブジェクトを選択します。

Complessを押すとメッシュが圧縮され、ブース範囲内に収まります。圧縮したメッシュは元のメッシュとは別の場所に保存されます。また、Tunnelオブジェクトの回転情報は圧縮済みメッシュに焼きこまれ、Transformの回転はリセットされます。メッシュの見た目が一時的に汚くなりますが、次の項で修正します。
圧縮メッシュの作成以外の処理はすべてUndo(Ctrl+z)で取り消しが可能です。

その後、TunnelUnlit.shader内にある2種類のvert関数を、それぞれ以下のように修正します。
以上の操作を行うと(何か干渉がなければ)ブースサイズ制限を突破しつつ、見た目が正常に戻ります。