【Unity】Material Editorでシーンビューにハンドルを表示する

投稿者: | 2023-12-26

マテリアルエディタでシーンビューにハンドルを表示して、値をセットしてみました。

シェーダー

フルスクリーンカスタムパスで、プロパティに2つの位置を定義して、ワールド空間位置との距離を計算します。

  1. float depth = LoadCameraDepth(varyings.positionCS.xy);
  2. PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
  3.  
  4. // 中心からの距離
  5. float dist = distance(posInput.positionWS, _CenterPos - _WorldSpaceCameraPos);
  6. float dist2 = distance(posInput.positionWS, _CenterPos2 - _WorldSpaceCameraPos);

step関数を使って、球の内側は白、外側は黒にします。

  1. // 球
  2. float sphere = 1 - step(_Radius, dist);
  3. float sphere2 = 1 - step(_Radius, dist2);
  4. //float sphere2 = step(0, _Radius - dist2);

排他的論理和を計算して色にかけてみました。

  1. // 合成する
  2. float result = frac(sphere * 0.5 + sphere2 * 0.5) * 2;
  3.  
  4. return result * _Color;

このシェーダーを設定したマテリアルを作成して、カスタムパスにアタッチしました。

Material Editor

Editorフォルダに新規C#スクリプトを作成して、MaterialEditorクラスを継承させます。

  1. using UnityEngine;
  2. using UnityEditor;
  3.  
  4. public class HandleTestMaterialEditor : MaterialEditor
  5. {
  6. private new void OnEnable()
  7. {
  8. // シーンビューのイベントを購読
  9. SceneView.duringSceneGui += OnSceneGUI;
  10. }
  11. private new void OnDisable()
  12. {
  13. // イベントの購読解除
  14. SceneView.duringSceneGui -= OnSceneGUI;
  15. }
  16. private void OnSceneGUI(SceneView sv)
  17. {
  18. // マテリアルを取得
  19. var mat = (Material)target;
  20.  
  21. if (mat == null) return;
  22.  
  23. // 値を取得
  24. Vector3 pos = mat.GetVector("_CenterPos");
  25. Vector3 pos2 = mat.GetVector("_CenterPos2");
  26.  
  27. // GUI要素の変更をチェック開始
  28. EditorGUI.BeginChangeCheck();
  29.  
  30. // ハンドルを表示
  31. pos = Handles.PositionHandle(pos, Quaternion.identity);
  32. pos2 = Handles.PositionHandle(pos2, Quaternion.identity);
  33.  
  34. // ハンドルが操作されたとき
  35. if (EditorGUI.EndChangeCheck())
  36. {
  37. // 元に戻せるようにする
  38. Undo.RecordObject(target, "Move point");
  39.  
  40. // 値をセット
  41. mat.SetVector("_CenterPos", pos);
  42. mat.SetVector("_CenterPos2", pos2);
  43. }
  44.  
  45. }
  46. }

カスタムハンドルを実装するために、シーンビューのイベントを購読/解除しています。

  1. private new void OnEnable()
  2. {
  3. // シーンビューのイベントを購読
  4. SceneView.duringSceneGui += OnSceneGUI;
  5. }
  6. private new void OnDisable()
  7. {
  8. // イベントの購読解除
  9. SceneView.duringSceneGui -= OnSceneGUI;
  10. }

OnSceneGUIメソッドでは、マテリアルとプロパティの値を取得します。

  1. private void OnSceneGUI(SceneView sv)
  2. {
  3. // マテリアルを取得
  4. var mat = (Material)target;
  5.  
  6. if (mat == null) return;
  7.  
  8. // 値を取得
  9. Vector3 pos = mat.GetVector("_CenterPos");
  10. Vector3 pos2 = mat.GetVector("_CenterPos2");

ハンドルの変更のチェックを開始して、ハンドルを表示します。

  1. // GUI要素の変更をチェック開始
  2. EditorGUI.BeginChangeCheck();
  3.  
  4. // ハンドルを表示
  5. pos = Handles.PositionHandle(pos, Quaternion.identity);
  6. pos2 = Handles.PositionHandle(pos2, Quaternion.identity);

変更があればUndoできるようにして、値をセットしています。

  1. // ハンドルが操作されたとき
  2. if (EditorGUI.EndChangeCheck())
  3. {
  4. // 元に戻せるようにする
  5. Undo.RecordObject(target, "Move point");
  6.  
  7. // 値をセット
  8. mat.SetVector("_CenterPos", pos);
  9. mat.SetVector("_CenterPos2", pos2);
  10. }

シェーダーでマテリアルエディタのクラス名を指定します。

  1.  
  2. // ...
  3. CustomEditor "HandleTestMaterialEditor"
  4. }

マテリアルを選択

Projectウィンドウでマテリアルを選択すると、シーンビューにハンドルが表示されました。

コメントを残す

メールアドレスが公開されることはありません。