diff --git a/com.unity.ml-agents.extensions/Editor/RigidBodySensorComponentEditor.cs b/com.unity.ml-agents.extensions/Editor/RigidBodySensorComponentEditor.cs
index f1606595fb..bc37bbd076 100644
--- a/com.unity.ml-agents.extensions/Editor/RigidBodySensorComponentEditor.cs
+++ b/com.unity.ml-agents.extensions/Editor/RigidBodySensorComponentEditor.cs
@@ -1,11 +1,10 @@
-using UnityEditor;
using Unity.MLAgents.Editor;
using Unity.MLAgents.Extensions.Sensors;
+using UnityEditor;
namespace Unity.MLAgents.Extensions.Editor
{
[CustomEditor(typeof(RigidBodySensorComponent))]
- [CanEditMultipleObjects]
internal class RigidBodySensorComponentEditor : UnityEditor.Editor
{
bool ShowHierarchy = true;
@@ -47,13 +46,13 @@ public override void OnInspectorGUI()
{
var treeNodes = rbSensorComp.GetDisplayNodes();
var originalIndent = EditorGUI.indentLevel;
+ var poseEnabled = so.FindProperty("m_PoseExtractor").FindPropertyRelative("m_PoseEnabled");
foreach (var node in treeNodes)
{
var obj = node.NodeObject;
var objContents = EditorGUIUtility.ObjectContent(obj, obj.GetType());
EditorGUI.indentLevel = originalIndent + node.Depth;
- var enabled = EditorGUILayout.Toggle(objContents, node.Enabled);
- rbSensorComp.SetPoseEnabled(node.OriginalIndex, enabled);
+ EditorGUILayout.PropertyField(poseEnabled.GetArrayElementAtIndex(node.OriginalIndex), objContents);
}
EditorGUI.indentLevel = originalIndent;
@@ -69,7 +68,5 @@ public override void OnInspectorGUI()
rbSensorComp.ResetPoseExtractor();
}
}
-
-
}
}
diff --git a/com.unity.ml-agents.extensions/Runtime/Sensors/PoseExtractor.cs b/com.unity.ml-agents.extensions/Runtime/Sensors/PoseExtractor.cs
index 059804377b..17e5a4f565 100644
--- a/com.unity.ml-agents.extensions/Runtime/Sensors/PoseExtractor.cs
+++ b/com.unity.ml-agents.extensions/Runtime/Sensors/PoseExtractor.cs
@@ -14,16 +14,17 @@ namespace Unity.MLAgents.Extensions.Sensors
/// Poses are either considered in model space, which is relative to a root body,
/// or in local space, which is relative to their parent.
///
- public abstract class PoseExtractor
+ [Serializable]
+ public abstract class PoseExtractor : ISerializationCallbackReceiver
{
- int[] m_ParentIndices;
+ [SerializeField] int[] m_ParentIndices;
Pose[] m_ModelSpacePoses;
Pose[] m_LocalSpacePoses;
Vector3[] m_ModelSpaceLinearVelocities;
Vector3[] m_LocalSpaceLinearVelocities;
- bool[] m_PoseEnabled;
+ [SerializeField] bool[] m_PoseEnabled;
///
@@ -177,11 +178,8 @@ protected void Setup(int[] parentIndices)
#endif
m_ParentIndices = parentIndices;
var numPoses = parentIndices.Length;
- m_ModelSpacePoses = new Pose[numPoses];
- m_LocalSpacePoses = new Pose[numPoses];
- m_ModelSpaceLinearVelocities = new Vector3[numPoses];
- m_LocalSpaceLinearVelocities = new Vector3[numPoses];
+ CreateSensorArrays(numPoses);
m_PoseEnabled = new bool[numPoses];
// All poses are enabled by default. Generally we'll want to disable the root though.
@@ -191,6 +189,25 @@ protected void Setup(int[] parentIndices)
}
}
+ public void OnBeforeSerialize()
+ {
+ // no-op
+ }
+
+ public void OnAfterDeserialize()
+ {
+ CreateSensorArrays(m_ParentIndices.Length);
+ }
+
+ private void CreateSensorArrays(int numPoses)
+ {
+ m_ModelSpacePoses = new Pose[numPoses];
+ m_LocalSpacePoses = new Pose[numPoses];
+
+ m_ModelSpaceLinearVelocities = new Vector3[numPoses];
+ m_LocalSpaceLinearVelocities = new Vector3[numPoses];
+ }
+
///
/// Return the world space Pose of the i'th object.
///
diff --git a/com.unity.ml-agents.extensions/Runtime/Sensors/RigidBodyPoseExtractor.cs b/com.unity.ml-agents.extensions/Runtime/Sensors/RigidBodyPoseExtractor.cs
index b54b0b5713..12161ac911 100644
--- a/com.unity.ml-agents.extensions/Runtime/Sensors/RigidBodyPoseExtractor.cs
+++ b/com.unity.ml-agents.extensions/Runtime/Sensors/RigidBodyPoseExtractor.cs
@@ -1,5 +1,7 @@
+using System;
using System.Collections.Generic;
using UnityEngine;
+using Object = UnityEngine.Object;
namespace Unity.MLAgents.Extensions.Sensors
{
@@ -8,15 +10,16 @@ namespace Unity.MLAgents.Extensions.Sensors
/// Utility class to track a hierarchy of RigidBodies. These are assumed to have a root node,
/// and child nodes are connect to their parents via Joints.
///
+ [Serializable]
public class RigidBodyPoseExtractor : PoseExtractor
{
- Rigidbody[] m_Bodies;
+ [SerializeField] Rigidbody[] m_Bodies;
///
/// Optional game object used to determine the root of the poses, separate from the actual Rigidbodies
/// in the hierarchy. For locomotion
///
- GameObject m_VirtualRoot;
+ [SerializeField] GameObject m_VirtualRoot;
///
/// Initialize given a root RigidBody.
diff --git a/com.unity.ml-agents.extensions/Runtime/Sensors/RigidBodySensorComponent.cs b/com.unity.ml-agents.extensions/Runtime/Sensors/RigidBodySensorComponent.cs
index a6dad23b66..80947f12db 100644
--- a/com.unity.ml-agents.extensions/Runtime/Sensors/RigidBodySensorComponent.cs
+++ b/com.unity.ml-agents.extensions/Runtime/Sensors/RigidBodySensorComponent.cs
@@ -94,7 +94,7 @@ internal void SetPoseEnabled(int index, bool enabled)
internal bool IsTrivial()
{
- if (ReferenceEquals(RootBody, null))
+ if (ReferenceEquals(RootBody, null) || !RootBody)
{
// It *is* trivial, but this will happen when the sensor is being set up, so don't warn then.
return false;