/// <summary>
        /// Check setup for warnings.
        /// </summary>
        /// <param name="obj">Target SceneTrackObject</param>
        static void CheckWarnings(SceneTrackObject obj)
        {
            if (_warnings == null)
            {
                _warnings = new List <Warnings>(4);
            }

            if (_missingObjectsOnBones == null)
            {
                _missingObjectsOnBones = new List <Transform>(1);
            }

            if (_enabledChildren == null)
            {
                _enabledChildren = new List <SceneTrackObject>(1);
            }

            _warnings.Clear();
            _missingObjectsOnBones.Clear();
            _enabledChildren.Clear();

            var tr  = obj.transform;
            var mf  = obj.GetComponent <MeshFilter>();
            var mr  = obj.GetComponent <MeshRenderer>();
            var smr = obj.GetComponent <SkinnedMeshRenderer>();

            var localScale = tr.localScale;

            // Check SkinnedMeshRenderer
            if (smr != null)
            {
                if (obj.TrackMeshRenderer == false)
                {
                    PushWarning(Warnings.DisabledMeshRecording);
                }

                if (smr.rootBone == null)
                {
                    PushWarning(Warnings.NoRootBone);
                }

                if (smr.sharedMesh == null)
                {
                    PushWarning(Warnings.NoSkinnedMesh);
                }

                if (obj.overrideMesh == true && obj.overrideMeshMesh == null)
                {
                    PushWarning(Warnings.MissingExportPoseMesh);
                }

                if (smr.sharedMaterials.Length == 0)
                {
                    PushWarning(Warnings.NoMaterial);
                }
                else
                {
                    if (smr.sharedMaterials[0].mainTexture == null)
                    {
                        PushWarning(Warnings.NoMaterialMainTexture);
                    }
                }

                if (Mathf.Approximately(localScale.x, 1.0f) == false ||
                    Mathf.Approximately(localScale.y, 1.0f) == false ||
                    Mathf.Approximately(localScale.z, 1.0f) == false)
                {
                    PushWarning(Warnings.ScaledSkinnedMeshRenderer);
                }

                if (smr.bones != null)
                {
                    foreach (var boneTr in smr.bones)
                    {
                        SceneTrackObject boneObject = boneTr.GetComponent <SceneTrackObject>();

                        if (boneObject == null)
                        {
                            PushWarning(Warnings.NotAllBonesHaveObjects);
                            _missingObjectsOnBones.Add(boneTr);
                        }
                    }
                    _missingObjectsOnBones.Sort((x, y) => x.name.CompareTo(y.name));
                }
                else
                {
                    PushWarning(Warnings.NoBones);
                }
            }

            // Check Mesh Renderer
            if (mr != null)
            {
                Material mat = null;

                if (mr.sharedMaterial != null)
                {
                    mat = mr.sharedMaterial;
                }
                else if (mr.sharedMaterials != null)
                {
                    if (mr.sharedMaterials[0] != null)
                    {
                        mat = mr.sharedMaterials[0];
                    }
                }

                if (mat == null)
                {
                    PushWarning(Warnings.NoMaterial);
                }
                else
                {
                    if (mat.mainTexture == null)
                    {
                        PushWarning(Warnings.NoMaterialMainTexture);
                    }
                }
            }
            else
            {
                if (mf != null)
                {
                    PushWarning(Warnings.NoMeshRenderer);
                }
            }

            // Check MeshFilter
            if (mf != null)
            {
                if (mr != null && obj.TrackMeshRenderer == false)
                {
                    PushWarning(Warnings.DisabledMeshRecording);
                }

                if (mf.sharedMesh == null)
                {
                    PushWarning(Warnings.NoMesh);
                }
            }

            // Check Tracked Object
            if (obj.TrackObject == false)
            {
                foreach (var so in obj.GetComponentsInChildren <SceneTrackObject>())
                {
                    if (so != obj && so.TrackObject == true)
                    {
                        PushWarning(Warnings.DisabledButChildTracking);
                        _enabledChildren.Add(so);
                    }
                }
            }

            // Odd Warning
            if (smr == null && mr == null && mf == null && obj.TrackMeshRenderer)
            {
                PushWarning(Warnings.NoRendererButWantsRecording);
            }
        }
        /// <summary>
        /// Unity Inspector
        /// </summary>
        public override void OnInspectorGUI()
        {
            if (Application.isPlaying)
            {
                EditorGUILayout.HelpBox("Changes Are Not Permitted During PlayMode", MessageType.Info);
                return;
            }

            bool dirty = false;

            // Get Current Reference
            _targetObject = (SceneTrackObject)target;

            if (_targetObject != lastObject)
            {
                lastObject = _targetObject;
            }

            CheckWarnings(_targetObject);
            InspectWarnings(_targetObject, ref dirty);

            SkinnedMeshRenderer smr = _targetObject.GetComponent <SkinnedMeshRenderer>();
            bool hasMeshRenderer    = _targetObject.GetComponent <MeshRenderer>() != null || smr != null;
            bool hasCollider        = _targetObject.GetComponent <Collider>() != null;

            GUILayout.Space(5);

            EditorGUILayout.LabelField("Tracking", EditorStyles.boldLabel);

            _targetObject.TrackObject = EditorGUILayout.Toggle("Track Object", _targetObject.TrackObject);

            EditorGUI.BeginDisabledGroup(!_targetObject.TrackObject);

            EditorGUILayout.LabelField("Components", EditorStyles.miniBoldLabel);
            EditorGUI.indentLevel++;

            if (hasMeshRenderer)
            {
                EditorGUILayout.BeginHorizontal();

                _targetObject.TrackMeshRenderer = EditorGUILayout.Toggle("Mesh", _targetObject.TrackMeshRenderer);

                if (smr != null && smr.sharedMesh != null && _targetObject.TrackMeshRenderer)
                {
                    if (_targetObject.overrideMesh == false && _targetObject.overrideMeshMesh == null)
                    {
                        if (GUILayout.Button("Set as Export Pose", EditorStyles.miniButton, GUILayout.Width(140)))
                        {
                            SetExportPose(_targetObject, smr);
                            dirty = true;
                        }
                    }
                    else
                    {
                        if (_targetObject.overrideMeshMesh == null)
                        {
                            GUILayout.Label("Missing Export Pose Mesh Asset!", EditorStyles.boldLabel);
                        }
                        else
                        {
                            if (GUILayout.Button("Remove Export Pose", EditorStyles.miniButton, GUILayout.Width(140)) && _targetObject.overrideMeshMesh != null)
                            {
                                RemoveExportPose(_targetObject, smr);
                                dirty = true;
                            }
                        }
                    }
                }
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();
            }

            if (hasCollider)
            {
                _targetObject.TrackPhysics = EditorGUILayout.Toggle("Physics Events", _targetObject.TrackPhysics);
            }

            EditorGUI.indentLevel--;

            if (_targetObject.TrackPhysics)
            {
                GUILayout.Space(10);
                EditorGUILayout.LabelField("User Defined Data", EditorStyles.boldLabel);
                _targetObject.UserDefinedData = EditorGUILayout.TextField(_targetObject.UserDefinedData);
            }

            EditorGUI.EndDisabledGroup();

            GUILayout.Space(10);

            // Calculate Children
            EditorGUILayout.LabelField("Children Trackers", EditorStyles.boldLabel);
            EditorGUILayout.BeginHorizontal();

            if (GUILayout.Button("Add", EditorStyles.miniButtonLeft))
            {
                // Look through all children (even inactive ones)
                foreach (var t in _targetObject.GetComponentsInChildren <Transform>(true))
                {
                    if (t.GetComponent <SceneTrackObject>() == null)
                    {
                        t.gameObject.AddComponent <SceneTrackObject>();
                    }
                }

                // Update Cache List
                SceneTrack.Unity.System.CacheKnownObjects();
            }

            if (GUILayout.Button("Remove", EditorStyles.miniButtonMid))
            {
                // Look through all children (even inactive ones)
                foreach (var t in _targetObject.GetComponentsInChildren <Transform>(true))
                {
                    var reference = t.GetComponent <SceneTrackObject>();
                    if (reference != null && reference != _targetObject)
                    {
                        UnityEngine.Object.DestroyImmediate(reference);
                    }
                }

                // Update Cache List
                SceneTrack.Unity.System.CacheKnownObjects();
            }

            if (GUILayout.Button("Enable", EditorStyles.miniButtonMid))
            {
                // Look through all children (even inactive ones)
                foreach (var t in _targetObject.GetComponentsInChildren <Transform>(true))
                {
                    var reference = t.GetComponent <SceneTrackObject>();
                    if (reference != null && reference != _targetObject)
                    {
                        reference.TrackObject = true;
                    }
                }

                // Update Cache List
                SceneTrack.Unity.System.CacheKnownObjects();
            }

            if (GUILayout.Button("Disable", EditorStyles.miniButtonRight))
            {
                // Look through all children (even inactive ones)
                foreach (var t in _targetObject.GetComponentsInChildren <Transform>(true))
                {
                    var reference = t.GetComponent <SceneTrackObject>();
                    if (reference != null && reference != _targetObject)
                    {
                        reference.TrackObject = false;
                    }
                }

                // Update Cache List
                SceneTrack.Unity.System.CacheKnownObjects();
            }

            EditorGUILayout.EndHorizontal();

            GUILayout.Space(10);

            if (dirty || GUI.changed)
            {
                EditorUtility.SetDirty(_targetObject);
                EditorSceneManager.MarkAllScenesDirty();
                CheckWarnings(_targetObject);
            }
        }