/// <summary>Collects all the models in the part or hierarchy.</summary> /// <remarks> /// The result of this method only includes meshes and renderers. Any colliders, animations or /// effects will be dropped. /// <para> /// Note, that this method captures the current model state fro the part, which may be affected /// by animations or third-party mods. That said, each call for the same part may return different /// results. /// </para> /// </remarks> /// <param name="rootPart">The part to start scanning the assembly from.</param> /// <param name="goThruChildren"> /// Tells if the parts down the hierarchy need to be captured too. /// </param> /// <returns> /// The root game object of the new hirerarchy. This object must be explicitly disposed when not /// needed anymore. /// </returns> public GameObject GetSceneAssemblyModel(Part rootPart, bool goThruChildren = true) { var modelObj = UnityEngine.Object.Instantiate <GameObject>( Hierarchy.GetPartModelTransform(rootPart).gameObject); modelObj.SetActive(true); // This piece of code was stolen from PartLoader.CreatePartIcon (alas, it's private). PartLoader.StripComponent <EffectBehaviour>(modelObj); PartLoader.StripGameObject <Collider>(modelObj, "collider"); PartLoader.StripComponent <Collider>(modelObj); PartLoader.StripComponent <WheelCollider>(modelObj); PartLoader.StripComponent <SmokeTrailControl>(modelObj); PartLoader.StripComponent <FXPrefab>(modelObj); PartLoader.StripComponent <ParticleSystem>(modelObj); PartLoader.StripComponent <Light>(modelObj); PartLoader.StripComponent <Animation>(modelObj); PartLoader.StripComponent <DAE>(modelObj); PartLoader.StripComponent <MeshRenderer>(modelObj, "Icon_Hidden", true); PartLoader.StripComponent <MeshFilter>(modelObj, "Icon_Hidden", true); PartLoader.StripComponent <SkinnedMeshRenderer>(modelObj, "Icon_Hidden", true); if (goThruChildren) { foreach (var childPart in rootPart.children) { var childObj = GetSceneAssemblyModel(childPart); childObj.transform.parent = modelObj.transform; childObj.transform.localRotation = rootPart.transform.rotation.Inverse() * childPart.transform.rotation; childObj.transform.localPosition = rootPart.transform.InverseTransformPoint(childPart.transform.position); } } return(modelObj); }
/// <summary>Collects all the models in the part or hierarchy.</summary> /// <remarks> /// The result of this method only includes meshes and renderers. Any colliders, animations or /// effects will be dropped. /// <para> /// Note, that this method captures the current model state fro the part, which may be affected /// by animations or third-party mods. That said, each call for the same part may return different /// results. /// </para> /// </remarks> /// <param name="rootPart">The part to start scanning the assembly from.</param> /// <param name="goThruChildren"> /// Tells if the parts down the hierarchy need to be captured too. /// </param> /// <returns> /// The root game object of the new hirerarchy. This object must be explicitly disposed when not /// needed anymore. /// </returns> public GameObject GetSceneAssemblyModel(Part rootPart, bool goThruChildren = true) { var modelObj = new GameObject("KisAssemblyRoot"); modelObj.SetActive(true); // Add a root object with scale 1.0 to account any part model adjustments. var partModelObj = UnityEngine.Object.Instantiate <GameObject>( Hierarchy.GetPartModelTransform(rootPart).gameObject, modelObj.transform, false); partModelObj.SetActive(true); // Drop stuff that is not intended to show up in flight. PartLoader.StripComponent <MeshRenderer>(partModelObj, "Icon_Hidden", true); PartLoader.StripComponent <MeshFilter>(partModelObj, "Icon_Hidden", true); PartLoader.StripComponent <SkinnedMeshRenderer>(partModelObj, "Icon_Hidden", true); // Strip anything that is not mesh related. var joints = new List <Joint>(); var rbs = new List <Rigidbody>(); foreach (var component in modelObj.GetComponentsInChildren(typeof(Component))) { if (component is Transform) { continue; // Transforms belong to the GameObject. } var rb = component as Rigidbody; if (rb != null) { rbs.Add(rb); continue; // It can be tied with a joint, which must be deleted first. } var joint = component as Joint; if (joint != null) { joints.Add(joint); continue; // They must be handled before the connected RBs handled. } if (!(component is Renderer || component is MeshFilter)) { UnityEngine.Object.DestroyImmediate(component); } } // Drop joints before rigidbodies. foreach (var joint in joints) { UnityEngine.Object.DestroyImmediate(joint); } // Drop rigidbodies once it's safe to do so. foreach (var rb in rbs) { UnityEngine.Object.DestroyImmediate(rb); } if (goThruChildren) { foreach (var childPart in rootPart.children) { var childObj = GetSceneAssemblyModel(childPart); childObj.transform.parent = modelObj.transform; childObj.transform.localRotation = rootPart.transform.rotation.Inverse() * childPart.transform.rotation; childObj.transform.localPosition = rootPart.transform.InverseTransformPoint(childPart.transform.position); } } return(modelObj); }