// Awake ops void AwakeMethods() { // Create RayFire manager if not created RayfireMan.RayFireManInit(); // Set components for mesh / skinned mesh / clusters SetComponentsBasic(); // Set particles RFParticles.SetParticleComponents(this); // Init mesh root. if (SetRootMesh() == true) { return; } // Check for user mistakes RFLimitations.Checks(this); // Set components for mesh / skinned mesh / clusters SetComponentsPhysics(); // Initialization Mesh input if (meshDemolition.meshInput == RFDemolitionMesh.MeshInputType.AtInitialization) { MeshInput(); } // Precache meshes at awake AwakePrecache(); // Prefragment object at awake AwakePrefragment(); }
// Destroy fragments and root static void DestroyFragments(RayfireRigid scr) { // Destroy fragments if (scr.HasFragments == true) { // Get amount of fragments int fragmentNum = scr.fragments.Count(t => t != null); // Destroy fragments and root for (int i = scr.fragments.Count - 1; i >= 0; i--) { if (scr.fragments[i] != null) { // Destroy fragment RayfireMan.DestroyGo(scr.fragments[i].gameObject); // Destroy root if (scr.fragments[i].rootParent != null) { RayfireMan.DestroyGo(scr.fragments[i].rootParent.gameObject); } } } // Nullify scr.fragments = null; // Subtract amount of deleted fragments RayfireMan.inst.advancedDemolitionProperties.currentAmount -= fragmentNum; // Destroy descendants if (scr.limitations.descendants.Count > 0) { // Get amount of descendants int descendantNum = scr.limitations.descendants.Count(t => t != null); // Destroy fragments and root for (int i = 0; i < scr.limitations.descendants.Count; i++) { if (scr.limitations.descendants[i] != null) { // Destroy fragment RayfireMan.DestroyGo(scr.limitations.descendants[i].gameObject); // Destroy root if (scr.limitations.descendants[i].rootParent != null) { RayfireMan.DestroyGo(scr.limitations.descendants[i].rootParent.gameObject); } } } // Clear scr.limitations.descendants = new List <RayfireRigid>(); // Subtract amount of deleted fragments RayfireMan.inst.advancedDemolitionProperties.currentAmount -= descendantNum; } } }
// Set instance void SetInstance() { // Set new static instance if (inst == null) { inst = this; } // Static instance not defined if (inst != null) { // Instance is this mono if (inst == this) { // Set vars SetVariables(); // Start pooling objects for fragments StartPooling(); } // Instance is not this mono if (inst != this) { Destroy(gameObject); } } }
// Destroy particles static void DestroyParticles(RayfireRigid scr) { // Destroy debris if (scr.HasDebris == true) { for (int d = 0; d < scr.debrisList.Count; d++) { if (scr.debrisList[d].hostTm != null) { scr.debrisList[d].hostTm.gameObject.SetActive(false); RayfireMan.DestroyGo(scr.debrisList[d].hostTm.gameObject); } } } // Destroy debris if (scr.HasDust == true) { for (int d = 0; d < scr.dustList.Count; d++) { if (scr.dustList[d].hostTm != null) { scr.dustList[d].hostTm.gameObject.SetActive(false); RayfireMan.DestroyGo(scr.dustList[d].hostTm.gameObject); } } } }
// Exclude from simulation, move under ground, destroy static IEnumerator FadeScaleDownCor(RayfireRigid scr) { // Scale object down during fade time float waitStep = 0.04f; int steps = (int)(scr.fading.fadeTime / waitStep); Vector3 vectorStep = scr.transForm.localScale / steps; // Repeat while (steps > 0) { steps--; // Scale down scr.transForm.localScale -= vectorStep; // Wait yield return(new WaitForSeconds(waitStep)); // Destroy when too small if (steps < 4) { RayfireMan.DestroyFragment(scr, scr.rootParent); } } }
// Init broke restriction static void BrokeRestriction(RayfireRigid scr) { // Set state scr.restriction.broke = true; // Event scr.restrictionEvent.InvokeLocalEvent(scr); RFRestrictionEvent.InvokeGlobalEvent(scr); // Destroy/Deactivate if (scr.restriction.breakAction == RFBoundActionType.PostDemolitionAction) { RayfireMan.DestroyFragment(scr, scr.rootParent); } // Fade else if (scr.restriction.breakAction == RFBoundActionType.Fade) { RFFade.Fade(scr); } // Reset else if (scr.restriction.breakAction == RFBoundActionType.Reset) { RFReset.ResetRigid(scr); } }
// Create RayFire manager if not created public static void RayFireManInit() { if (inst == null) { GameObject rfMan = new GameObject("RayFireMan"); inst = rfMan.AddComponent <RayfireMan>(); } EditorCreate(); }
/// ///////////////////////////////////////////////////////// /// Coroutines /// ///////////////////////////////////////////////////////// // Exclude from simulation, move under ground, destroy static IEnumerator FadeMoveDown(RayfireRigid scr) { // Activate inactive if (scr.simulationType == SimType.Inactive) { scr.Activate(); } // Wale up if sleeping scr.physics.rigidBody.WakeUp(); // Turn off collider // TODO CHECK CLUSTER COLLIDERS scr.physics.meshCollider.enabled = false; // Wait to fall down yield return(new WaitForSeconds(scr.fading.fadeTime)); // Check if fragment is the last child in root and delete root as well RayfireMan.DestroyFragment(scr, scr.rootParent); }
// SLice mesh public static void SliceMesh(RayfireRigid scr) { // Empty lists scr.DeleteCache(); scr.DeleteFragments(); // SLice RFFragment.SliceMeshes(ref scr.meshes, ref scr.pivots, ref scr.subIds, scr, scr.limitations.slicePlanes); // Remove plane info scr.limitations.slicePlanes.Clear(); // Stop if (scr.HasMeshes == false) { return; } // Get fragments scr.fragments = RFDemolitionMesh.CreateSlices(scr); // TODO check for fragments // Set demolition scr.limitations.demolished = true; // Fragments initialisation scr.InitMeshFragments(); // Event scr.demolitionEvent.InvokeLocalEvent(scr); RFDemolitionEvent.InvokeGlobalEvent(scr); // Destroy original RayfireMan.DestroyFragment(scr, scr.rootParent); }
/// ///////////////////////////////////////////////////////// /// Coroutines /// ///////////////////////////////////////////////////////// // Exclude from simulation, move under ground, destroy static IEnumerator FadeMoveDown(RayfireRigid scr) { // Activate inactive if (scr.simulationType == SimType.Inactive) { scr.Activate(); } // Wale up if sleeping scr.physics.rigidBody.WakeUp(); // Turn off collider if (scr.objectType == ObjectType.Mesh) { if (scr.physics.meshCollider != null) { scr.physics.meshCollider.enabled = false; } } else if (scr.objectType == ObjectType.ConnectedCluster || scr.objectType == ObjectType.NestedCluster) { if (scr.physics.clusterColliders != null) { for (int i = 0; i < scr.physics.clusterColliders.Count; i++) { scr.physics.clusterColliders[i].enabled = false; } } } // Wait to fall down yield return(new WaitForSeconds(scr.fading.fadeTime)); // Check if fragment is the last child in root and delete root as well RayfireMan.DestroyFragment(scr, scr.rootParent); }
// Slice object public void SliceObjectByPlanes() { // Empty lists DeleteCache(); DeleteFragments(); // SLice RFFragment.SliceMeshes(ref meshes, ref pivots, ref subIds, this, limitations.slicePlanes); // Remove plane info limitations.slicePlanes.Clear(); // Stop if (HasMeshes == false) { return; } // Get fragments fragments = CreateSlices(); // TODO check for fragments // Set demolition limitations.demolished = true; // Fragments initialisation InitFragments(); // Event demolitionEvent.InvokeLocalEvent(this); RFDemolitionEvent.InvokeGlobalEvent(this); // Destroy original RayfireMan.DestroyFragment(this, rootParent); }
// Demolish object public void Demolish() { // Profiler.BeginSample ("Demolition"); // Debug.Log (limitations.demolitionShould); // Initialize if not if (initialized == false) { Initialize(); } // Timestamp float t1 = Time.realtimeSinceStartup; // Restore position and rotation to prevent high collision offset transForm.position = physics.position; transForm.rotation = physics.rotation; // Demolish mesh or cluster to reference if (RFReferenceDemolition.DemolishReference(this) == false) { return; } // Demolish mesh and create fragments. Stop if runtime caching or no meshes/fragments were created if (RFDemolitionMesh.DemolishMesh(this) == false) { return; } /* EXPERIMENTAL * // TODO Clusterize * bool clusterize = true; * if (clusterize == true && objectType == ObjectType.Mesh && demolitionType == DemolitionType.Runtime) * { * * foreach (var frag in fragments) * { * Destroy (frag.physics.rigidBody); * Destroy (frag); * } * * RayfireRigid scr = this.rootChild.gameObject.AddComponent<RayfireRigid>(); * this.CopyPropertiesTo (scr); * scr.demolitionType = DemolitionType.Runtime; * scr.objectType = ObjectType.ConnectedCluster; * * scr.limitations.contactPoint = this.limitations.contactPoint; * scr.limitations.contactNormal = this.limitations.contactNormal; * scr.limitations.contactVector3 = this.limitations.contactVector3; * * scr.physics.velocity = this.physics.velocity; * * scr.clusterDemolition.cluster = new RFCluster(); * scr.Initialize(); * * scr.physics.rigidBody.velocity = this.physics.velocity; * scr.limitations.demolitionShould = true; * //scr.Demolish(); * RayfireMan.DestroyFragment (this, rootParent); * return; * } */ // Demolish cluster to children nodes if (RFDemolitionCluster.DemolishCluster(this) == true) { return; } // Check fragments and proceed TODO separate flow for connected cls demolition if (limitations.demolished == false) { limitations.demolitionShould = false; demolitionType = DemolitionType.None; return; } // Connectivity check activation.CheckConnectivity(); // Fragments initialisation InitMeshFragments(); // Sum total demolition time RayfireMan.inst.maxTimeThisFrame += Time.realtimeSinceStartup - t1; // Init particles RFParticles.InitDemolitionParticles(this); // Init sound RFSound.DemolitionSound(sound, limitations.bboxSize); // Event demolitionEvent.InvokeLocalEvent(this); RFDemolitionEvent.InvokeGlobalEvent(this); // Destroy demolished object RayfireMan.DestroyFragment(this, rootParent); // Timestamp // float t2 = Time.realtimeSinceStartup; // Debug.Log (t2 - t1); // Profiler.EndSample(); }
/// ///////////////////////////////////////////////////////// /// Coroutines /// ///////////////////////////////////////////////////////// // Start life coroutine IEnumerator LivingCor(RayfireRigid scr) { // Wait for simulation get rest if (scr.fading.lifeType == RFFadeLifeType.BySimulationAndLifeTime) { yield return(scr.StartCoroutine(SimulationCor(scr))); } // Set living scr.fading.state = 1; // Get final life duration float lifeDuration = scr.fading.lifeTime; if (scr.fading.lifeVariation > 0) { lifeDuration += Random.Range(0f, scr.fading.lifeVariation); } // Wait life time if (lifeDuration > 0) { yield return(new WaitForSeconds(lifeDuration)); } // Stop fading if (stop == true) { scr.fading.Reset(); yield break; } // Set fading scr.fading.state = 2; // TODO MAKE RESETABLE // scr.reset.action = RFReset.PostDemolitionType.DestroyWithDelay; // Exclude from simulation and keep object in scene if (scr.fading.fadeType == FadeType.SimExclude) { FadeExclude(scr); } // Exclude from simulation, move under ground, destroy else if (scr.fading.fadeType == FadeType.MoveDown) { scr.StartCoroutine(FadeMoveDown(scr)); } // Start scale down and destroy else if (scr.fading.fadeType == FadeType.ScaleDown) { scr.StartCoroutine(FadeScaleDownCor(scr)); } // Destroy object else if (scr.fading.fadeType == FadeType.Destroy) { RayfireMan.DestroyFragment(scr, scr.rootParent); } }
// Demolish object to reference public static bool DemolishReference(RayfireRigid scr) { if (scr.demolitionType == DemolitionType.ReferenceDemolition) { // Get instance GameObject referenceGo = scr.referenceDemolition.GetReference(); // Has reference if (referenceGo != null) { // Instantiate turned off reference bool refState = referenceGo.activeSelf; referenceGo.SetActive(false); GameObject fragRoot = scr.InstantiateGo(referenceGo); referenceGo.SetActive(refState); fragRoot.name = referenceGo.name; // Set tm scr.rootChild = fragRoot.transform; scr.rootChild.position = scr.transForm.position; scr.rootChild.rotation = scr.transForm.rotation; scr.rootChild.transform.parent = RayfireMan.inst.transForm; // Clear list for fragments scr.fragments = new List <RayfireRigid>(); // Check root for rigid props RayfireRigid rootScr = fragRoot.gameObject.GetComponent <RayfireRigid>(); // Reference Root has not rigid. Add to if (rootScr == null && scr.referenceDemolition.addRigid == true) { // Add rigid and copy rootScr = fragRoot.gameObject.AddComponent <RayfireRigid>(); rootScr.initialization = RayfireRigid.InitType.AtStart; scr.CopyPropertiesTo(rootScr); // Copy particles RFParticles.CopyParticles(scr, rootScr); // Single mesh TODO improve if (fragRoot.transform.childCount == 0) { rootScr.objectType = ObjectType.Mesh; } // Multiple meshes if (fragRoot.transform.childCount > 0) { rootScr.objectType = ObjectType.MeshRoot; } } // Activate and init rigid scr.rootChild.gameObject.SetActive(true); // Reference has rigid if (rootScr != null) { // Create rigid for root children if (rootScr.objectType == ObjectType.MeshRoot) { for (int i = 0; i < rootScr.fragments.Count; i++) { rootScr.fragments[i].limitations.currentDepth++; } scr.fragments.AddRange(rootScr.fragments); scr.DestroyRigid(rootScr); } // Get ref rigid else if (rootScr.objectType == ObjectType.Mesh || rootScr.objectType == ObjectType.SkinnedMesh) { rootScr.meshDemolition.runtimeCaching.type = CachingType.Disable; RFDemolitionMesh.DemolishMesh(rootScr); // TODO COPY MESH DATA FROM ROOTSCR TO THIS TO REUSE scr.fragments.AddRange(rootScr.fragments); RayfireMan.DestroyFragment(rootScr, rootScr.rootParent, 1f); } // Get ref rigid else if (rootScr.objectType == ObjectType.NestedCluster || rootScr.objectType == ObjectType.ConnectedCluster) { rootScr.Default(); rootScr.limitations.contactPoint = scr.limitations.contactPoint; RFDemolitionCluster.DemolishCluster(rootScr); rootScr.physics.exclude = true; scr.fragments.AddRange(rootScr.fragments); RayfireMan.DestroyFragment(rootScr, rootScr.rootParent, 1f); } // Has rigid by has No fragments. Stop demolition if (scr.HasFragments == false) { scr.demolitionType = DemolitionType.None; return(false); } } } // Has no rigid, has No fragments, but demolished scr.limitations.demolished = true; } return(true); }
// Inspector editing public override void OnInspectorGUI() { // Get target RayfireMan man = target as RayfireMan; // Set new static instance if (RayfireMan.inst == null) { RayfireMan.inst = man; } // Draw script UI DrawDefaultInspector(); // Info GUILayout.Label(" Info:", EditorStyles.boldLabel); // Pool if (Application.isPlaying == true) { if (man.fragments.poolList.Count > 0) { GUILayout.Label("Pool amount: " + man.fragments.poolList.Count); } if (man.advancedDemolitionProperties.currentAmount > 0) { GUILayout.Label("Fragments: " + man.advancedDemolitionProperties.currentAmount + "/" + man.advancedDemolitionProperties.maximumAmount); } } // Space GUILayout.Space(5); // About GUILayout.Label(" About", EditorStyles.boldLabel); // Version GUILayout.Label("Plugin build: " + RayfireMan.buildMajor + '.' + RayfireMan.buildMinor.ToString("D2")); // Logo TODO remove if component removed if (logo == null) { logo = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/RayFire/Info/Logo/logo_small.png", typeof(Texture2D)); } if (logo != null) { GUILayout.Box(logo, GUILayout.Width((int)EditorGUIUtility.currentViewWidth - 19f), GUILayout.Height(64)); } // Begin GUILayout.BeginHorizontal(); // Changelog check if (GUILayout.Button(" Changelog ", GUILayout.Height(20))) { Application.OpenURL("http://rayfirestudios.com/main/unity-changelog/"); } // Update check if (GUILayout.Button("Check for updates", GUILayout.Height(20))) { Application.OpenURL("https://assetstore.unity.com/packages/templates/systems/rayfire-for-unity-148690"); } // End EditorGUILayout.EndHorizontal(); // Space GUILayout.Space(3); }
// Create fragments by mesh and pivots array public static List <RayfireRigid> CreateFragments(RayfireRigid scr) { // Fragments list List <RayfireRigid> scrArray = new List <RayfireRigid>(); // Stop if has no any meshes if (scr.meshes == null) { return(scrArray); } // Create RayFire manager if not created RayfireMan.RayFireManInit(); // Create root object and parent RFLimitations.CreateRoot(scr); // Vars int baseLayer = scr.meshDemolition.GetLayer(scr); string baseTag = scr.gameObject.tag; string baseName = scr.gameObject.name + fragmentStr; // Save original rotation // Quaternion originalRotation = rootChild.transform.rotation; // Set rotation to precache rotation if (scr.demolitionType == DemolitionType.AwakePrecache) { scr.rootChild.transform.rotation = scr.cacheRotation; } // Get original mats Material[] mats = scr.skinnedMeshRend != null ? scr.skinnedMeshRend.sharedMaterials : scr.meshRenderer.sharedMaterials; // Create fragment objects for (int i = 0; i < scr.meshes.Length; ++i) { // Get object from pool or create RayfireRigid rfScr = RayfireMan.inst == null ? RFPoolingFragment.CreateRigidInstance() : RayfireMan.inst.fragments.GetPoolObject(RayfireMan.inst.transForm); // Setup rfScr.transform.position = scr.transForm.position + scr.pivots[i]; rfScr.transform.parent = scr.rootChild; rfScr.name = baseName + i; rfScr.gameObject.tag = baseTag; rfScr.gameObject.layer = baseLayer; rfScr.meshFilter.sharedMesh = scr.meshes[i]; rfScr.rootParent = scr.rootChild; // Copy properties from parent to fragment node scr.CopyPropertiesTo(rfScr); // Copy particles RFParticles.CopyParticles(scr, rfScr); // Set collider RFPhysic.SetFragmentMeshCollider(rfScr, scr.meshes[i]); // Shadow casting if (RayfireMan.inst.advancedDemolitionProperties.sizeThreshold > 0 && RayfireMan.inst.advancedDemolitionProperties.sizeThreshold > scr.meshes[i].bounds.size.magnitude) { rfScr.meshRenderer.shadowCastingMode = ShadowCastingMode.Off; } // Turn on rfScr.gameObject.SetActive(true); // Set multymaterial RFSurface.SetMaterial(scr.subIds, mats, scr.materials, rfScr.meshRenderer, i, scr.meshes.Length); // Update depth level and amount rfScr.limitations.currentDepth = scr.limitations.currentDepth + 1; rfScr.meshDemolition.amount = (int)(rfScr.meshDemolition.amount * rfScr.meshDemolition.depthFade); if (rfScr.meshDemolition.amount < 3) { rfScr.meshDemolition.amount = 3; } // Add in array scrArray.Add(rfScr); // Debug.Log (rfScr.rootParent); } // Fix transform for precached fragments if (scr.demolitionType == DemolitionType.AwakePrecache) { scr.rootChild.rotation = scr.transForm.rotation; } // Fix runtime caching rotation difference. Get rotation difference and add to root if (scr.demolitionType == DemolitionType.Runtime && scr.meshDemolition.runtimeCaching.type != CachingType.Disable) { Quaternion cacheRotationDif = scr.transForm.rotation * Quaternion.Inverse(scr.meshDemolition.cacheRotationStart); scr.rootChild.rotation = cacheRotationDif * scr.rootChild.rotation; } return(scrArray); }
// Demolish object public void Demolish() { // Profiler.BeginSample ("Demolition"); // Debug.Log (limitations.demolitionShould); // Initialize if not if (initialized == false) { Initialize(); } // Timestamp float t1 = Time.realtimeSinceStartup; // Restore position and rotation to prevent high collision offset transForm.position = physics.position; transForm.rotation = physics.rotation; // Demolish mesh or cluster to reference if (RFReferenceDemolition.DemolishReference(this) == false) { return; } // Demolish mesh and create fragments. Stop if runtime caching or no meshes/fragments were created if (RFDemolitionMesh.DemolishMesh(this) == false) { return; } // Demolish cluster to children nodes if (RFDemolitionCluster.DemolishCluster(this) == true) { return; } // Check fragments and proceed TODO separate flow for connected cls demolition if (limitations.demolished == false) { limitations.demolitionShould = false; demolitionType = DemolitionType.None; return; } // Connectivity check activation.CheckConnectivity(); // Fragments initialisation InitMeshFragments(); // Sum total demolition time RayfireMan.inst.maxTimeThisFrame += Time.realtimeSinceStartup - t1; // Init particles RFParticles.InitDemolitionParticles(this); // Event demolitionEvent.InvokeLocalEvent(this); RFDemolitionEvent.InvokeGlobalEvent(this); // Destroy demolished object RayfireMan.DestroyFragment(this, rootParent); // Timestamp // float t2 = Time.realtimeSinceStartup; // Debug.Log (t2 - t1); // Profiler.EndSample(); }
// Create slices by mesh and pivots array public static List <RayfireRigid> CreateSlices(RayfireRigid scr) { // Fragments list List <RayfireRigid> scrArray = new List <RayfireRigid>(); // Stop if has no any meshes if (scr.meshes == null) { return(scrArray); } // Create RayFire manager if not created RayfireMan.RayFireManInit(); // Create root object and parent RFLimitations.CreateRoot(scr); // Vars int baseLayer = scr.meshDemolition.GetLayer(scr); string baseTag = scr.gameObject.tag; string baseName = scr.gameObject.name + fragmentStr; // Get original mats Material[] mats = scr.skinnedMeshRend != null ? scr.skinnedMeshRend.sharedMaterials : scr.meshRenderer.sharedMaterials; // Create fragment objects for (int i = 0; i < scr.meshes.Length; ++i) { // Get object from pool or create RayfireRigid rfScr = RayfireMan.inst == null ? RFPoolingFragment.CreateRigidInstance() : RayfireMan.inst.fragments.GetPoolObject(RayfireMan.inst.transForm); // Setup rfScr.transform.position = scr.transForm.position + scr.pivots[i]; rfScr.transform.parent = scr.rootChild; rfScr.name = baseName + i; rfScr.gameObject.tag = baseTag; rfScr.gameObject.layer = baseLayer; rfScr.meshFilter.sharedMesh = scr.meshes[i]; rfScr.rootParent = scr.rootChild; // Copy properties from parent to fragment node scr.CopyPropertiesTo(rfScr); // Copy particles RFParticles.CopyParticles(scr, rfScr); // Set collider RFPhysic.SetFragmentMeshCollider(rfScr, scr.meshes[i]); // Shadow casting if (RayfireMan.inst.advancedDemolitionProperties.sizeThreshold > 0 && RayfireMan.inst.advancedDemolitionProperties.sizeThreshold > scr.meshes[i].bounds.size.magnitude) { rfScr.meshRenderer.shadowCastingMode = ShadowCastingMode.Off; } // Turn on rfScr.gameObject.SetActive(true); // Set multymaterial RFSurface.SetMaterial(scr.subIds, mats, scr.materials, rfScr.meshRenderer, i, scr.meshes.Length); // Update depth level and amount rfScr.limitations.currentDepth = scr.limitations.currentDepth + 1; //rfScr.meshDemolition.amount = (int)(rfScr.meshDemolition.amount * rfScr.meshDemolition.depthFade); //if (rfScr.meshDemolition.amount < 2) // rfScr.meshDemolition.amount = 2; // Add in array scrArray.Add(rfScr); } // Empty lists scr.DeleteCache(); return(scrArray); }
// Demolish object to reference public static bool DemolishReference(RayfireRigid scr) { if (scr.demolitionType == DemolitionType.ReferenceDemolition) { // Demolished scr.limitations.demolished = true; // Turn off original scr.gameObject.SetActive(false); // Get instance GameObject refGo = scr.referenceDemolition.GetReference(); // Has no reference if (refGo == null) { return(true); } // Instantiate turned off reference with null parent GameObject instGo = Object.Instantiate(refGo, scr.transForm.position, scr.transForm.rotation); instGo.name = refGo.name; // Set root to manager or to the same parent if (RayfireMan.inst != null && RayfireMan.inst.advancedDemolitionProperties.parent == RFManDemolition.FragmentParentType.Manager) { instGo.transform.parent = RayfireMan.inst.transform; } else { instGo.transform.parent = scr.transForm.parent; } // Set tm scr.rootChild = instGo.transform; // Copy scale if (scr.referenceDemolition.inheritScale == true) { scr.rootChild.localScale = scr.transForm.localScale; } // Clear list for fragments scr.fragments = new List <RayfireRigid>(); // Check root for rigid props RayfireRigid refScr = instGo.gameObject.GetComponent <RayfireRigid>(); // Reference Root has not rigid. Add to if (refScr == null && scr.referenceDemolition.addRigid == true) { // Add rigid and copy refScr = instGo.gameObject.AddComponent <RayfireRigid>(); // Copy rigid scr.CopyPropertiesTo(refScr); // Copy particles RFParticles.CopyParticles(scr, refScr); // Single mesh TODO improve if (instGo.transform.childCount == 0) { refScr.objectType = ObjectType.Mesh; } // Multiple meshes if (instGo.transform.childCount > 0) { refScr.objectType = ObjectType.MeshRoot; } } // Activate and init rigid instGo.transform.gameObject.SetActive(true); // Reference has rigid if (refScr != null) { // Init if not initialized yet refScr.Initialize(); // Create rigid for root children if (refScr.objectType == ObjectType.MeshRoot) { for (int i = 0; i < refScr.fragments.Count; i++) { refScr.fragments[i].limitations.currentDepth++; } scr.fragments.AddRange(refScr.fragments); scr.DestroyRigid(refScr); } // Get ref rigid else if (refScr.objectType == ObjectType.Mesh || refScr.objectType == ObjectType.SkinnedMesh) { refScr.meshDemolition.runtimeCaching.type = CachingType.Disable; RFDemolitionMesh.DemolishMesh(refScr); // TODO COPY MESH DATA FROM ROOTSCR TO THIS TO REUSE scr.fragments.AddRange(refScr.fragments); RayfireMan.DestroyFragment(refScr, refScr.rootParent, 1f); } // Get ref rigid else if (refScr.objectType == ObjectType.NestedCluster || refScr.objectType == ObjectType.ConnectedCluster) { refScr.Default(); // Copy contact data refScr.limitations.contactPoint = scr.limitations.contactPoint; refScr.limitations.contactVector3 = scr.limitations.contactVector3; refScr.limitations.contactNormal = scr.limitations.contactNormal; // Demolish RFDemolitionCluster.DemolishCluster(refScr); // Collect new fragments scr.fragments.AddRange(refScr.fragments); //refScr.physics.exclude = true; //RayfireMan.DestroyFragment (refScr, refScr.rootParent, 1f); } } } return(true); }