Files
UniVRM/Packages/VRM/Runtime/BlendShape/MeshPreviewItem.cs
Isamu Mogi 40a3a6dbe1 Unity 6.2 以降で ShaderUtil の一部のメンバーが Obsolete 警告を出すのに対応
Unity 6.2 以降で、UniVRMが利用している ShaderUtil の次のメンバーが Obsolete となり警告が出るようになりました。

- [GetPropertyCount](https://docs.unity3d.com/6000.2/Documentation/ScriptReference/ShaderUtil.GetPropertyCount.html)
- [GetPropertyType](https://docs.unity3d.com/6000.2/Documentation/ScriptReference/ShaderUtil.GetPropertyType.html)
- [GetPropertyName](https://docs.unity3d.com/6000.2/Documentation/ScriptReference/ShaderUtil.GetPropertyName.html)
- [ShaderPropertyType](https://docs.unity3d.com/6000.2/Documentation/ScriptReference/ShaderUtil.ShaderPropertyType.html)

これらは `Shader` インスタンスのメソッドと `UnityEngine.Rendering.ShaderPropertyType` に置き換わりました。これらの置き換え後の項目は全て UniVRM の最小サポートバージョンである Unity 2022.3 LTS にも存在するため、そのまま置き換えました。

発生していた警告は次のようなものでした。

```
Packages\VRM10\Runtime\Components\Expression\Preview\PreviewMaterialUtil.cs(19,33): warning CS0618: 'ShaderUtil.GetPropertyCount(Shader)' is obsolete: 'Use Shader.GetPropertyCount instead.'
Packages\VRM10\Runtime\Components\Expression\Preview\PreviewMaterialUtil.cs(21,32): warning CS0618: 'ShaderUtil.GetPropertyType(Shader, int)' is obsolete: 'Use Shader.GetPropertyType instead.'
Packages\VRM10\Runtime\Components\Expression\Preview\PreviewMaterialUtil.cs(22,28): warning CS0618: 'ShaderUtil.GetPropertyName(Shader, int)' is obsolete: 'Use Shader.GetPropertyName instead.'
```
2026-07-04 16:20:25 +09:00

229 lines
7.2 KiB
C#

using System.Linq;
using UnityEngine;
using UniGLTF;
using System;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace VRM
{
#if UNITY_EDITOR
[Serializable]
public struct PropItem
{
public UnityEngine.Rendering.ShaderPropertyType PropertyType;
public Vector4 DefaultValues;
}
#endif
[Serializable]
public class MaterialItem
{
public Material Material { get; private set; }
#if UNITY_EDITOR
public Dictionary<string, PropItem> PropMap = new Dictionary<string, PropItem>();
public string[] PropNames
{
get;
private set;
}
#endif
public static MaterialItem Create(Material material)
{
var item = new MaterialItem
{
Material = material
};
#if UNITY_EDITOR
var propNames = new List<string>();
for (int i = 0; i < material.shader.GetPropertyCount(); ++i)
{
var propType = material.shader.GetPropertyType(i);
var name = material.shader.GetPropertyName(i);
switch (propType)
{
case UnityEngine.Rendering.ShaderPropertyType.Color:
// 色
item.PropMap.Add(name, new PropItem
{
PropertyType = propType,
DefaultValues = material.GetColor(name),
});
propNames.Add(name);
break;
case UnityEngine.Rendering.ShaderPropertyType.Texture:
// テクスチャ
{
name += "_ST";
item.PropMap.Add(name, new PropItem
{
PropertyType = propType,
DefaultValues = material.GetVector(name),
});
propNames.Add(name);
}
// 縦横分離用
{
var st_name = name + "_S";
item.PropMap.Add(st_name, new PropItem
{
PropertyType = propType,
DefaultValues = material.GetVector(name),
});
propNames.Add(st_name);
}
{
var st_name = name + "_T";
item.PropMap.Add(st_name, new PropItem
{
PropertyType = propType,
DefaultValues = material.GetVector(name),
});
propNames.Add(st_name);
}
break;
}
}
item.PropNames = propNames.ToArray();
#endif
return item;
}
}
[Serializable]
public class MeshPreviewItem
{
public string Path
{
get;
private set;
}
public SkinnedMeshRenderer SkinnedMeshRenderer
{
get;
private set;
}
public Mesh Mesh
{
get;
private set;
}
public string[] BlendShapeNames
{
get;
private set;
}
public int BlendShapeCount
{
get { return BlendShapeNames.Length; }
}
public Material[] Materials
{
get;
private set;
}
Transform m_transform;
public Vector3 Position
{
get { return m_transform.position; }
}
public Quaternion Rotation
{
get { return m_transform.rotation; }
}
MeshPreviewItem(string path, Transform transform, Material[] materials)
{
Path = path;
m_transform = transform;
Materials = materials;
}
public void Bake(IEnumerable<BlendShapeBinding> values, float weight)
{
if (SkinnedMeshRenderer == null) return;
// Update baked mesh
if (values != null)
{
// clear
for (int i = 0; i < BlendShapeCount; ++i)
{
SkinnedMeshRenderer.SetBlendShapeWeight(i, 0);
}
foreach (var x in values)
{
if (x.RelativePath == Path)
{
if (x.Index >= 0 && x.Index < SkinnedMeshRenderer.sharedMesh.blendShapeCount)
{
SkinnedMeshRenderer.SetBlendShapeWeight(x.Index, x.Weight * weight);
}
else
{
UniGLTFLogger.Warning($"Out of range {SkinnedMeshRenderer.name}: 0 <= {x.Index} < {SkinnedMeshRenderer.sharedMesh.blendShapeCount}");
}
}
}
}
SkinnedMeshRenderer.BakeMesh(Mesh);
}
public static MeshPreviewItem Create(Transform t, Transform root,
Func<Material, Material> getOrCreateMaterial)
{
if (t.TryGetComponent<MeshFilter>(out var meshFilter) && t.TryGetComponent<MeshRenderer>(out var meshRenderer))
{
// copy
meshRenderer.sharedMaterials = meshRenderer.sharedMaterials.Select(x => getOrCreateMaterial(x)).ToArray();
return new MeshPreviewItem(t.RelativePathFrom(root), t, meshRenderer.sharedMaterials)
{
Mesh = meshFilter.sharedMesh
};
}
else if (t.TryGetComponent<SkinnedMeshRenderer>(out var skinnedMeshRenderer))
{
// copy
skinnedMeshRenderer.sharedMaterials = skinnedMeshRenderer.sharedMaterials.Select(x => getOrCreateMaterial(x)).ToArray();
if (skinnedMeshRenderer.sharedMesh.blendShapeCount > 0)
{
// bake required
var sharedMesh = skinnedMeshRenderer.sharedMesh;
return new MeshPreviewItem(t.RelativePathFrom(root), t, skinnedMeshRenderer.sharedMaterials)
{
SkinnedMeshRenderer = skinnedMeshRenderer,
Mesh = new Mesh(), // for bake
BlendShapeNames = Enumerable.Range(0, sharedMesh.blendShapeCount).Select(x => sharedMesh.GetBlendShapeName(x)).ToArray()
};
}
else
{
return new MeshPreviewItem(t.RelativePathFrom(root), t, skinnedMeshRenderer.sharedMaterials)
{
Mesh = skinnedMeshRenderer.sharedMesh,
};
}
}
else
{
return null;
}
}
}
}