/// <summary>
        /// Produce a string that displays the heirachy and other information about a transform.
        /// </summary>
        /// <returns>String containing the dump.</returns>
        public static string DumpTree(this Transform t, DumpTreeOption options = DumpTreeOption.Default)
        {
            StringBuilder sb = new StringBuilder();

            DumpTree(t, options, 0, sb);
            return(sb.ToString());
        }
        private static void DumpTree(Transform t, DumpTreeOption options, int level, StringBuilder sb)
        {
            string space = "";

            for (int i = 0; i < level; ++i)
            {
                space += '-';
            }
            sb.AppendLine(space + t.name);
            if ((options & DumpTreeOption.Active) == DumpTreeOption.Active)
            {
                sb.AppendLine(space + "+ activeSelf=" + t.gameObject.activeSelf + " activeInHeirachy=" + t.gameObject.activeInHierarchy);
            }
            if ((options & DumpTreeOption.TransformPosition) == DumpTreeOption.TransformPosition)
            {
                sb.AppendLine(space + "+ position: " + t.position + " localPosition: " + t.localPosition);
            }
            if ((options & DumpTreeOption.TransformRotation) == DumpTreeOption.TransformRotation)
            {
                sb.AppendLine(space + "+ rotation: " + t.rotation + " localRotation: " + t.localRotation);
            }

            if ((((int)options & 0x10) == 0))
            {
                goto skipComponents;
            }

            Renderer renderer = t.gameObject.GetComponent <Renderer>();

            foreach (Component c in t.gameObject.GetComponents <Component>())
            {
                if (!(c is Transform) && ((options & DumpTreeOption.Components) == DumpTreeOption.Components))
                {
                    sb.AppendLine(space + "+ component:" + c.GetType());
                }

                if (c is Renderer && (options & DumpTreeOption.Materials) == DumpTreeOption.Materials)
                {
                    foreach (Material m in renderer.sharedMaterials)
                    {
                        sb.AppendLine(space + "++ mat:" + m.name);
                    }
                }

                if (c is MeshFilter && (options & DumpTreeOption.Mesh) == DumpTreeOption.Mesh)
                {
                    MeshFilter filter = (MeshFilter)c;
                    sb.AppendLine(space + "++ mesh:" + ((filter.sharedMesh == null) ? "*null*" : (filter.sharedMesh.name + " verts:" + filter.sharedMesh.vertexCount)));
                }

                if (c is MeshCollider && (options & DumpTreeOption.Mesh) == DumpTreeOption.Mesh)
                {
                    MeshCollider collider = (MeshCollider)c;
                    sb.AppendLine(space + "++ mesh:" + ((collider.sharedMesh == null) ? "*null*" : (collider.sharedMesh.name + " verts:" + collider.sharedMesh.vertexCount)));
                }

                if (c is Rigidbody && (options & DumpTreeOption.Rigidbody) == DumpTreeOption.Rigidbody)
                {
                    Rigidbody body = (Rigidbody)c;
                    sb.AppendLine(space + "++ Mass:" + body.mass.ToString("F3"));
                    sb.AppendLine(space + "++ CoM:" + body.centerOfMass.ToString("F3"));
                }
                if (c is Joint && (options & DumpTreeOption.Rigidbody) == DumpTreeOption.Rigidbody)
                {
                    Joint joint = (Joint)c;
                    sb.AppendLine(space + "++ anchor:" + joint.anchor.ToString("F3"));

                    sb.AppendLine(space + "++ connectedBody: " + (joint.connectedBody != null));
                    if (joint.connectedBody != null)
                    {
                        DumpTree(joint.connectedBody.transform, options, level + 1, sb);
                    }
                }
            }

skipComponents:
            for (int i = 0; i < t.childCount; ++i)
            {
                DumpTree(t.GetChild(i), options, level + 1, sb);
            }
        }