1168 lines
49 KiB
C#
1168 lines
49 KiB
C#
using UnityEditor;
|
|
using UnityEngine;
|
|
#if UNITY_2021_2_OR_NEWER
|
|
using UnityEditor.SceneManagement;
|
|
#else
|
|
using UnityEditor.Experimental.SceneManagement;
|
|
#endif
|
|
#if hPHOTON2
|
|
using Photon.Pun;
|
|
#endif
|
|
|
|
namespace Passer {
|
|
using Humanoid;
|
|
|
|
[CanEditMultipleObjects]
|
|
[HelpURLAttribute("http://passervr.com/documentation/humanoid-control/")]
|
|
[CustomEditor(typeof(HumanoidControl), true)]
|
|
public class HumanoidControl_Editor : Editor {
|
|
|
|
protected HumanoidControl humanoid;
|
|
protected GameObject realWorld;
|
|
|
|
private bool settingAvatar;
|
|
|
|
#region Enable
|
|
|
|
public void OnEnable() {
|
|
ConfigurationCheck.CheckXrSdks();
|
|
humanoid = (HumanoidControl)target;
|
|
if (humanoid == null)
|
|
return;
|
|
|
|
humanoid.path = Configuration_Editor.FindHumanoidFolder();
|
|
|
|
if (humanoid.gameObject.name.EndsWith("_prefab"))
|
|
humanoid.gameObject.name = humanoid.gameObject.name.Substring(0, humanoid.gameObject.name.Length - 7);
|
|
|
|
if (humanoid.disconnectInstances) {
|
|
PrefabInstanceStatus prefabInstanceStatus = PrefabUtility.GetPrefabInstanceStatus(humanoid.gameObject);
|
|
if (prefabInstanceStatus == PrefabInstanceStatus.Connected) {
|
|
Debug.Log("Unpacking Prefab Instance for Humanoid");
|
|
PrefabUtility.UnpackPrefabInstance(humanoid.gameObject, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction);
|
|
}
|
|
}
|
|
|
|
if (!IsPrefab(humanoid)) {
|
|
CheckHumanoidId(humanoid);
|
|
|
|
CheckAvatar(humanoid);
|
|
InitTargets();
|
|
}
|
|
else {
|
|
humanoid.DetermineTargets();
|
|
}
|
|
InitTrackers(humanoid);
|
|
InitPose();
|
|
InitSettings();
|
|
InitNetworking();
|
|
|
|
realWorld = HumanoidControl.GetRealWorld(humanoid.transform);
|
|
|
|
SetScriptingOrder((MonoBehaviour)target);
|
|
}
|
|
|
|
private void SetScriptingOrder(MonoBehaviour target) {
|
|
MonoScript monoScript = MonoScript.FromMonoBehaviour(target);
|
|
int currentExecutionOrder = MonoImporter.GetExecutionOrder(monoScript);
|
|
|
|
if (currentExecutionOrder <= 0) {
|
|
MonoImporter.SetExecutionOrder(monoScript, 1000);
|
|
}
|
|
}
|
|
|
|
#region HumanoidId
|
|
private static void CheckHumanoidId(HumanoidControl humanoid) {
|
|
if (humanoid.humanoidId >= 0)
|
|
return;
|
|
|
|
HumanoidControl[] humanoids = FindObjectsOfType<HumanoidControl>();
|
|
for (int i = 0; i < humanoids.Length; i++) {
|
|
humanoids[i].humanoidId = i;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Disable
|
|
|
|
public void OnDisable() {
|
|
CleanupStuff();
|
|
|
|
if (Application.isPlaying)
|
|
return;
|
|
|
|
HumanoidControl humanoid = (HumanoidControl)target;
|
|
if (humanoid == null)
|
|
return;
|
|
}
|
|
|
|
#if hPHOTON1 || hPHOTON2
|
|
private PhotonView cleanupPhotonView;
|
|
#endif
|
|
private void CleanupStuff() {
|
|
#if hPHOTON1 || hPHOTON2
|
|
if (cleanupPhotonView) {
|
|
DestroyImmediate(cleanupPhotonView, true);
|
|
cleanupPhotonView = null;
|
|
}
|
|
#endif
|
|
}
|
|
#endregion
|
|
|
|
#region Destroy
|
|
public void OnDestroy() {
|
|
if (Application.isPlaying || target != null || humanoid == null || IsPrefab(humanoid))
|
|
return;
|
|
|
|
if (realWorld != null)
|
|
DestroyImmediate(realWorld, true);
|
|
|
|
if (humanoid.headTarget != null)
|
|
DestroyImmediate(humanoid.headTarget.gameObject, true);
|
|
if (humanoid.leftHandTarget != null)
|
|
DestroyImmediate(humanoid.leftHandTarget.gameObject, true);
|
|
if (humanoid.rightHandTarget != null)
|
|
DestroyImmediate(humanoid.rightHandTarget.gameObject, true);
|
|
if (humanoid.hipsTarget != null)
|
|
DestroyImmediate(humanoid.hipsTarget.gameObject, true);
|
|
if (humanoid.leftFootTarget != null)
|
|
DestroyImmediate(humanoid.leftFootTarget.gameObject, true);
|
|
if (humanoid.rightFootTarget != null)
|
|
DestroyImmediate(humanoid.rightFootTarget.gameObject, true);
|
|
|
|
if (humanoid.targetsRig != null)
|
|
DestroyImmediate(humanoid.targetsRig.gameObject, true);
|
|
}
|
|
#endregion
|
|
|
|
#region Inspector
|
|
|
|
public override void OnInspectorGUI() {
|
|
serializedObject.Update();
|
|
|
|
HumanoidControl humanoid = (HumanoidControl)target;
|
|
|
|
PlayerTypeInspector();
|
|
|
|
if (humanoid.gameObject.name.EndsWith("_prefab"))
|
|
humanoid.gameObject.name = humanoid.gameObject.name.Substring(0, humanoid.gameObject.name.Length - 7);
|
|
|
|
if (humanoid.avatarRig == null) {
|
|
EditorGUILayout.HelpBox("Could not detect suitable avatar", MessageType.Warning);
|
|
// Even without an avatar, we still need a target rig!
|
|
//if (humanoid.targetsRig != null)
|
|
// DestroyImmediate(humanoid.targetsRig.gameObject, true);
|
|
}
|
|
|
|
TargetsInspector(humanoid);
|
|
|
|
if (humanoid.headTarget == null || humanoid.leftHandTarget == null || humanoid.rightHandTarget == null || humanoid.hipsTarget == null ||
|
|
humanoid.leftFootTarget == null || humanoid.rightFootTarget == null)
|
|
// targets could have been deleted in the hierarchy
|
|
return;
|
|
|
|
TrackerInspectors();
|
|
PoseInspector();
|
|
NetworkingInspector(humanoid);
|
|
MovementInspector();
|
|
SettingsInspector();
|
|
Buttons();
|
|
|
|
serializedObject.ApplyModifiedProperties();
|
|
}
|
|
|
|
protected void PlayerTypeInspector() {
|
|
//Players players = Players_Editor.GetPlayers();
|
|
//if (players.playerTypes.Length <= 1)
|
|
// return;
|
|
|
|
//SerializedProperty playerTypeProp = serializedObject.FindProperty("playerType");
|
|
//playerTypeProp.intValue = EditorGUILayout.Popup("Player Type", playerTypeProp.intValue, players.playerTypes);
|
|
}
|
|
|
|
#region Avatar
|
|
|
|
public static void CheckAvatar(HumanoidControl humanoid) {
|
|
if (humanoid == null || IsPrefab(humanoid) || !humanoid.gameObject.activeInHierarchy)
|
|
return;
|
|
|
|
humanoid.avatarRig = humanoid.GetAvatar(humanoid.gameObject);
|
|
if (humanoid.avatarRig != null) {
|
|
// these need to be zero to avoid problems with the avatar being at an different position than the player
|
|
if (humanoid.avatarRig.transform != humanoid.transform) {
|
|
humanoid.avatarRig.transform.localPosition = Vector3.zero;
|
|
humanoid.avatarRig.transform.localRotation = Quaternion.identity;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SetAvatar(HumanoidControl ivr) {
|
|
if (GUILayout.Button("Set Avatar")) {
|
|
int controlID = EditorGUIUtility.GetControlID(FocusType.Passive);
|
|
settingAvatar = true;
|
|
EditorGUIUtility.ShowObjectPicker<GameObject>(null, false, "avatar", controlID);
|
|
}
|
|
if (settingAvatar && UnityEngine.Event.current.commandName == "ObjectSelectorUpdated") {
|
|
Animator[] animators = ivr.GetComponentsInChildren<Animator>();
|
|
foreach (Animator animator in animators)
|
|
DestroyImmediate(animator.gameObject);
|
|
GameObject prefab = (GameObject)EditorGUIUtility.GetObjectPickerObject();
|
|
if (prefab != null) {
|
|
GameObject avatar = Instantiate(prefab);
|
|
avatar.name = prefab.name;
|
|
avatar.transform.parent = ivr.transform;
|
|
avatar.transform.localPosition = Vector3.zero;
|
|
avatar.transform.localRotation = Quaternion.identity;
|
|
}
|
|
}
|
|
if (settingAvatar && UnityEngine.Event.current.commandName == "ObjectSelectorClosed") {
|
|
settingAvatar = false;
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Targets
|
|
private void InitTargets() {
|
|
TargetsRigInspector(humanoid);
|
|
|
|
if (!HeadTarget.IsInitialized(humanoid) ||
|
|
!HandTarget.IsInitialized(humanoid) ||
|
|
!HipsTarget.IsInitialized(humanoid) ||
|
|
!FootTarget.IsInitialized(humanoid)) {
|
|
|
|
humanoid.DetermineTargets();
|
|
humanoid.RetrieveBones();
|
|
humanoid.InitAvatar();
|
|
humanoid.MatchTargetsToAvatar();
|
|
}
|
|
|
|
humanoid.InitTargets();
|
|
}
|
|
|
|
private static void TargetsRigInspector(HumanoidControl humanoid) {
|
|
HumanoidControl.CheckTargetRig(humanoid);
|
|
|
|
if (humanoid.targetsRig.gameObject.hideFlags != HideFlags.None) {
|
|
humanoid.targetsRig.gameObject.hideFlags = HideFlags.None;
|
|
EditorApplication.DirtyHierarchyWindowSorting();
|
|
}
|
|
//else if (!humanoid.showTargetRig && humanoid.targetsRig.gameObject.hideFlags != HideFlags.HideInHierarchy) {
|
|
// humanoid.targetsRig.gameObject.hideFlags = HideFlags.HideInHierarchy;
|
|
// EditorApplication.DirtyHierarchyWindowSorting();
|
|
//}
|
|
}
|
|
|
|
static bool showTargets;
|
|
private void TargetsInspector(HumanoidControl humanoid) {
|
|
GUIContent text = new GUIContent(
|
|
"Targets",
|
|
"The target transforms controlling the body parts"
|
|
);
|
|
showTargets = EditorGUILayout.Foldout(showTargets, text, true);
|
|
|
|
if (showTargets) {
|
|
EditorGUI.indentLevel++;
|
|
humanoid.headTarget = (HeadTarget)HumanoidTarget_Editor.Inspector(humanoid.headTarget, "Head Target");
|
|
humanoid.leftHandTarget = (HandTarget)HandTarget_Editor.Inspector(humanoid.leftHandTarget, "Left Hand Target");
|
|
humanoid.rightHandTarget = (HandTarget)HandTarget_Editor.Inspector(humanoid.rightHandTarget, "Right Hand Target");
|
|
humanoid.hipsTarget = (HipsTarget)HumanoidTarget_Editor.Inspector(humanoid.hipsTarget, "Hips Target");
|
|
humanoid.leftFootTarget = (FootTarget)FootTarget_Editor.Inspector(humanoid.leftFootTarget, "Left Foot Target");
|
|
humanoid.rightFootTarget = (FootTarget)FootTarget_Editor.Inspector(humanoid.rightFootTarget, "Right Foot Target");
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Trackers
|
|
|
|
private HumanoidTargetObjs targetObjs;
|
|
private HumanoidTrackerProps[] allTrackerProps;
|
|
|
|
public void InitTrackers(HumanoidControl humanoid) {
|
|
targetObjs = new HumanoidTargetObjs(humanoid);
|
|
|
|
allTrackerProps = new HumanoidTrackerProps[] {
|
|
#if pUNITYXR
|
|
new UnityXR_Editor.TrackerProps(serializedObject, targetObjs, humanoid.unityXR),
|
|
#endif
|
|
//#if hOPENVR && (UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX)
|
|
// new OpenVR_Editor.TrackerProps(serializedObject, targetObjs, humanoid.openVR),
|
|
//#endif
|
|
//#if hSTEAMVR && UNITY_STANDALONE_WIN
|
|
// //new SteamVR_Editor.TrackerProps(serializedObject, targetObjs, humanoid.steamVR),
|
|
//#endif
|
|
//#if hOCULUS && (UNITY_STANDALONE_WIN || UNITY_ANDROID)
|
|
// new Oculus_Editor.TrackerProps(serializedObject, targetObjs, humanoid.oculus),
|
|
//#endif
|
|
#if hWINDOWSMR && UNITY_WSA_10_0
|
|
new WindowsMR_Editor.TrackerProps(serializedObject, targetObjs, humanoid.mixedReality),
|
|
|
|
#endif
|
|
#if hWAVEVR
|
|
new WaveVR_Editor.TrackerProps(serializedObject, targetObjs, humanoid.waveVR),
|
|
#endif
|
|
#if hVRTK
|
|
new Vrtk_Editor.TrackerProps(serializedObject, targetObjs, humanoid.vrtk),
|
|
#endif
|
|
#if hHYDRA && (UNITY_STANDALONE_WIN || UNITY_WSA_10_0)
|
|
new Hydra_Editor.TrackerProps(serializedObject, targetObjs, humanoid.hydra),
|
|
#endif
|
|
#if hLEAP && (UNITY_STANDALONE_WIN || UNITY_WSA_10_0)
|
|
new LeapMotion_Editor.TrackerProps(serializedObject, targetObjs, humanoid.leapTracker),
|
|
#endif
|
|
#if hKINECT1 && (UNITY_STANDALONE_WIN || UNITY_WSA_10_0)
|
|
new Kinect1_Editor.TrackerProps(serializedObject, targetObjs, humanoid.kinect1),
|
|
#endif
|
|
#if hKINECT2 && (UNITY_STANDALONE_WIN || UNITY_WSA_10_0)
|
|
new Kinect2_Editor.TrackerProps(serializedObject, targetObjs, humanoid.kinect2),
|
|
#endif
|
|
#if hKINECT4 && (UNITY_STANDALONE_WIN || UNITY_WSA_10_0)
|
|
new Kinect4_Editor.TrackerProps(serializedObject, targetObjs, humanoid.kinect4),
|
|
#endif
|
|
#if hORBBEC && (UNITY_STANDALONE_WIN || UNITY_ANDROID)
|
|
new Astra_Editor.TrackerProps(serializedObject, targetObjs, humanoid.astra),
|
|
#endif
|
|
#if hREALSENSE && (UNITY_STANDALONE_WIN || UNITY_WSA_10_0)
|
|
new Realsense_Editor.TrackerProps(serializedObject, targetObjs, humanoid.realsense),
|
|
#endif
|
|
#if hOPTITRACK && (UNITY_STANDALONE_WIN)
|
|
new Optitrack_Editor.TrackerProps(serializedObject, targetObjs, humanoid.optitrack),
|
|
#endif
|
|
#if hNEURON && (UNITY_STANDALONE_WIN)
|
|
new Neuron_Editor.TrackerProps(serializedObject, targetObjs, humanoid.neuronTracker),
|
|
#endif
|
|
#if hTOBII && (UNITY_STANDALONE_WIN)
|
|
new Tobii_Editor.TrackerProps(serializedObject, targetObjs, humanoid.tobiiTracker),
|
|
#endif
|
|
#if hARKIT && hFACE && UNITY_IOS && UNITY_2019_1_OR_NEWER
|
|
new ArKit_Editor.TrackerProps(serializedObject, targetObjs, humanoid.arkit),
|
|
#endif
|
|
#if hDLIB && (UNITY_STANDALONE_WIN)
|
|
new Dlib_Editor.TrackerProps(serializedObject, targetObjs, humanoid.dlib),
|
|
#endif
|
|
#if hPUPIL && (UNITY_STANDALONE_WIN)
|
|
new Tracking.Pupil.Pupil_Editor.TrackerProps(serializedObject, targetObjs, humanoid.pupil),
|
|
#endif
|
|
#if hANTILATENCY
|
|
new Antilatency_Editor.TrackerProps(serializedObject, targetObjs, humanoid.antilatency),
|
|
#endif
|
|
#if hHI5
|
|
new Hi5_Editor.TrackerProps(serializedObject, targetObjs, humanoid.hi5),
|
|
#endif
|
|
#if hCUSTOM
|
|
new Custom_Editor.TrackerProps(serializedObject, targetObjs, humanoid.custom),
|
|
#endif
|
|
};
|
|
|
|
InitAnimations(humanoid);
|
|
}
|
|
|
|
private bool showTrackers = true;
|
|
protected void TrackerInspectors() {
|
|
GUIContent text = new GUIContent(
|
|
"Input",
|
|
"Activate supported tracking devices for this humanoid"
|
|
);
|
|
showTrackers = EditorGUILayout.Foldout(showTrackers, text, true);
|
|
|
|
if (showTrackers) {
|
|
EditorGUI.indentLevel++;
|
|
|
|
if (targetObjs != null)
|
|
targetObjs.Update();
|
|
if (allTrackerProps != null) {
|
|
foreach (HumanoidTrackerProps props in allTrackerProps)
|
|
props.Inspector(humanoid);
|
|
}
|
|
if (targetObjs != null)
|
|
targetObjs.ApplyModifiedProperties();
|
|
|
|
AnimatorInspector(humanoid);
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
}
|
|
|
|
#region Animations
|
|
|
|
private SerializedProperty animatorParamForwardProp;
|
|
private SerializedProperty animatorParamSidewardProp;
|
|
private SerializedProperty animatorParamRotationProp;
|
|
private SerializedProperty animatorParamHeightProp;
|
|
|
|
|
|
private void InitAnimations(HumanoidControl humanoid) {
|
|
|
|
animatorParamForwardProp = serializedObject.FindProperty("animatorParameterForwardIndex");
|
|
animatorParamSidewardProp = serializedObject.FindProperty("animatorParameterSidewardIndex");
|
|
animatorParamRotationProp = serializedObject.FindProperty("animatorParameterRotationIndex");
|
|
animatorParamHeightProp = serializedObject.FindProperty("animatorParameterHeightIndex");
|
|
}
|
|
|
|
bool showAnimatorParameters = false;
|
|
private void AnimatorInspector(HumanoidControl humanoid) {
|
|
AnimatorControllerInspector(humanoid);
|
|
AnimatorParametersInspector(humanoid);
|
|
}
|
|
|
|
private void AnimatorControllerInspector(HumanoidControl humanoid) {
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
SerializedProperty animatorEnabledProp = serializedObject.FindProperty("animatorEnabled");
|
|
GUIContent text = new GUIContent(
|
|
"Animator",
|
|
"Standard Unity Animator Controller for animating the character"
|
|
);
|
|
animatorEnabledProp.boolValue = EditorGUILayout.ToggleLeft(text, animatorEnabledProp.boolValue, GUILayout.Width(120));
|
|
|
|
SerializedProperty animatorControllerProp = serializedObject.FindProperty("animatorController");
|
|
if (humanoid.targetsRig != null) {
|
|
if (animatorEnabledProp.boolValue) {
|
|
if (humanoid.targetsRig.runtimeAnimatorController != null)
|
|
showAnimatorParameters = EditorGUILayout.Foldout(showAnimatorParameters, "Params", true);
|
|
animatorControllerProp.objectReferenceValue = (RuntimeAnimatorController)EditorGUILayout.ObjectField(humanoid.targetsRig.runtimeAnimatorController, typeof(RuntimeAnimatorController), true);
|
|
if (animatorControllerProp.objectReferenceValue != humanoid.targetsRig.runtimeAnimatorController)
|
|
animatorParameterNames = null;
|
|
humanoid.targetsRig.runtimeAnimatorController = (RuntimeAnimatorController)animatorControllerProp.objectReferenceValue;
|
|
}
|
|
else
|
|
humanoid.targetsRig.runtimeAnimatorController = null;
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
|
|
private void AnimatorParametersInspector(HumanoidControl humanoid) {
|
|
if (showAnimatorParameters && humanoid.animatorEnabled && humanoid.targetsRig.runtimeAnimatorController != null) {
|
|
if (animatorParameterNames == null)
|
|
animatorParameterNames = GetAnimatorParameters(humanoid);
|
|
|
|
EditorGUI.indentLevel++;
|
|
|
|
GUIContent forwardSpeedText = new GUIContent(
|
|
"Forward Speed",
|
|
"Animator parameter controlling the forward motion animation"
|
|
);
|
|
animatorParamForwardProp.intValue = SetAnimatorInput(forwardSpeedText, animatorParamForwardProp.intValue, ref humanoid.animatorParameterForward);
|
|
|
|
GUIContent sidewardSpeedText = new GUIContent(
|
|
"Sideward Speed",
|
|
"Animator parameter controlling the sideward motion animation"
|
|
);
|
|
animatorParamSidewardProp.intValue = SetAnimatorInput(sidewardSpeedText, animatorParamSidewardProp.intValue, ref humanoid.animatorParameterSideward);
|
|
|
|
GUIContent turnSpeedText = new GUIContent(
|
|
"Turn Speed",
|
|
"Animator parameter controlling the rotation animation"
|
|
);
|
|
animatorParamRotationProp.intValue = SetAnimatorInput(turnSpeedText, animatorParamRotationProp.intValue, ref humanoid.animatorParameterRotation);
|
|
|
|
GUIContent headHeightText = new GUIContent(
|
|
"Head Height",
|
|
"Animation parameter controlling the squatting animation"
|
|
);
|
|
animatorParamHeightProp.intValue = SetAnimatorInput(headHeightText, animatorParamHeightProp.intValue, ref humanoid.animatorParameterHeight);
|
|
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
else
|
|
showAnimatorParameters = false;
|
|
|
|
}
|
|
|
|
protected GUIContent[] animatorParameterNames;
|
|
public GUIContent[] GetAnimatorParameters(HumanoidControl humanoid) {
|
|
if (humanoid == null || humanoid.targetsRig.runtimeAnimatorController == null)
|
|
return null;
|
|
|
|
AnimatorControllerParameter[] animatorParameters = humanoid.targetsRig.parameters;
|
|
GUIContent[] fullAnimatorParameterNames = new GUIContent[animatorParameters.Length + 1];
|
|
fullAnimatorParameterNames[0] = new GUIContent(" ");
|
|
int j = 1;
|
|
for (int i = 0; i < animatorParameters.Length; i++)
|
|
if (animatorParameters[i].type == AnimatorControllerParameterType.Float)
|
|
fullAnimatorParameterNames[j++] = new GUIContent(animatorParameters[i].name);
|
|
|
|
GUIContent[] truncatedParameterNames = new GUIContent[j];
|
|
for (int i = 0; i < j; i++)
|
|
truncatedParameterNames[i] = fullAnimatorParameterNames[i];
|
|
return truncatedParameterNames;
|
|
}
|
|
|
|
private int SetAnimatorInput(GUIContent label, int parameterIndex, ref string parameterName) {
|
|
if (parameterIndex > animatorParameterNames.Length)
|
|
parameterIndex = 0;
|
|
int newParameterIndex = EditorGUILayout.Popup(label, parameterIndex, animatorParameterNames, GUILayout.MinWidth(80));
|
|
|
|
if (newParameterIndex > 0 && newParameterIndex < animatorParameterNames.Length) {
|
|
parameterName = animatorParameterNames[newParameterIndex].text;
|
|
}
|
|
else {
|
|
parameterName = null;
|
|
}
|
|
return newParameterIndex;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Networking
|
|
#if hNW_UNET || hNW_PHOTON || hNW_BOLT || hNW_MIRROR
|
|
private SerializedProperty remoteAvatarProp;
|
|
#endif
|
|
|
|
private void InitNetworking() {
|
|
#if hNW_UNET || hNW_PHOTON || hNW_BOLT || hNW_MIRROR
|
|
remoteAvatarProp = serializedObject.FindProperty("remoteAvatar");
|
|
#endif
|
|
}
|
|
|
|
private void NetworkingInspector(HumanoidControl humanoid) {
|
|
#if hNW_UNET || hNW_PHOTON || hNW_BOLT || hNW_MIRROR
|
|
GUIContent text = new GUIContent(
|
|
"Networking",
|
|
"Settings for networking"
|
|
);
|
|
EditorGUILayout.LabelField(text, GUILayout.Width(100));
|
|
|
|
EditorGUI.indentLevel++;
|
|
RemoteAvatarInspector();
|
|
EditorGUI.indentLevel--;
|
|
#endif
|
|
}
|
|
|
|
private void RemoteAvatarInspector() {
|
|
if (humanoid.isRemote)
|
|
return;
|
|
#if hNW_UNET || hNW_PHOTON || hNW_BOLT || hNW_MIRROR
|
|
GUIContent text = new GUIContent(
|
|
"Remote Avatar",
|
|
"Determines how the avatar looks like on remote clients. Required for networking setups"
|
|
);
|
|
remoteAvatarProp.objectReferenceValue = (GameObject)EditorGUILayout.ObjectField(text, remoteAvatarProp.objectReferenceValue, typeof(GameObject), false);
|
|
|
|
GameObject remoteAvatarPrefab = (GameObject)remoteAvatarProp.objectReferenceValue;
|
|
if (remoteAvatarPrefab == null) {
|
|
remoteAvatarPrefab = DetermineRemoteAvatar();
|
|
if (remoteAvatarPrefab == null)
|
|
EditorGUILayout.HelpBox("Remote Avatar cannot be null for networking", MessageType.Error);
|
|
else
|
|
remoteAvatarProp.objectReferenceValue = remoteAvatarPrefab;
|
|
}
|
|
else {
|
|
GameObject remoteAvatarTest = (GameObject)Resources.Load(remoteAvatarPrefab.name);
|
|
if (remoteAvatarTest == null)
|
|
EditorGUILayout.HelpBox(remoteAvatarPrefab.name + " is not located in a Resources folder", MessageType.Error);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
protected virtual GameObject DetermineRemoteAvatar() {
|
|
string avatarName = humanoid.avatarRig.gameObject.name;
|
|
GameObject remoteAvatarTest = (GameObject)Resources.Load(avatarName);
|
|
if (remoteAvatarTest == null)
|
|
return null;
|
|
|
|
return remoteAvatarTest;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Pose
|
|
|
|
private void InitPose() {
|
|
if (!Application.isPlaying && humanoid.pose != null)
|
|
humanoid.pose.Show(humanoid);
|
|
}
|
|
|
|
private void PoseInspector() {
|
|
EditorGUILayout.BeginHorizontal();
|
|
SerializedProperty poseProp = serializedObject.FindProperty("pose");
|
|
Pose newHumanoidPose = (Pose)EditorGUILayout.ObjectField("Pose", poseProp.objectReferenceValue, typeof(Pose), false);
|
|
if (newHumanoidPose != humanoid.pose) {
|
|
poseProp.objectReferenceValue = newHumanoidPose;
|
|
if (humanoid.pose != null) {
|
|
humanoid.pose.Show(humanoid);
|
|
humanoid.CopyRigToTargets();
|
|
humanoid.UpdateMovements();
|
|
}
|
|
}
|
|
|
|
if (!Application.isPlaying && humanoid.pose != null) {
|
|
GUIContent text = new GUIContent(
|
|
"",
|
|
"Edit Pose"
|
|
);
|
|
bool isEdited = EditorGUILayout.Toggle(text, humanoid.editPose, "button", GUILayout.Width(19));
|
|
if (humanoid.editPose != isEdited)
|
|
SceneView.RepaintAll();
|
|
humanoid.editPose = isEdited;
|
|
|
|
if (humanoid.editPose)
|
|
humanoid.pose.UpdatePose(humanoid);
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
#endregion
|
|
|
|
#region Movement
|
|
|
|
protected bool showMovement = false;
|
|
protected void MovementInspector() {
|
|
GUIContent text = new GUIContent(
|
|
"Movement",
|
|
"Settings related to moving the humanoid around"
|
|
);
|
|
showMovement = EditorGUILayout.Foldout(showMovement, text, true);
|
|
if (showMovement) {
|
|
EditorGUI.indentLevel++;
|
|
ForwardSpeedInspector();
|
|
BackwardSpeedInspector();
|
|
SidewardSpeedInspector();
|
|
MaxAccelerationInspector();
|
|
RotationSpeedInspector();
|
|
StepOffsetInspector();
|
|
ProximitySpeedInspector();
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
}
|
|
|
|
protected virtual void ForwardSpeedInspector() {
|
|
SerializedProperty forwardSpeedProp = serializedObject.FindProperty("forwardSpeed");
|
|
GUIContent text = new GUIContent(
|
|
"Forward Speed",
|
|
"Maximum forward speed in units(meters)/second"
|
|
);
|
|
forwardSpeedProp.floatValue = EditorGUILayout.FloatField(text, forwardSpeedProp.floatValue);
|
|
}
|
|
|
|
protected virtual void BackwardSpeedInspector() {
|
|
SerializedProperty backwardSpeedProp = serializedObject.FindProperty("backwardSpeed");
|
|
GUIContent text = new GUIContent(
|
|
"Backward Speed",
|
|
"Maximum backward speed in units(meters)/second"
|
|
);
|
|
backwardSpeedProp.floatValue = EditorGUILayout.FloatField(text, backwardSpeedProp.floatValue);
|
|
}
|
|
|
|
protected virtual void SidewardSpeedInspector() {
|
|
SerializedProperty sidewardSpeedPop = serializedObject.FindProperty("sidewardSpeed");
|
|
GUIContent text = new GUIContent(
|
|
"Sideward Speed",
|
|
"Maximum sideward speed in units(meters)/second"
|
|
);
|
|
sidewardSpeedPop.floatValue = EditorGUILayout.FloatField(text, sidewardSpeedPop.floatValue);
|
|
}
|
|
|
|
protected virtual void MaxAccelerationInspector() {
|
|
SerializedProperty maxAccelerationProp = serializedObject.FindProperty("maxAcceleration");
|
|
GUIContent text = new GUIContent(
|
|
"Maximum Acceleration",
|
|
"Maximum acceleration in units(meters)/second/second, 0 = no maximum acceleration"
|
|
);
|
|
maxAccelerationProp.floatValue = EditorGUILayout.FloatField(text, maxAccelerationProp.floatValue);
|
|
}
|
|
|
|
protected virtual void RotationSpeedInspector() {
|
|
SerializedProperty rotationSpeedProp = serializedObject.FindProperty("rotationSpeed");
|
|
GUIContent text = new GUIContent(
|
|
"Rotation Speed",
|
|
"Maximum rotational speed in degrees/second"
|
|
);
|
|
rotationSpeedProp.floatValue = EditorGUILayout.FloatField(text, rotationSpeedProp.floatValue);
|
|
}
|
|
|
|
protected virtual void ProximitySpeedInspector() {
|
|
SerializedProperty proximitySpeedProp = serializedObject.FindProperty("proximitySpeed");
|
|
GUIContent text = new GUIContent(
|
|
"Proximity Speed",
|
|
"Decreases movement speed when the pawn is close to static objects to reduce motion sickness"
|
|
);
|
|
proximitySpeedProp.boolValue = EditorGUILayout.Toggle(text, proximitySpeedProp.boolValue);
|
|
}
|
|
|
|
|
|
protected void StepOffsetInspector() {
|
|
SerializedProperty stepOffsetProp = serializedObject.FindProperty("stepOffset");
|
|
GUIContent text = new GUIContent(
|
|
"Step Offset",
|
|
"The maximum vertical distance which the humanoid van walk over"
|
|
);
|
|
stepOffsetProp.floatValue = EditorGUILayout.FloatField(text, stepOffsetProp.floatValue);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Settings
|
|
|
|
protected virtual void InitSettings() {
|
|
ShowRealWorldObjects();
|
|
}
|
|
|
|
protected bool showSettings = false;
|
|
protected void SettingsInspector() {
|
|
GUIContent text = new GUIContent(
|
|
"Settings",
|
|
"To contract various aspects of the script"
|
|
);
|
|
showSettings = EditorGUILayout.Foldout(showSettings, text, true);
|
|
|
|
if (showSettings) {
|
|
EditorGUI.indentLevel++;
|
|
|
|
RealWorldObjects(humanoid);
|
|
ShowSkeletonsInspector();
|
|
|
|
PhysicsSetting();
|
|
UseGravitySetting();
|
|
BodyPullSetting();
|
|
HapticsSetting();
|
|
CalibrateAtStartSetting();
|
|
StartPositionSetting();
|
|
ScalingSetting();
|
|
DontDestroySetting();
|
|
if (IsPrefab(humanoid))
|
|
DisconnectInstancesSetting();
|
|
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
|
|
ShowTrackers(humanoid, humanoid.showRealObjects);
|
|
}
|
|
|
|
private void RealWorldObjects(HumanoidControl humanoid) {
|
|
SerializedProperty showRealObjectsProp = serializedObject.FindProperty("showRealObjects");
|
|
|
|
bool lastShowRealObjects = showRealObjectsProp.boolValue;
|
|
|
|
GUIContent text = new GUIContent(
|
|
"Show Real Objects",
|
|
"Shows real physical objects like trackers, controllers and camera's at their actual location"
|
|
);
|
|
showRealObjectsProp.boolValue = EditorGUILayout.Toggle(text, lastShowRealObjects);
|
|
|
|
if (!lastShowRealObjects && showRealObjectsProp.boolValue) { // we turned real world objects on
|
|
humanoid.leftHandTarget.showRealObjects = true;
|
|
humanoid.leftHandTarget.ShowSensors(true);
|
|
humanoid.rightHandTarget.showRealObjects = true;
|
|
humanoid.rightHandTarget.ShowSensors(true);
|
|
}
|
|
else {
|
|
humanoid.leftHandTarget.ShowSensors(showRealObjectsProp.boolValue && humanoid.leftHandTarget.showRealObjects);
|
|
humanoid.rightHandTarget.ShowSensors(showRealObjectsProp.boolValue && humanoid.rightHandTarget.showRealObjects);
|
|
}
|
|
}
|
|
|
|
private void ShowSkeletonsInspector() {
|
|
SerializedProperty showSkeletonsProp = serializedObject.FindProperty("_showSkeletons");
|
|
bool lastShowSkeletons = showSkeletonsProp.boolValue;
|
|
|
|
GUIContent text = new GUIContent(
|
|
"Show Skeletons",
|
|
"If enabled, tracking skeletons will be rendered"
|
|
);
|
|
showSkeletonsProp.boolValue = EditorGUILayout.Toggle(text, lastShowSkeletons);
|
|
// This line is needed to activate the setter
|
|
humanoid.showSkeletons = showSkeletonsProp.boolValue;
|
|
}
|
|
|
|
protected void ShowRealWorldObjects() {
|
|
}
|
|
|
|
protected void ScalingSetting() {
|
|
SerializedProperty scalingProp = serializedObject.FindProperty("scaling");
|
|
GUIContent text = new GUIContent(
|
|
"Scaling",
|
|
"Determines how differences between the player size and the avatar are resolved"
|
|
);
|
|
scalingProp.intValue = (int)(HumanoidControl.ScalingType)EditorGUILayout.EnumPopup(text, (HumanoidControl.ScalingType)scalingProp.intValue);
|
|
}
|
|
|
|
private void ShowTrackers(HumanoidControl humanoid, bool shown) {
|
|
foreach (Tracker tracker in humanoid.trackers)
|
|
tracker.ShowTracker(shown);
|
|
}
|
|
|
|
protected virtual void UseGravitySetting() {
|
|
SerializedProperty useGravityProp = serializedObject.FindProperty("useGravity");
|
|
GUIContent text = new GUIContent(
|
|
"Use Gravity",
|
|
"Implements downward motion when the character is not on solid ground"
|
|
);
|
|
useGravityProp.boolValue = EditorGUILayout.Toggle(text, useGravityProp.boolValue);
|
|
}
|
|
|
|
protected virtual void PhysicsSetting() {
|
|
// Physics cannot bet changes during runtime
|
|
EditorGUI.BeginDisabledGroup(Application.isPlaying);
|
|
|
|
SerializedProperty physicsProp = serializedObject.FindProperty("physics");
|
|
GUIContent text = new GUIContent(
|
|
"Physics",
|
|
"Enables collisions of the pawn with the environment using the physics engine"
|
|
);
|
|
physicsProp.boolValue = EditorGUILayout.Toggle(text, physicsProp.boolValue);
|
|
|
|
EditorGUI.EndDisabledGroup();
|
|
}
|
|
|
|
protected virtual void BodyPullSetting() {
|
|
SerializedProperty bodyPullProp = serializedObject.FindProperty("bodyPull");
|
|
GUIContent text = new GUIContent(
|
|
"Body Pull",
|
|
"Moves the body when grabbing static objects"
|
|
);
|
|
bodyPullProp.boolValue = EditorGUILayout.Toggle(text, bodyPullProp.boolValue);
|
|
}
|
|
|
|
protected void HapticsSetting() {
|
|
SerializedProperty hapticsProp = serializedObject.FindProperty("haptics");
|
|
GUIContent text = new GUIContent(
|
|
"Haptics",
|
|
"Uses haptic feedback when colliding with objects"
|
|
);
|
|
hapticsProp.boolValue = EditorGUILayout.Toggle(text, hapticsProp.boolValue);
|
|
}
|
|
|
|
protected virtual void CalibrateAtStartSetting() {
|
|
SerializedProperty calibrateAtStartProp = serializedObject.FindProperty("calibrateAtStart");
|
|
GUIContent text = new GUIContent(
|
|
"Calibrate at Start",
|
|
"Will calibrate the pawn when the tracking starts."
|
|
);
|
|
calibrateAtStartProp.boolValue = EditorGUILayout.Toggle(text, calibrateAtStartProp.boolValue);
|
|
}
|
|
|
|
//protected virtual void ScalingSetting() {
|
|
// SerializedProperty scalingProp = serializedObject.FindProperty("avatarMatching");
|
|
// GUIContent text = new GUIContent(
|
|
// "Scaling",
|
|
// "Determines how differences between the player size and the character are resolved"
|
|
// );
|
|
// scalingProp.intValue = (int)(PawnControl.MatchingType)EditorGUILayout.EnumPopup(text, (PawnControl.MatchingType)scalingProp.intValue);
|
|
//}
|
|
|
|
protected virtual void StartPositionSetting() {
|
|
SerializedProperty startPositionProp = serializedObject.FindProperty("startPosition");
|
|
GUIContent text = new GUIContent(
|
|
"Start Position",
|
|
"Determines the start position of the player"
|
|
);
|
|
startPositionProp.intValue = (int)(HumanoidControl.StartPosition)EditorGUILayout.EnumPopup(text, (HumanoidControl.StartPosition)startPositionProp.intValue);
|
|
}
|
|
|
|
protected void DontDestroySetting() {
|
|
SerializedProperty dontDestroyProp = serializedObject.FindProperty("dontDestroyOnLoad");
|
|
GUIContent text = new GUIContent(
|
|
"Don't Destroy on Load",
|
|
"Ensures that the pawn survives a scene change"
|
|
);
|
|
dontDestroyProp.boolValue = EditorGUILayout.Toggle(text, dontDestroyProp.boolValue);
|
|
}
|
|
|
|
protected void DisconnectInstancesSetting() {
|
|
SerializedProperty disconnectInstancesProp = serializedObject.FindProperty("disconnectInstances");
|
|
GUIContent text = new GUIContent(
|
|
"Disconnect Instances",
|
|
"Disconnects instances from prefab when instantiating"
|
|
);
|
|
disconnectInstancesProp.boolValue = EditorGUILayout.Toggle(text, disconnectInstancesProp.boolValue);
|
|
}
|
|
|
|
protected virtual void IsRemoteSetting() {
|
|
SerializedProperty isRemoteProp = serializedObject.FindProperty("isRemote");
|
|
GUIContent text = new GUIContent(
|
|
"Is Remote",
|
|
"This pawn is used for remote clients"
|
|
);
|
|
isRemoteProp.boolValue = EditorGUILayout.Toggle(text, isRemoteProp.boolValue);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Buttons
|
|
private void Buttons() {
|
|
GUILayout.BeginHorizontal();
|
|
if (Application.isPlaying && GUILayout.Button("Calibrate"))
|
|
humanoid.Calibrate();
|
|
GUILayout.EndHorizontal();
|
|
}
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Scene
|
|
public void OnSceneGUI() {
|
|
if (Application.isPlaying)
|
|
return;
|
|
if (humanoid == null)
|
|
return;
|
|
|
|
if (humanoid.pose != null) {
|
|
if (humanoid.editPose)
|
|
humanoid.pose.UpdatePose(humanoid);
|
|
else {
|
|
humanoid.pose.Show(humanoid);
|
|
humanoid.CopyRigToTargets();
|
|
}
|
|
}
|
|
|
|
if (humanoid.headTarget == null ||
|
|
humanoid.leftHandTarget == null ||
|
|
humanoid.rightHandTarget == null ||
|
|
humanoid.hipsTarget == null ||
|
|
humanoid.leftFootTarget == null ||
|
|
humanoid.rightFootTarget == null) {
|
|
|
|
return;
|
|
}
|
|
// update the avatar bones from the target rig
|
|
humanoid.UpdateMovements();
|
|
// match the target rig with the new avatar pose
|
|
|
|
humanoid.MatchTargetsToAvatar();
|
|
|
|
// and update all targets to match the target rig
|
|
humanoid.CopyRigToTargets();
|
|
|
|
// Update the sensors to match the updated targets
|
|
humanoid.UpdateSensorsFromTargets();
|
|
}
|
|
#endregion
|
|
|
|
public static bool IsPrefab(HumanoidControl humanoid) {
|
|
PrefabStage prefabStage = PrefabStageUtility.GetPrefabStage(humanoid.gameObject);
|
|
if (prefabStage == null)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
public static void ShowTracker(GameObject trackerObject, bool enabled) {
|
|
Renderer renderer = trackerObject.GetComponent<Renderer>();
|
|
if (renderer != null)
|
|
renderer.enabled = enabled;
|
|
}
|
|
|
|
public abstract class TrackerProps {
|
|
public SerializedProperty enabledProp;
|
|
//public SerializedProperty trackerTransfromProp;
|
|
public HumanoidTracker tracker;
|
|
|
|
public TrackerProps(SerializedObject serializedObject, HumanoidTracker _tracker, string trackerName) {
|
|
enabledProp = serializedObject.FindProperty(trackerName + ".enabled");
|
|
//trackerTransfromProp = serializedObject.FindProperty(trackerName + ".trackerTransform");
|
|
|
|
tracker = _tracker;
|
|
}
|
|
}
|
|
|
|
public class HumanoidTargetObjs {
|
|
public SerializedObject headTargetObj;
|
|
public SerializedObject leftHandTargetObj;
|
|
public SerializedObject rightHandTargetObj;
|
|
public SerializedObject hipsTargetObj;
|
|
public SerializedObject leftFootTargetObj;
|
|
public SerializedObject rightFootTargetObj;
|
|
|
|
public HumanoidTargetObjs(HumanoidControl humanoid) {
|
|
if (humanoid.headTarget != null)
|
|
headTargetObj = new SerializedObject(humanoid.headTarget);
|
|
if (humanoid.leftHandTarget != null)
|
|
leftHandTargetObj = new SerializedObject(humanoid.leftHandTarget);
|
|
if (humanoid.rightHandTarget != null)
|
|
rightHandTargetObj = new SerializedObject(humanoid.rightHandTarget);
|
|
if (humanoid.hipsTarget != null)
|
|
hipsTargetObj = new SerializedObject(humanoid.hipsTarget);
|
|
if (humanoid.leftFootTarget != null)
|
|
leftFootTargetObj = new SerializedObject(humanoid.leftFootTarget);
|
|
if (humanoid.rightFootTarget != null)
|
|
rightFootTargetObj = new SerializedObject(humanoid.rightFootTarget);
|
|
}
|
|
|
|
public void Update() {
|
|
headTargetObj?.Update();
|
|
leftHandTargetObj?.Update();
|
|
rightHandTargetObj?.Update();
|
|
hipsTargetObj?.Update();
|
|
leftFootTargetObj?.Update();
|
|
rightFootTargetObj?.Update();
|
|
}
|
|
|
|
public void ApplyModifiedProperties() {
|
|
headTargetObj?.ApplyModifiedProperties();
|
|
leftHandTargetObj?.ApplyModifiedProperties();
|
|
rightHandTargetObj?.ApplyModifiedProperties();
|
|
hipsTargetObj?.ApplyModifiedProperties();
|
|
leftFootTargetObj?.ApplyModifiedProperties();
|
|
rightFootTargetObj?.ApplyModifiedProperties();
|
|
}
|
|
}
|
|
|
|
public abstract class HumanoidTrackerProps : TrackerProps {
|
|
protected HumanoidTargetObjs targetObjs;
|
|
|
|
protected SerializedProperty trackerProp;
|
|
|
|
protected SerializedProperty headSensorProp;
|
|
protected SerializedProperty leftHandSensorProp;
|
|
protected SerializedProperty rightHandSensorProp;
|
|
protected SerializedProperty hipsSensorProp;
|
|
protected SerializedProperty leftFootSensorProp;
|
|
protected SerializedProperty rightFootSensorProp;
|
|
|
|
public HumanoidTrackerProps(SerializedObject serializedObject, HumanoidTargetObjs _targetObjs, HumanoidTracker _tracker, string trackerName) :
|
|
base(serializedObject, _tracker, trackerName) {
|
|
targetObjs = _targetObjs;
|
|
|
|
trackerProp = serializedObject.FindProperty($"{trackerName}.{nameof(Tracker.trackerComponent)}");
|
|
|
|
if (targetObjs.headTargetObj != null)
|
|
headSensorProp = targetObjs.headTargetObj.FindProperty(trackerName);
|
|
if (targetObjs.leftHandTargetObj != null)
|
|
leftHandSensorProp = targetObjs.leftHandTargetObj.FindProperty(trackerName);
|
|
if (targetObjs.rightHandTargetObj != null)
|
|
rightHandSensorProp = targetObjs.rightHandTargetObj.FindProperty(trackerName);
|
|
if (targetObjs.hipsTargetObj != null)
|
|
hipsSensorProp = targetObjs.hipsTargetObj.FindProperty(trackerName);
|
|
if (targetObjs.leftFootTargetObj != null)
|
|
leftFootSensorProp = targetObjs.leftFootTargetObj.FindProperty(trackerName);
|
|
if (targetObjs.rightFootTargetObj != null)
|
|
rightFootSensorProp = targetObjs.rightFootTargetObj.FindProperty(trackerName);
|
|
}
|
|
|
|
public abstract void Inspector(HumanoidControl humanoid);
|
|
|
|
public void Inspector(HumanoidControl humanoid, string resourceName) {
|
|
EditorGUILayout.BeginHorizontal();
|
|
bool wasEnabled = enabledProp.boolValue;
|
|
|
|
GUIContent text = new GUIContent(
|
|
tracker.name,
|
|
"Activate " + tracker.name + " support for this humanoid"
|
|
);
|
|
enabledProp.boolValue = EditorGUILayout.ToggleLeft(text, tracker.enabled, GUILayout.Width(200));
|
|
|
|
if (Application.isPlaying && enabledProp.boolValue)
|
|
EditorGUILayout.EnumPopup(tracker.status);
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
if (Application.isPlaying)
|
|
return;
|
|
|
|
|
|
if (IsPrefab(humanoid))
|
|
return;
|
|
|
|
if (tracker.humanoid == null)
|
|
tracker.humanoid = humanoid;
|
|
|
|
if (!Application.isPlaying && !enabledProp.boolValue)
|
|
RemoveTracker();
|
|
|
|
//tracker.ShowTracker(humanoid.showRealObjects && enabledProp.boolValue);
|
|
|
|
if (!wasEnabled && enabledProp.boolValue)
|
|
InitControllers();
|
|
else if (wasEnabled && !enabledProp.boolValue)
|
|
RemoveControllers();
|
|
|
|
if (enabledProp.boolValue && !Application.isPlaying) {
|
|
SetSensors2Target();
|
|
}
|
|
}
|
|
|
|
protected void TrackerInspector(HumanoidControl humanoid, HumanoidTracker tracker) {
|
|
if (trackerProp.objectReferenceValue == null) {
|
|
// Tracker does not exist
|
|
using (new EditorGUILayout.HorizontalScope()) {
|
|
EditorGUILayout.LabelField("Tracker", GUILayout.Width(120));
|
|
if (TrackerComponentShowButton())
|
|
tracker.CheckTracker(humanoid);
|
|
}
|
|
}
|
|
else {
|
|
TrackerComponentInspector();
|
|
}
|
|
}
|
|
|
|
protected bool TrackerComponentShowButton() {
|
|
GUIContent labelText = new GUIContent(
|
|
"Show",
|
|
"Press this button to show the tracker in the Real World"
|
|
);
|
|
return GUILayout.Button(labelText);
|
|
}
|
|
|
|
protected void TrackerComponentInspector() {
|
|
GUIContent trackerLabel = new GUIContent(
|
|
"Tracker",
|
|
"The tracker component in the real world"
|
|
);
|
|
trackerProp.objectReferenceValue = (Tracking.TrackerComponent)EditorGUILayout.ObjectField(trackerLabel, trackerProp.objectReferenceValue, typeof(Tracking.TrackerComponent), true);
|
|
}
|
|
|
|
private void RemoveTracker() {
|
|
if (tracker.trackerComponent == null)
|
|
return;
|
|
DestroyImmediate(tracker.trackerComponent.gameObject, true);
|
|
}
|
|
|
|
public virtual void InitControllers() {
|
|
tracker.enabled = enabledProp.boolValue;
|
|
// this is necessary because the serializedproperty has not been processed yet
|
|
// and is used in InitController
|
|
|
|
// This #if is necessary for build assetbundles (somehow)
|
|
#if UNITY_EDITOR
|
|
if (tracker.headSensor != null)
|
|
tracker.headSensor.InitController(headSensorProp, tracker.humanoid.headTarget);
|
|
if (tracker.leftHandSensor != null)
|
|
tracker.leftHandSensor.InitController(leftHandSensorProp, tracker.humanoid.leftHandTarget);
|
|
if (tracker.rightHandSensor != null)
|
|
tracker.rightHandSensor.InitController(rightHandSensorProp, tracker.humanoid.rightHandTarget);
|
|
if (tracker.hipsSensor != null)
|
|
tracker.hipsSensor.InitController(hipsSensorProp, tracker.humanoid.hipsTarget);
|
|
if (tracker.leftFootSensor != null)
|
|
tracker.leftFootSensor.InitController(leftFootSensorProp, tracker.humanoid.leftFootTarget);
|
|
if (tracker.rightFootSensor != null)
|
|
tracker.rightFootSensor.InitController(rightFootSensorProp, tracker.humanoid.rightFootTarget);
|
|
#endif
|
|
}
|
|
|
|
private void RemoveControllers() {
|
|
foreach (HumanoidSensor sensor in tracker.sensors)
|
|
RemoveTransform(sensor.sensorTransform);
|
|
|
|
if (tracker.headSensor != null)
|
|
tracker.headSensor.RemoveController(headSensorProp);
|
|
if (tracker.leftHandSensor != null)
|
|
tracker.leftHandSensor.RemoveController(leftHandSensorProp);
|
|
if (tracker.rightHandSensor != null)
|
|
tracker.rightHandSensor.RemoveController(rightHandSensorProp);
|
|
if (tracker.hipsSensor != null)
|
|
tracker.hipsSensor.RemoveController(hipsSensorProp);
|
|
if (tracker.leftFootSensor != null)
|
|
tracker.leftFootSensor.RemoveController(leftFootSensorProp);
|
|
if (tracker.rightFootSensor != null)
|
|
tracker.rightFootSensor.RemoveController(rightFootSensorProp);
|
|
}
|
|
|
|
private void RemoveTransform(Transform trackerTransform) {
|
|
if (trackerTransform != null)
|
|
DestroyImmediate(trackerTransform.gameObject, true);
|
|
}
|
|
|
|
private void SetSensors2Target() {
|
|
foreach (HumanoidSensor sensor in tracker.sensors) {
|
|
sensor.SetSensor2Target();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|