Skip to content
109 changes: 105 additions & 4 deletions Editor/MMDEngineEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public override void OnInspectorGUI()
is_dirty = OnInspectorGUIforUseRigidbody() || is_dirty;
is_dirty = OnInspectorGUIforIkList() || is_dirty;
is_dirty = OnInspectorGUIforShaderList() || is_dirty;

is_dirty = OnInspectorGUIforRenderQueue() || is_dirty;

if (is_dirty) {
//更新が有ったなら
//Inspector更新
Expand Down Expand Up @@ -215,7 +216,9 @@ private bool OnInspectorGUIforShaderList()
, new {flag=ShaderFlag.Hidden, reverse=false}
};
//マテリアル
foreach (var material in materials) {
for (int i = 0, i_max = materials.Length; i < i_max; ++i) {
Material material = materials[i];

EditorGUILayout.BeginHorizontal();
{
//ラベル
Expand Down Expand Up @@ -256,7 +259,8 @@ private bool OnInspectorGUIforShaderList()
Undo.RegisterUndo(material, "Shader Change");
#endif

SetShader(material, flag);
int render_queue = ((self.enable_render_queue)? self.render_queue_value + i: -1);
SetShader(material, flag, render_queue);
is_update = true;
}
}
Expand All @@ -269,6 +273,92 @@ private bool OnInspectorGUIforShaderList()
return is_update;
}

/// <summary>
/// カスタムレンダーキューの為のInspector描画
/// </summary>
/// <returns>更新が有ったか(true:更新有り, false:未更新)</returns>
private bool OnInspectorGUIforRenderQueue()
{
MMDEngine self = (MMDEngine)target;
bool is_update = false;

#if !MFU_DISABLE_LEGACY_DATA_SUPPORT
if ((false == self.enable_render_queue) && (0 == self.render_queue_value)) {
//カスタムレンダーキュー関連が設定されていないなら(昔の変換データ)
//無効状態で初期化
self.enable_render_queue = false;
const int c_render_queue_transparent = 3000;
self.render_queue_value = c_render_queue_transparent;
}
#endif

bool enable_render_queue = self.enable_render_queue;
enable_render_queue = EditorGUILayout.Toggle("Render Queue", enable_render_queue);
if (self.enable_render_queue != enable_render_queue) {
//変更が掛かったなら
is_update = true;
}
int render_queue_value = -1;
if (enable_render_queue) {
//有効なら
render_queue_value = self.render_queue_value;
render_queue_value = EditorGUILayout.IntField("Render Queue Value", render_queue_value);
if (self.render_queue_value != render_queue_value) {
//変更が掛かったなら
is_update = true;
}
}

if (is_update) {
//変更が掛かったなら
Material[] materials = GetMaterials(self);
//Undo登録
var record_objects = materials.Select(x=>(UnityEngine.Object)x) //マテリアル全てと
.Concat(new UnityEngine.Object[]{self}) //UnityEngine
.ToArray();
#if !UNITY_4_2 //4.3以降
Undo.RecordObjects(record_objects, "Render Queue Change");
#else
Undo.RegisterUndo(record_objects, "Render Queue Change");
#endif
//更新
self.enable_render_queue = enable_render_queue;
if (enable_render_queue) {
//有効化
self.render_queue_value = render_queue_value;
for (int i = 0, i_max = materials.Length; i < i_max; ++i) {
var material = materials[i];
ShaderFlag flag = AnalyzeShaderFlag(material);
if (0 != (flag & ShaderFlag.MmdShader)) {
//Mmdシェーダーなら
//カスタムレンダーキュー
if (0 != (flag & ShaderFlag.Transparent)) {
//透過なら
//マテリアル順にカスタムレンダーキューを設定
material.renderQueue = render_queue_value + i;
} else {
//不透明なら
//カスタムレンダーキューを解除
material.renderQueue = -1;
}
}
}
} else {
//無効化
foreach (var material in materials) {
ShaderFlag flag = AnalyzeShaderFlag(material);
if (0 != (flag & ShaderFlag.MmdShader)) {
//Mmdシェーダーなら
//カスタムレンダーキューを解除
material.renderQueue = -1;
}
}
}
}

return is_update;
}

/// <summary>
/// MMDシェーダー確認
/// </summary>
Expand Down Expand Up @@ -357,7 +447,8 @@ static ShaderFlag AnalyzeShaderFlag(Material material) {
/// </summary>
/// <param name='material'>マテリアル</param>
/// <param name='flag'>シェーダーフラグ</param>
static void SetShader(Material material, ShaderFlag flag) {
/// <param name='render_queue'>透過の場合に設定するレンダーキュー</param>
static void SetShader(Material material, ShaderFlag flag, int render_queue) {
if (0 != (flag & ShaderFlag.MmdShader)) {
//Mmdシェーダーなら
material.shader = CreateShaderFromShaderFlag(flag);
Expand All @@ -371,6 +462,16 @@ static void SetShader(Material material, ShaderFlag flag) {
float original_shader_type = (float)(int)flag;
material.SetFloat("_DummyOriginalShaderType", original_shader_type);
material.SetColor("_DummyColor", new Color(1.0f, 0.0f, 1.0f, 1.0f));
}
//カスタムレンダーキュー
if (0 != (flag & ShaderFlag.Transparent)) {
//透過なら
//マテリアル順にカスタムレンダーキューを設定
material.renderQueue = render_queue;
} else {
//不透明なら
//カスタムレンダーキューを解除
material.renderQueue = -1;
}
}
}
Expand Down
123 changes: 123 additions & 0 deletions Editor/MMDLoader/Private/AlphaReadableTexture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;

public class AlphaReadableTexture : System.IDisposable {

/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="texture_path_list">テクスチャ相対パスリスト</param>
/// <param name="current_directory">カレントディレクトリ("/"終わり、テクスチャの相対パス基点)</param>
/// <param name="temporary_directory">解析作業用ディレクトリ("/"終わり、このディレクトリの下に解析作業用ディレクトリを作ります)</param>
public AlphaReadableTexture(string[] texture_path_list, string current_directory, string temporary_directory)
{
texture_path_list_ = texture_path_list;
current_directory_ = current_directory;
temporary_directory_ = temporary_directory + directory_name + "/";

//テクスチャ作成
foreach (string texture_path in texture_path_list_.Where(x=>!string.IsNullOrEmpty(x)).Distinct()) {
CreateReadableTexture(texture_path);
}
AssetDatabase.Refresh();
//テクスチャ取得
textures_ = texture_path_list_.Select(x=>GetReadableTexture(x)).ToArray();
}

/// <summary>
/// 読み込み可能テクスチャの取得
/// </summary>
/// <value>読み込み可能テクスチャ</value>
public Texture2D[] textures {get{return textures_;}}

/// <summary>
/// Disposeインターフェース
/// </summary>
public void Dispose()
{
//テクスチャ破棄
foreach (string texture_path in texture_path_list_.Where(x=>!string.IsNullOrEmpty(x)).Distinct()) {
DeleteReadableTexture(texture_path);
}
//ディレクトリの破棄
string path = Application.dataPath + "/../" + temporary_directory_; //"Asset/"が被るので1階層上がる
if (System.IO.Directory.Exists(path)) {
System.IO.Directory.Delete(path, true);
}
}

/// <summary>
/// 解析対象ディレクトリ名の取得
/// </summary>
/// <value>The directory_name.</value>
public static string directory_name {get{return "AlphaReadableTextureDirectory.MmdForUnity";}}

/// <summary>
/// 読み込み可能テクスチャの作成
/// </summary>
/// <param name="texture_path">テクスチャパス</param>
private void CreateReadableTexture(string texture_path)
{
if (!string.IsNullOrEmpty(texture_path)) {
string base_texture_path = current_directory_ + texture_path;
string readable_texture_path = temporary_directory_ + texture_path;
CreateDirectoryPath(System.IO.Path.GetDirectoryName(readable_texture_path));
bool is_copy_success = AssetDatabase.CopyAsset(base_texture_path, readable_texture_path);
if (!is_copy_success) {
throw new System.InvalidOperationException();
}
}
}

/// <summary>
/// 読み込み可能テクスチャの取得
/// </summary>
/// <returns>読み込み可能テクスチャ</returns>
/// <param name="texture_path">テクスチャパス</param>
private Texture2D GetReadableTexture(string texture_path)
{
Texture2D result = null;
if (!string.IsNullOrEmpty(texture_path)) {
string readable_texture_path = temporary_directory_ + texture_path;
result = (Texture2D)AssetDatabase.LoadAssetAtPath(readable_texture_path, typeof(Texture2D));
}
return result;
}

/// <summary>
/// 読み込み可能テクスチャの削除
/// </summary>
/// <param name="texture_path">テクスチャパス</param>
private void DeleteReadableTexture(string texture_path)
{
if (!string.IsNullOrEmpty(texture_path)) {
string readable_texture_path = temporary_directory_ + texture_path;
AssetDatabase.DeleteAsset(readable_texture_path);
}
}

/// <summary>
/// ディレクトリの作成(親ディレクトリが無ければ再帰的に作成)
/// </summary>
/// <param name="path">ディレクトリパス</param>
private static void CreateDirectoryPath(string path)
{
//親ディレクトリ作成
string parent_path = System.IO.Path.GetDirectoryName(path);
if (!string.IsNullOrEmpty(parent_path) && !System.IO.Directory.Exists(parent_path)) {
CreateDirectoryPath(parent_path);
}
//カレントディレクトリ作成
if (!System.IO.Directory.Exists(path)) {
string name = System.IO.Path.GetFileName(path);
AssetDatabase.CreateFolder(parent_path, name);
}
}

private Texture2D[] textures_; //読み込み可能テクスチャ
private string[] texture_path_list_; //解析するテクスチャリスト
private string current_directory_; //カレントディレクトリ
private string temporary_directory_; //解析作業用ディレクトリ
}
28 changes: 28 additions & 0 deletions Editor/MMDLoader/Private/AlphaReadableTextureDirectoryImporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

public class AlphaReadableTextureDirectoryImporter : AssetPostprocessor {

/// <summary>
/// テクスチャプリプロセッサ
/// </summary>
void OnPreprocessTexture() {
if (-1 != assetPath.IndexOf(AlphaReadableTexture.directory_name)) {
//MmdForUnityの解析用ディレクトリなら
TextureImporter importer = (TextureImporter)assetImporter;
importer.isReadable = true; //読み込み可能とする
importer.textureFormat = TextureImporterFormat.Alpha8; //アルファのみ
importer.mipmapEnabled = false; //mipmapを作成しない
if (importer.DoesSourceTextureHaveAlpha()) {
//アルファが有れば
//透過フラグを立てる
importer.alphaIsTransparency = true;
} else {
//アルファが無ければ
//解像度を最小化
importer.maxTextureSize = 1;
}
}
}
}
Loading