マテリアルエディタでシーンビューにハンドルを表示して、値をセットしてみました。
シェーダー
フルスクリーンカスタムパスで、プロパティに2つの位置を定義して、ワールド空間位置との距離を計算します。
- float depth = LoadCameraDepth(varyings.positionCS.xy);
- PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
-
- // 中心からの距離
- float dist = distance(posInput.positionWS, _CenterPos - _WorldSpaceCameraPos);
- float dist2 = distance(posInput.positionWS, _CenterPos2 - _WorldSpaceCameraPos);
step関数を使って、球の内側は白、外側は黒にします。
- // 球
- float sphere = 1 - step(_Radius, dist);
- float sphere2 = 1 - step(_Radius, dist2);
- //float sphere2 = step(0, _Radius - dist2);
排他的論理和を計算して色にかけてみました。
- // 合成する
- float result = frac(sphere * 0.5 + sphere2 * 0.5) * 2;
-
- return result * _Color;
このシェーダーを設定したマテリアルを作成して、カスタムパスにアタッチしました。
Material Editor
Editorフォルダに新規C#スクリプトを作成して、MaterialEditorクラスを継承させます。
- using UnityEngine;
- using UnityEditor;
-
- public class HandleTestMaterialEditor : MaterialEditor
- {
- private new void OnEnable()
- {
- // シーンビューのイベントを購読
- SceneView.duringSceneGui += OnSceneGUI;
- }
- private new void OnDisable()
- {
- // イベントの購読解除
- SceneView.duringSceneGui -= OnSceneGUI;
- }
- private void OnSceneGUI(SceneView sv)
- {
- // マテリアルを取得
- var mat = (Material)target;
-
- if (mat == null) return;
-
- // 値を取得
- Vector3 pos = mat.GetVector("_CenterPos");
- Vector3 pos2 = mat.GetVector("_CenterPos2");
-
- // GUI要素の変更をチェック開始
- EditorGUI.BeginChangeCheck();
-
- // ハンドルを表示
- pos = Handles.PositionHandle(pos, Quaternion.identity);
- pos2 = Handles.PositionHandle(pos2, Quaternion.identity);
-
- // ハンドルが操作されたとき
- if (EditorGUI.EndChangeCheck())
- {
- // 元に戻せるようにする
- Undo.RecordObject(target, "Move point");
-
- // 値をセット
- mat.SetVector("_CenterPos", pos);
- mat.SetVector("_CenterPos2", pos2);
- }
-
- }
- }
カスタムハンドルを実装するために、シーンビューのイベントを購読/解除しています。
- private new void OnEnable()
- {
- // シーンビューのイベントを購読
- SceneView.duringSceneGui += OnSceneGUI;
- }
- private new void OnDisable()
- {
- // イベントの購読解除
- SceneView.duringSceneGui -= OnSceneGUI;
- }
OnSceneGUIメソッドでは、マテリアルとプロパティの値を取得します。
- private void OnSceneGUI(SceneView sv)
- {
- // マテリアルを取得
- var mat = (Material)target;
-
- if (mat == null) return;
-
- // 値を取得
- Vector3 pos = mat.GetVector("_CenterPos");
- Vector3 pos2 = mat.GetVector("_CenterPos2");
ハンドルの変更のチェックを開始して、ハンドルを表示します。
- // GUI要素の変更をチェック開始
- EditorGUI.BeginChangeCheck();
-
- // ハンドルを表示
- pos = Handles.PositionHandle(pos, Quaternion.identity);
- pos2 = Handles.PositionHandle(pos2, Quaternion.identity);
変更があればUndoできるようにして、値をセットしています。
- // ハンドルが操作されたとき
- if (EditorGUI.EndChangeCheck())
- {
- // 元に戻せるようにする
- Undo.RecordObject(target, "Move point");
-
- // 値をセット
- mat.SetVector("_CenterPos", pos);
- mat.SetVector("_CenterPos2", pos2);
- }
シェーダーでマテリアルエディタのクラス名を指定します。
-
- // ...
- CustomEditor "HandleTestMaterialEditor"
- }
マテリアルを選択
Projectウィンドウでマテリアルを選択すると、シーンビューにハンドルが表示されました。