Пример #1
0
        // 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();
        }
Пример #2
0
        // 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;
                }
            }
        }
Пример #3
0
        // 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);
                }
            }
        }
Пример #4
0
        // 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);
                    }
                }
            }
        }
Пример #5
0
        // 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);
                }
            }
        }
Пример #6
0
        // 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);
            }
        }
Пример #7
0
        // Create RayFire manager if not created
        public static void RayFireManInit()
        {
            if (inst == null)
            {
                GameObject rfMan = new GameObject("RayFireMan");
                inst = rfMan.AddComponent <RayfireMan>();
            }

            EditorCreate();
        }
Пример #8
0
        /// /////////////////////////////////////////////////////////
        /// 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);
        }
Пример #9
0
        // 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);
        }
Пример #10
0
        /// /////////////////////////////////////////////////////////
        /// 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);
        }
Пример #11
0
        // 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);
        }
Пример #12
0
        // 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();
        }
Пример #13
0
        /// /////////////////////////////////////////////////////////
        /// 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);
            }
        }
Пример #14
0
        // 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);
        }
Пример #15
0
        // 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);
        }
Пример #16
0
        // 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);
        }
Пример #17
0
        // 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();
        }
Пример #18
0
        // 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);
        }
Пример #19
0
        // 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);
        }