Replace UltimateXR with HurricaneVR
This commit is contained in:
513
Assets/HurricaneVR/Framework/Editor/HVRManagementWindow.cs
Normal file
513
Assets/HurricaneVR/Framework/Editor/HVRManagementWindow.cs
Normal file
@@ -0,0 +1,513 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using HurricaneVR.Framework.Core;
|
||||
using HurricaneVR.Framework.Core.HandPoser;
|
||||
using HurricaneVR.Framework.Core.Utils;
|
||||
using HurricaneVR.Framework.Shared;
|
||||
using HurricaneVR.Framework.Shared.Utilities;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using GameObject = UnityEngine.GameObject;
|
||||
|
||||
|
||||
namespace HurricaneVR.Editor
|
||||
{
|
||||
public class HVRManagementWindow : EditorWindow
|
||||
{
|
||||
private ObjectField grabbableObjectField;
|
||||
private ObjectField posableObjectField;
|
||||
private ObjectField grabPointsObjectField;
|
||||
private UnityEditor.Editor _poserEditor;
|
||||
private VisualElement _poserRoot;
|
||||
private TextField _recordedPrefixTextBox;
|
||||
private VisualElement _root;
|
||||
private ScrollView _scrollView;
|
||||
|
||||
[MenuItem("Tools/HurricaneVR/Posing")]
|
||||
public static void ShowExample()
|
||||
{
|
||||
HVRManagementWindow wnd = GetWindow<HVRManagementWindow>();
|
||||
wnd.titleContent = new GUIContent("HVR Posing");
|
||||
}
|
||||
|
||||
public const string GrabbleName = "VRPoser_Grabbable";
|
||||
|
||||
public GameObject SelectedGrabPoints
|
||||
{
|
||||
get
|
||||
{
|
||||
var obj = grabPointsObjectField.value as GameObject;
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
public GameObject SelectedPoser
|
||||
{
|
||||
get
|
||||
{
|
||||
return posableObjectField.value as GameObject;
|
||||
}
|
||||
}
|
||||
|
||||
public GameObject SelectedGrabbable
|
||||
{
|
||||
get
|
||||
{
|
||||
return grabbableObjectField.value as GameObject;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
_root = rootVisualElement;
|
||||
var visualTree = UnityEngine.Resources.Load<VisualTreeAsset>("HVRManagementWindow");
|
||||
_root.Add(visualTree.CloneTree());
|
||||
|
||||
_scrollView = _root.Q<ScrollView>("ScrollView");
|
||||
|
||||
SetupObjectFields(_root);
|
||||
SetupFocusButtons(_root);
|
||||
SetupAddPoser(_root);
|
||||
SetupPoseSelected(_root);
|
||||
|
||||
var list = _root.Q<VisualElement>("RecordedPoses");
|
||||
list.styleSheets.Add(Resources.Load<StyleSheet>("HVRManagementWindow"));
|
||||
_recordedPrefixTextBox = _root.Q<TextField>("RecordedPrefixTextBox");
|
||||
|
||||
SetupButtons(_root);
|
||||
}
|
||||
|
||||
public ListView PosesListView { get; set; }
|
||||
private List<HVRHandPose> Poses { get; set; }
|
||||
|
||||
private void SetupPosesListView(List<HVRHandPose> poses)
|
||||
{
|
||||
var posesParent = GameObject.Find("RecordedPosesCloneHolder");
|
||||
if (!posesParent)
|
||||
{
|
||||
posesParent = new GameObject("RecordedPosesCloneHolder");
|
||||
}
|
||||
|
||||
foreach (Transform child in posesParent.transform)
|
||||
{
|
||||
DestroyImmediate(child.gameObject);
|
||||
}
|
||||
|
||||
Poses = poses;
|
||||
var listview = _root.Q<ScrollView>("RecordedPoses");
|
||||
listview.Clear();
|
||||
|
||||
foreach (var pose in poses)
|
||||
{
|
||||
var row = new VisualElement();
|
||||
row.AddToClassList("poserow");
|
||||
|
||||
var field = new ObjectField("Pose:");
|
||||
field.objectType = typeof(HVRHandPose);
|
||||
field.value = pose;
|
||||
row.Add(field);
|
||||
field.AddToClassList("poserow-field");
|
||||
|
||||
var clone = Instantiate(HVRSettings.Instance.GetPoserHand(pose.SnappedLeft ? HVRHandSide.Left : HVRHandSide.Right), posesParent.transform, true);
|
||||
|
||||
var posableHand = clone.GetComponent<HVRPosableHand>();
|
||||
if (posableHand != null)
|
||||
{
|
||||
posableHand.Pose(pose);
|
||||
}
|
||||
|
||||
var attach = new Button(() =>
|
||||
{
|
||||
if (!SelectedGrabPoints)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error!", "Please set GrabPoints field.", "Ok!");
|
||||
return;
|
||||
}
|
||||
|
||||
var grabPoint = new GameObject("GrabPoint");
|
||||
grabPoint.transform.parent = SelectedGrabPoints.transform;
|
||||
grabPoint.transform.localPosition = Vector3.zero;
|
||||
var poser = grabPoint.AddComponent<HVRHandPoser>();
|
||||
var posable = grabPoint.AddComponent<HVRPosableGrabPoint>();
|
||||
posable.HandPoser = poser;
|
||||
grabPoint.transform.localPosition = Vector3.zero;//.position = pose.SnappedLeft ? pose.LeftHand.Position : pose.RightHand.Position;
|
||||
grabPoint.transform.localRotation = Quaternion.identity;
|
||||
|
||||
var clonedPose = posableHand.CreateFullHandPose(posableHand.MirrorAxis);
|
||||
|
||||
clonedPose.RightHand.Rotation = Quaternion.Inverse(grabPoint.transform.rotation) * clonedPose.RightHand.Rotation;
|
||||
clonedPose.LeftHand.Rotation = Quaternion.Inverse(grabPoint.transform.rotation) * clonedPose.LeftHand.Rotation;
|
||||
|
||||
clonedPose.RightHand.Position = Vector3.zero;
|
||||
clonedPose.LeftHand.Position = Vector3.zero;
|
||||
|
||||
poser.PrimaryPose = new HVRHandPoseBlend();
|
||||
poser.PrimaryPose.Pose = clonedPose;
|
||||
poser.PrimaryPose.SetDefaults();
|
||||
|
||||
var grabbable = grabPoint.GetComponentInParent<HVRGrabbable>();
|
||||
string name;
|
||||
if (grabbable)
|
||||
{
|
||||
name = grabbable.name + "-" + pose.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = DateTime.Now.Ticks.ToString();
|
||||
}
|
||||
|
||||
poser.PrimaryPose.Pose = HVRSettings.Instance.SavePoseToDefault(clonedPose, name, "");
|
||||
|
||||
|
||||
//EditorUtility.SetDirty(pose);
|
||||
//AssetDatabase.SaveAssets();
|
||||
//AssetDatabase.Refresh();
|
||||
|
||||
})
|
||||
{
|
||||
text = "Attach"
|
||||
};
|
||||
|
||||
var delete = new Button(() =>
|
||||
{
|
||||
row.RemoveFromHierarchy();
|
||||
DestroyImmediate(clone);
|
||||
})
|
||||
{ text = "-" };
|
||||
|
||||
var focus = new Button(() =>
|
||||
{
|
||||
Selection.activeGameObject = clone;
|
||||
SceneView.FrameLastActiveSceneView();
|
||||
|
||||
})
|
||||
{ text = "Focus" };
|
||||
|
||||
attach.AddToClassList("poserow-button");
|
||||
delete.AddToClassList("poserow-button");
|
||||
focus.AddToClassList("poserow-button");
|
||||
|
||||
row.Add(focus);
|
||||
row.Add(attach);
|
||||
row.Add(delete);
|
||||
|
||||
listview.Insert(listview.childCount, row);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void SetupButtons(VisualElement root)
|
||||
{
|
||||
var button = root.Q<Button>("SetGrabPoints");
|
||||
button.clickable.clicked += () =>
|
||||
{
|
||||
if (Selection.activeGameObject) grabPointsObjectField.value = Selection.activeGameObject;
|
||||
};
|
||||
|
||||
button = root.Q<Button>("SetGrabbable");
|
||||
button.clickable.clicked += () =>
|
||||
{
|
||||
if (Selection.activeGameObject) grabbableObjectField.value = Selection.activeGameObject;
|
||||
};
|
||||
|
||||
button = root.Q<Button>("ExpandGrabbable");
|
||||
button.clickable.clicked += () =>
|
||||
{
|
||||
if (SelectedGrabbable) SelectedGrabbable.SetExpandedRecursive(true);
|
||||
};
|
||||
|
||||
button = root.Q<Button>("CollapseGrabbable");
|
||||
button.clickable.clicked += () =>
|
||||
{
|
||||
if (SelectedGrabbable) SelectedGrabbable.SetExpandedRecursive(false);
|
||||
};
|
||||
|
||||
button = root.Q<Button>("ExpandGrabPoints");
|
||||
button.clickable.clicked += () =>
|
||||
{
|
||||
if (SelectedGrabPoints) SelectedGrabPoints.SetExpandedRecursive(true);
|
||||
};
|
||||
|
||||
button = root.Q<Button>("CollapseGrabPoints");
|
||||
button.clickable.clicked += () =>
|
||||
{
|
||||
if (SelectedGrabPoints) SelectedGrabPoints.SetExpandedRecursive(false);
|
||||
};
|
||||
|
||||
root.Q<Button>("SetupGrabbable").clickable.clicked += () =>
|
||||
{
|
||||
if (SelectedGrabbable == null || SelectedGrabbable != Selection.activeGameObject)
|
||||
{
|
||||
grabbableObjectField.value = Selection.activeGameObject;
|
||||
AddGrabbable(Selection.activeGameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddGrabbable(SelectedGrabbable);
|
||||
}
|
||||
};
|
||||
|
||||
root.Q<Button>("AddGrabPoints").clickable.clicked += () =>
|
||||
{
|
||||
AddGrabPoints(SelectedGrabbable ? SelectedGrabbable : Selection.activeGameObject);
|
||||
};
|
||||
|
||||
root.Q<Button>("AddGrabPointButton").clickable.clicked += () =>
|
||||
{
|
||||
if (!SelectedGrabPoints) return;
|
||||
AddGrabPoint(SelectedGrabPoints);
|
||||
SelectedGrabPoints.SetExpandedRecursive(true);
|
||||
};
|
||||
|
||||
root.Q<Button>("SetupGrabPoints").clickable.clicked += () =>
|
||||
{
|
||||
if (!SelectedGrabbable) return;
|
||||
var grabbable = SelectedGrabbable.GetComponent<HVRGrabbable>();
|
||||
if (grabbable != null) grabbable.PopulateGrabPoints();
|
||||
EditorUtility.SetDirty(grabbable);
|
||||
};
|
||||
|
||||
root.Q<Button>("LoadPoses").clickable.clicked += () =>
|
||||
{
|
||||
var path = EditorUtility.OpenFolderPanel("Load poses", HVRSettings.Instance.GetRuntimePosesDirectory(), "");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var files = Directory.GetFiles(path);
|
||||
|
||||
var poses = new List<HVRHandPose>();
|
||||
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (file.EndsWith(".asset"))
|
||||
{
|
||||
var start = file.IndexOf("Assets");
|
||||
var localPath = file.Substring(start).Replace("\\", "/");
|
||||
var pose = AssetDatabase.LoadAssetAtPath<HVRHandPose>(localPath);
|
||||
poses.Add(pose);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
SetupPosesListView(poses);
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
public Toggle ToggleSteam { get; set; }
|
||||
|
||||
public Toggle ToggleOculus { get; set; }
|
||||
|
||||
private void AddGrabbable(GameObject obj)
|
||||
{
|
||||
if (!obj) return;
|
||||
|
||||
var grabbable = obj.GetComponent<HVRGrabbable>();
|
||||
var physicsGrabbable = obj.GetComponent<HVRPhysicsGrabbable>();
|
||||
if (!grabbable && !physicsGrabbable)
|
||||
{
|
||||
obj.AddComponent<HVRGrabbable>();
|
||||
}
|
||||
|
||||
if (AddGrabPoints(obj))
|
||||
{
|
||||
AddGrabPoint(SelectedGrabPoints);
|
||||
}
|
||||
|
||||
obj.SetExpandedRecursive(true);
|
||||
}
|
||||
|
||||
private GameObject AddGrabPoint(GameObject obj)
|
||||
{
|
||||
var grabPoint = new GameObject("GrabPoint");
|
||||
grabPoint.transform.parent = obj.transform;
|
||||
grabPoint.transform.ResetLocalProps();
|
||||
var poser = grabPoint.AddComponent<HVRHandPoser>();
|
||||
var posable = grabPoint.AddComponent<HVRPosableGrabPoint>();
|
||||
posable.HandPoser = poser;
|
||||
|
||||
posableObjectField.value = grabPoint;
|
||||
|
||||
return grabPoint;
|
||||
}
|
||||
|
||||
private bool AddGrabPoints(GameObject obj)
|
||||
{
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
var points = obj.GetComponentInChildren<HVRGrabPoints>()?.gameObject;
|
||||
|
||||
if (points)
|
||||
{
|
||||
if (!EditorUtility.DisplayDialog("Warning!", "GrabPoint component exists in children, add another?", "Yes", "No"))
|
||||
{
|
||||
Debug.Log($"This object already has a child VRGrabPoints");
|
||||
grabPointsObjectField.value = points;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
points = new GameObject("GrabPoints");
|
||||
var vrGrabPoints = points.AddComponent<HVRGrabPoints>();
|
||||
points.transform.parent = obj.transform;
|
||||
points.transform.ResetLocalProps();
|
||||
//vrGrabPoints.AddRunTimePoses();
|
||||
//AddGrabPoint(points);
|
||||
|
||||
grabPointsObjectField.value = points;
|
||||
obj.SetExpandedRecursive(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetupObjectFields(VisualElement root)
|
||||
{
|
||||
posableObjectField = root.Q<ObjectField>("VRHandPoser");
|
||||
posableObjectField.objectType = typeof(GameObject);
|
||||
|
||||
posableObjectField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
if (evt.newValue)
|
||||
{
|
||||
var obj = evt.newValue as GameObject;
|
||||
var poser = obj.GetComponent<HVRHandPoser>();
|
||||
if (poser != null)
|
||||
{
|
||||
SetupPoser(root, poser);
|
||||
}
|
||||
else
|
||||
{
|
||||
CleanupPoserEditor();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CleanupPoserEditor();
|
||||
}
|
||||
});
|
||||
|
||||
grabbableObjectField = root.Q<ObjectField>("Grabbable");
|
||||
grabbableObjectField.objectType = typeof(GameObject);
|
||||
|
||||
grabbableObjectField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
});
|
||||
|
||||
if (posableObjectField.value)
|
||||
{
|
||||
var obj = posableObjectField.value as GameObject;
|
||||
|
||||
var poser = obj.GetComponent<HVRHandPoser>();
|
||||
if (poser != null)
|
||||
{
|
||||
SetupPoser(root, poser);
|
||||
}
|
||||
}
|
||||
|
||||
grabPointsObjectField = root.Q<ObjectField>("GrabPointsObject");
|
||||
grabPointsObjectField.objectType = typeof(GameObject);
|
||||
}
|
||||
|
||||
private void SetupPoser(VisualElement root, HVRHandPoser poser)
|
||||
{
|
||||
CleanupPoserEditor();
|
||||
|
||||
_poserEditor = UnityEditor.Editor.CreateEditor(poser);
|
||||
_poserRoot = _poserEditor.CreateInspectorGUI();
|
||||
//root.Add(_poserRoot);
|
||||
_scrollView.Add(_poserRoot);
|
||||
_poserRoot.Unbind();
|
||||
_poserRoot.Bind(_poserEditor.serializedObject);
|
||||
}
|
||||
|
||||
private void CleanupPoserEditor()
|
||||
{
|
||||
if (_poserRoot != null)
|
||||
{
|
||||
_poserRoot.Clear();
|
||||
_poserRoot.RemoveFromHierarchy();
|
||||
}
|
||||
|
||||
if (_poserEditor != null)
|
||||
{
|
||||
DestroyImmediate(_poserEditor);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupAddPoser(VisualElement root)
|
||||
{
|
||||
var button = root.Q<ToolbarButton>("AddPoser");
|
||||
button.clickable.clicked += () =>
|
||||
{
|
||||
if (!SelectedPoser) return;
|
||||
|
||||
var poser = SelectedPoser.GetComponent<HVRHandPoser>();
|
||||
if (poser == null)
|
||||
{
|
||||
poser = SelectedPoser.AddComponent<HVRHandPoser>();
|
||||
SetupPoser(root, poser);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private void SetupFocusButtons(VisualElement root)
|
||||
{
|
||||
root.Q<Button>("FocusPoser").clickable.clicked += () =>
|
||||
{
|
||||
if (SelectedPoser) Selection.activeGameObject = SelectedPoser;
|
||||
};
|
||||
|
||||
root.Q<Button>("FocusGrabbable").clickable.clicked += () =>
|
||||
{
|
||||
if (SelectedGrabbable) Selection.activeGameObject = SelectedGrabbable;
|
||||
};
|
||||
|
||||
root.Q<Button>("FocusGrabPoints").clickable.clicked += () =>
|
||||
{
|
||||
if (SelectedGrabPoints) Selection.activeGameObject = SelectedGrabPoints;
|
||||
};
|
||||
}
|
||||
|
||||
private void SetupPoseSelected(VisualElement root)
|
||||
{
|
||||
var button = root.Q<Button>("SetPoser");
|
||||
button.clickable.clicked += () =>
|
||||
{
|
||||
if (Selection.activeGameObject != null) posableObjectField.value = Selection.activeGameObject;
|
||||
};
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
CleanupPoserEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user