本日はUnityの小ネタ枠です。
Unityでスクリプトからシェーダのキーワード定義を変更して処理を切り替える方法です。
今回はシェーダに設定しているキーワードを確認する方法を試します。
前回記事
以下の記事で作成したサンプルシェーダを基にサンプルを作成します。
bluebirdofoz.hatenablog.com
シェーダのキーワードを確認する
スクリプトからシェーダのキーワードの有効状態を確認するにはShader.IsKeywordEnabledを利用します。
docs.unity3d.com
if (Shader.IsKeywordEnabled(_shaderKeywordRed)) { // ... }
マテリアルごとに設定されたキーワードの有効状態を確認するにはMaterial.IsKeywordEnabledを利用します。
docs.unity3d.com
// 対象のマテリアルの参照を取得する Material targetMaterial = _renderer.material; if (targetMaterial.IsKeywordEnabled(_shaderKeywordRed)) { // ... }
サンプルスクリプト
前回作成したスクリプトにキーワードの有効状態を確認する関数を追加しました。
・ShaderKeywordController.cs
using UnityEngine; public class ShaderKeywordController : MonoBehaviour { private readonly string _shaderKeywordRed = "FORCE_RED_COLOR"; private readonly string _shaderKeywordGreen = "FORCE_GREEN_COLOR"; private readonly string _shaderKeywordBlue = "FORCE_BLUE_COLOR"; [SerializeField] Renderer _renderer; /// <summary> /// 全てのキーワードを無効化する /// </summary> [ContextMenu("ResetShaderKeyword")] public void ResetShaderKeyword() { // シェーダのキーワードの定義を削除する Shader.DisableKeyword(_shaderKeywordRed); Shader.DisableKeyword(_shaderKeywordGreen); Shader.DisableKeyword(_shaderKeywordBlue); } /// <summary> /// シェーダー全体に赤色にするキーワードを有効化する /// </summary> [ContextMenu("SetShaderKeywordRed")] public void SetShaderKeywordRed() { // シェーダのキーワードの定義を追加する Shader.EnableKeyword(_shaderKeywordRed); // シェーダのキーワードの定義を削除する Shader.DisableKeyword(_shaderKeywordGreen); Shader.DisableKeyword(_shaderKeywordBlue); } /// <summary> /// 指定のレンダラーが保持するマテリアルのシェーダにのみ赤色にするキーワードを有効化する /// </summary> [ContextMenu("SetMaterialShaderKeywordRed")] public void SetMaterialShaderKeywordRed() { // マテリアルのシェーダのキーワードの定義を追加する _renderer.material.EnableKeyword(_shaderKeywordRed); // シェーダのキーワードの定義を削除する _renderer.material.DisableKeyword(_shaderKeywordGreen); _renderer.material.DisableKeyword(_shaderKeywordBlue); } /// <summary> /// シェーダの赤色のキーワードの定義が有効化されているか確認する /// </summary> [ContextMenu("CheckShaderKeywordRed")] public void CheckShaderKeywordRed() { // シェーダの赤色のキーワードの定義が有効化されているか確認する if (Shader.IsKeywordEnabled(_shaderKeywordRed)) { Debug.Log("Shader.IsKeywordEnabled:赤色のキーワードが有効化されています"); } else { Debug.Log("Shader.IsKeywordEnabled:赤色のキーワードが有効化されていません"); } } /// <summary> /// 指定のレンダラーが保持するマテリアルのシェーダの赤色のキーワードの定義が有効化されているか確認する /// </summary> [ContextMenu("CheckMaterialShaderKeywordRed")] public void CheckMaterialShaderKeywordRed() { // 指定のレンダラーが保持するマテリアルのシェーダの赤色のキーワードの定義が有効化されているか確認する if (_renderer.material.IsKeywordEnabled(_shaderKeywordRed)) { Debug.Log("Material.IsKeywordEnabled:赤色のキーワードが有効化されています"); } else { Debug.Log("Material.IsKeywordEnabled:赤色のキーワードが有効化されていません"); } } #if UNITY_EDITOR private void OnApplicationQuit() { ResetShaderKeyword(); } #endif }
スクリプトをシーンに設定して変更対象のマテリアルの参照を追加します。
動作確認
シーンを再生して動作を確認します。
Shader.IsKeywordEnabledの動作
Shader.IsKeywordEnabledはShader.EnableKeywordまたはShader.DisableKeywordで設定したキーワードの有効状態のみチェックします。
以下の通り、Shader.EnableKeywordで有効化した場合はShader.IsKeywordEnabledで検出できますが、Material.IsKeywordEnabledでは有効と判定されません。
Material.IsKeywordEnabledの動作
Material.IsKeywordEnabledは指定のマテリアルに対してMaterial.EnableKeywordまたはMaterial.DisableKeywordで設定したキーワードの有効状態のみチェックします。
以下の通り、Material.EnableKeywordで有効化した場合はMaterial.IsKeywordEnabledで検出できますが、Shader.IsKeywordEnabledでは有効と判定されません。