Search Unity

[Released] DestroyIt - Cinematic Destruction System

Discussion in 'Assets and Asset Store' started by DeadlyAccurate, Jun 14, 2014.

  1. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    @moltke - I sent you the scripts to change in an email. Please let me know if you have any issues getting it to work. Going forward, this feature will be part of DestroyIt, in case anyone else needs it. Thanks for the feature suggestion!
     
  2. StevoFx

    StevoFx

    Joined:
    Apr 1, 2020
    Posts:
    10
    Hey, I've got 2 suggestions on features if you are open to hearing them.

    1) Making a global tick box on the destruction manager that enables and disables allowing objects to take damage. Could be useful to disable all destructible item health temporarily or after a trigger at some point in the scene.

    2) Allow us to specify a max damage received per hit. This can be useful for many reasons an example being different materials having their own max damage.
     
  3. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Excellent suggestions! Thank you, I've added these features to our to-do list.
     
    StevoFx likes this.
  4. EpicMcDude

    EpicMcDude

    Joined:
    Apr 15, 2013
    Posts:
    117
    Hi Zangad!

    I'm currently trying to make a custom Playmaker action for Destroyit using your script called WhenDestroyed.
    As I'm not proficient in C#, I don't know if this script is well made, so to speak, wondering if you had any pointers for using this WhenDestroyed event.

    Code (CSharp):
    1. using DestroyIt;
    2. using UnityEngine;
    3.  
    4. namespace HutongGames.PlayMaker.Actions
    5. {
    6.  
    7.     [ActionCategory(ActionCategory.GameObject)]
    8.     [Tooltip("Send an event when a Destroyit Destructible object is destroyed.")]
    9.     public class WhenDestroyed : FsmStateAction
    10.     {
    11.         [Tooltip("The DestroyIt Destructible object to check when it's destroyed.")]
    12.         public FsmGameObject destructibleObject;
    13.         [Tooltip("Where to send the event.")]
    14.         public FsmEventTarget eventTarget;
    15.         [RequiredField]
    16.         [Tooltip("The event to send. NOTE: Events must be marked Global to send between FSMs.")]
    17.         public FsmEvent sendEvent;
    18.  
    19.         public override void Reset()
    20.         {
    21.             destructibleObject = null;
    22.             eventTarget = null;
    23.             sendEvent = null;
    24.         }
    25.         public override void OnEnter()
    26.         {
    27.             // Try to get the Destructible script on the object. If found, attach the OnDestroyed event listener to the DestroyedEvent.
    28.             Destructible destObj = destructibleObject.Value.GetComponentInChildren<Destructible>();
    29.             if (destObj != null)
    30.                 destObj.DestroyedEvent += OnDestroyed;
    31.         }
    32.         public void OnDestroyed()
    33.         {
    34.             Fsm.Event(eventTarget, sendEvent);
    35.         }
    36.         private void OnDisable()
    37.         {
    38.             Destructible destObj = destructibleObject.Value.GetComponentInChildren<Destructible>();
    39.             // Unregister the event listener when disabled/destroyed. Very important to prevent memory leaks due to orphaned event listeners!
    40.             if (destObj == null) return;
    41.             destObj.DestroyedEvent -= OnDestroyed;
    42.         }
    43.        
    44.     }
    45.  
    46. }
    47.  
    Since when the object is destroyed, it returns a null value, I'm simply checking if the object I assigned on the PM action is null to send an event.
    This works, but am I doing it right? I'd love to create more custom actions for Destroyit as you have so many great scripts but only 3 PM actions for this asset :(~

    Thanks!
     
  5. wendymorrison

    wendymorrison

    Joined:
    Jan 6, 2014
    Posts:
    246
    Using Opsive controllers with destroyit doesn't seem to work with the sword.
     
  6. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @EpicMcDude,

    I know what you mean - I'm the opposite, though. I know C# pretty well, but I'm not very proficient in PlayMaker! :)

    I imported your Action script into my test DestroyIt Project with PlayMaker, and I was able to get it sending events when the object was destroyed, and I stepped through it in the Visual Studio debugger, and it looks good to me. Since GetComponentInChildren() will return the first Destructible component it finds (and not continue to iterate over all Destructibles in the hierarchy), I think it's pretty efficient. And since your Action script could theoretically be used anywhere in your FSM and on any object, you can't pre-cache it and hold onto the Destructible reference in the member variables section of the class, so you do need to fetch the reference each time OnEnter() is called, as you're doing.

    So as far as I can tell, you're doing it correctly. I'm certainly no PlayMaker expert, but your script is about as efficient and correct as I know how to make it.
     
    EpicMcDude likes this.
  7. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @wendymorrison,

    I have Opsive's UFPS controller asset, and I don't see a sword in that one. Are you using this asset? If so, I have reached out to Opsive to get a copy of UCC to help with integration support. Please let me know if that is not the asset you're using and I will try to get whichever one you need so I can help with getting the sword to work. In the past, I did an integration tutorial with the Third Person Controller, and I think that one has a sword in it, too, so I just need to know which controller asset you're using. Thanks!
     
  8. EpicMcDude

    EpicMcDude

    Joined:
    Apr 15, 2013
    Posts:
    117
    I'm trying to make sense of the HitEffects feature, but I'm not sure how to extend it for other uses.

    For example, how can I tell the destructible object, that it's being hit by a cannonball, a bullet or in my case a melee attack?
    I checked the Enums script and added a Melee tag, but how could I point to the character's hand as a Melee weapon type, so that when it punches anything with the Destructible component, a hit effect would instantiate?

    I also wanted to check if this could be used to instantiate a hit effect on a collision hit by anything?

    For example a barrel would spawn a hit effect on hitting the ground, the wall etc, as it loses health. I know you have the damage levels by health percentage, but having to set this up on every destructible object would be extremely time consuming.
    I thought the HitEffects script would handle that, but I have to hit it with a specific weapon type that I don't have in my own game (cannonball, weapon, rocket).
     
  9. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @EpicMcDude,

    The HitEffects script is really just a simple way to spawn particle effects based on the type of object that hit the destructible. It's not really designed for passing hit information around to other parts of your game. That can get complex quickly, depending on what type of game you're making, and the method for doing so would be different for each game. But all you need to do to get that working is drop some code into key places in DestroyIt so that it passes that info around to the appropriate parts of your game.

    So for your example, if you want to tell the Destructible object (or any other object) information about what type of weapon just hit it, the way to do this depends on whether the object hitting it is a rigidbody (like the cannonball) or not (like the hitscan bullet). The reason the method differs is because collisions with rigidbodies use the Unity physics system, and hitscan bullets (or other non-physics type of collisions) do not.

    If it's a rigidbody, you can put script like this (below) in the DestructibleExtensions.cs script, right at the end of the ProcessDestructibleCollisions() method.


    Code (CSharp):
    1. if (otherRbody != null)
    2. {
    3.     // Log the name of the rigidbody object that hit this destructible object
    4.     Debug.Log($"Object that hit me: {otherRbody.name}");
    5.  
    6.     // Log the weapon type of the rigidbody projectile that hit this destructible object
    7.     RigidbodyProjectile rbProjectile = otherRbody.GetComponent<RigidbodyProjectile>();
    8.     if (rbProjectile != null)
    9.         Debug.Log($"Weapon type that hit me: {rbProjectile.weaponType}");
    10.  
    11.     // Log the Unity tag on the the rigidbody object that hit this destructible object
    12.     Debug.Log($"Tag on object that hit me: {otherRbody.tag}");
    13. }
    This code captures info about the object that hit the destructible and logs it to the console. Of course, you don't have to log the info to the console. With that info, you could fire an event that other event listeners are listening for, and do something special with that data (like keep a scoreboard or XP tally). You could store that info in public variables added the Destructible.cs script, say create a LastObjectHitBy variable which would store details (name, tag, weapon type, damage done, etc) about the last object that hit the destructible.

    If the object that hit the Destructible is not a rigidbody and you want to collect/report information on it, then I would do that by adding similar code to the above to the weapon object itself. For instance, if I wanted to report info on hitscan bullets, I would add some code (like above) to the Bullet.cs script, at the end of the ProcessBulletHit() method. (And if that's what you're needing, I can write up some sample code for that, just let me know.)

    For a melee weapon, it again depends on how the melee weapon is setup.

    Some melee weapons use an area of effect (a trigger collider) and if that area touches something that can be damaged (like a player), it damages it. With that method, it doesn't matter how hard of a "swing" it was or how heavy of a weapon it is, it only matters that the trigger collider collided with something. In that case, it's like the hitscan bullet (or like our melee axe weapon in the demo scene) - there would be a script on the trigger collider that does the work, and that's where you would insert your code to collect/report weapon damage info.

    If the melee weapon is a rigidbody, then it would be just like the cannonball. You would add the RigidbodyProjectile.cs script to the weapon, and add a new WeaponType (ie, "Sword") in the Enums.cs script (like you did). Then you'd add your logging/reporting code to the DestructibleExtensions.cs script, like above. The benefit of a rigidbody melee weapon is that the amount of damage could be based on how hard it hit (collision magnitude) when it connected, it could even take into effect the weight (mass) of the weapon. So the method needed to achieve this really depends on how the melee system is setup, and that will be different depending on what type of game you're making.

    If you want to have an object that spawns the same effect every time it is hit, regardless of what it is hit by, then you don't need to use the HitEffects script for that. You can put a script like this (below) on any destructible object you want to spawn the effect on.

    HitEffectsWood.cs
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace DestroyIt
    4. {
    5.     [DisallowMultipleComponent]
    6.     public class HitEffectsWood : MonoBehaviour
    7.     {
    8.         private GameObject effect;
    9.  
    10.         public void Start()
    11.         {
    12.             // Load the effect from the Resources folder so we don't have to assign it on every script
    13.             // NOTE: You need to put your particle effect game object into a folder named "Resources" for this to work.
    14.             effect = Resources.Load<GameObject>("Default_Particles/WoodSplintersLarge");
    15.         }
    16.  
    17.         // Play the effect anytime a collision is detected.
    18.         // NOTE: OnCollisionEnter will only fire if a rigidbody is attached to this object!
    19.         public void OnCollisionEnter(Collision collision)
    20.         {
    21.             if (effect != null && collision.contacts.Length > 0)
    22.                 ObjectPool.Instance.Spawn(effect, collision.contacts[0].point, Quaternion.LookRotation(collision.contacts[0].normal));
    23.         }
    24.     }
    25. }
    What this script does is simply spawn the effect (in this case, LargeWoodSplinters) any time the object hits (or is hit by) anything. So if it hits the terrain, it will spawn the effect. If a rigidbody collides with it, it will spawn the effect. And it will spawn the effect at the contact point (the place it is hit) and rotate the effect to match the hit normal (the direction the hit came from) so it looks good.

    I hope this info helps. If you're still having trouble achieving the effect you want, I'd be happy to take a look at your project (just send us a link to download it to modelsharkstudio@gmail.com) and help you get over this hurdle.
     
    EpicMcDude likes this.
  10. EpicMcDude

    EpicMcDude

    Joined:
    Apr 15, 2013
    Posts:
    117
    Thank you so much for your extensive reply! I'll look into the scripts and methods you've explained in your post.

    Currently, I'm using the trigger method as I'm doing a hand-to-hand based combat, like you mentioned here:

    In the game I'm making, the player is able to damage destructible objects with their punches. The specific object is a window, so I was looking for a way to spawn the hit effect whenever the player hits the window with a punch or kick without using the damage levels. The example you gave of the Bullet script makes sense, I'll try to come up with something based on what you said!

    Many thanks!
     
  11. prolixe

    prolixe

    Joined:
    Jun 27, 2018
    Posts:
    11
    Last edited: Sep 15, 2021
  12. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @prolixe,

    Thanks for reaching out to us. No, DestroyIt is not fully integrated with Game Kit Controller out-of-the-box. However, it is a very flexible/open system and we regularly help our customers with many different asset integrations.

    Below are step-by-step instructions for getting DestroyIt to work with Game Kit Controller for bullets and the sticky grenade. There's also a video at the end - it's not narrated, but you can see the behavior before the changes, then I make the changes, then you can see the results afterwards. And I go slow, so you can pause and follow along. Note that these instructions are from about a year and a half ago, so if you purchase DestroyIt and have any issues getting this to work, just let us know here on the forum (or at modelsharkstudio@gmail.com) and I'll take another look at it and update the instructions.

    How to Integrate DestroyIt with Game Kit Controller


    1) Import Game Kit Controller
    2) Import DestroyIt
    3) Open a Game Kit Controller scene (I opened the AI Demo scene)
    4) From the Unity top menu, choose Window -> DestroyIt -> Setup Minimal
    5) Drag a destructible object into the scene (I used the Column from Assets\DestroyIt\Demos (safe to delete)\Prefabs\Destructible Objects\Pristine)
    6) Open the Assets\Game Kit Controller\Scripts\Weapons\Projectiles\projectileSystem.cs
    7) Add the following code after the "if" statement on line 336:
    Code (CSharp):
    1. // Apply damage to any DestroyIt Destructible objects
    2. DestroyIt.Destructible destObj = objectToDamage.GetComponentInParent<DestroyIt.Destructible>();
    3. if (destObj != null)
    4.     destObj.ApplyDamage(currentProjectileInfo.projectileDamage);
    8) That will take care of the bullets. If you also want to integrate the adhesive grenade, edit the Adhesive Grenade Projectile prefab as follows...
    9) Add a new empty game object named Explosion to the Adhesive Grenade Projectile prefab and disable it
    10) Add the Explosion.cs script from DestroyIt to the game object
    11) On the ProjectileSystem script on the Adhesive Grenade Projectile, add a new Event on Explosion that activates the Explosion game object
    12) Save the prefab and scene, and run. You can now shoot destructible objects and see progressive damage, as well as destroying them and blowing them up with grenades.

    Results:

    You can integrate more weapons like the knife and so on. They will all follow a similar pattern: you just need to find the Game Kit Controller code that handles impacts or damage to objects, and add a small piece of DestroyIt code that checks if the object is Destructible and if so, applies damage to Destructible objects. Once you call ApplyDamage(), DestroyIt handles the rest.

    Hope that helps!
     
  13. prolixe

    prolixe

    Joined:
    Jun 27, 2018
    Posts:
    11
    Hello @zangad

    Well its working like alway ; )

    just for the bullet the code to add on projectileSystem.cs is on line 414.

    and the Explosion.cs is now Explode.cs

    Thank You for this ; )
     
    zangad likes this.
  14. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    Hi again @zangad,

    I was just wondering your thoughts on this; I'm building an RTS using your Destroyit scripts.

    When my buildings are destroyed they bring in a destroyed prefab and when it pulls the destroyed prefab i often get a hiccup in the editor where the game freezes for a second or two. Do you have any recommendations how I could optimize this?

    here's a video showing you what i am doing

     
    zangad likes this.
  15. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @moltke,

    Thanks for uploading a video and describing the issue, it really helps. I do see the lag you're talking about. I'm not sure off-hand what could be causing it, but I have some ideas for things to look at.

    First off, I noticed you're getting some errors in your console log. I would be interested to see what errors and warnings you're getting, there. For example, if you're getting a warning that says "the destroyed prefab could not be spawned from the object pool", that would let me know there's an issue with the object pooling in your project, and the freeze is likely happening because the destroyed prefab is not being pooled in memory. So I would look at both the warnings and errors in the console log.

    Also, I see this is happening in the editor. I wonder if it happens when you build and run the scene? Many times, things happen in the editor that look like issues, but they don't happen in the actual build. My guess is you will still get the freeze in the build version of your game, but it's worth checking to see if it's an editor-only issue. I would build your project and see if the issue persists in the build version.

    The next thing I noticed is there are a lot of particle effects (fire/smoke) that get spawned when the destroyed prefab is instantiated. I wonder how resource-intensive those particle effects are, and how heavy the emission rate is. For example, if the particle effects are using a multi-pass shader to get volumetric fire and smoke, it could be okay for a couple of them, but it could bring the system to its knees when 6-10 of those effects are spawned in at once. To check for this, I would disable (turn off) all particle effects on your destroyed prefabs. Then if there's no hiccup when they spawn in, I would look closer at the particle effects to optimize or reduce them.

    How complex are the colliders/rigidbodies on your destroyed buildings? If they are sinking after being destroyed, then probably all you need is a few box colliders and no rigidbodies, just to keep the player from walking through them. If your destroyed prefabs have lots of colliders and rigidbodies attached to them, then it could put a heavy load on your system when all those physics objects spawn in and become active (wake up) in the scene. Reducing the number of physics objects, or reducing the solver iteration count (Edit => Project Settings => Physics => Default Solver Iterations => set to 6) could help a lot. For this one, I would remove all complex geometry (Mesh Colliders, compound Box Colliders) and active rigidbodies from your destroyed prefab. Also make sure the Default Solver Iterations is set to something low if you have a lot of physics objects in your scene.

    Lastly, if these things above didn't uncover anything, I would run the Profiler in the editor and record a Deep Profile snapshot right at the moment when the building is destroyed. You should see a large spike when the destroyed prefab is instantiated, and where the profiler is spending its time should tell you where to look for optimization opportunities. For example, if it's spending most of its time in the Physics loop, then it's probably a collider/rigidbody physics complexity issue. If it's spending its time in Rendering, then it could be too many materials on your destroyed prefab, or the materials could be using resource-heavy multipass shaders that spike your GPU when they become rendered. Or it could be a post-processing effect in your scene causing heavy render load. Significant time spent in Scripts or Garbage Collector could indicate that there's a problem with the way DestroyIt is handling the destroyed prefab spawn, and I would need to look more closely at that.

    I hope this helps you narrow down the issue. If it doesn't, you can always send us a link to your project (modelsharkstudio@gmail.com) and I can take a look at it. A second set of eyes can help sometimes. :)
     
    moltke likes this.
  16. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    you were right, there was an older particle effect that is causing the issue, the normal fire is fine but i had some ash particle effects that were causing the lag. thank you again. Thank you for all the other details i will use the suggestions in my future testing.
     
    zangad likes this.
  17. OmnifariousStudios

    OmnifariousStudios

    Joined:
    Mar 12, 2018
    Posts:
    48
    Hello again!

    A few questions:

    1. Is there a Pool Everything function? And if not, is it as easy as running PoolObject on every item in Pool?

    2. I'm asking the first question because I want to make sure that when I change scenes, destruction objects aren't staying active. Sometimes when I destroy objects and then change scenes, the destroyed objects are still active and have moved into my new scene.

    3. Any big updates coming soon we should know about??

    Thanks!
     
  18. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @OmnifariousStudios,

    Destructible objects should be automatically added to the object pool at runtime for you. On every Destructible object script, the Autopool checkbox is selected by default. So you shouldn't need to run PoolObject to get them into the pool.



    But if you're asking about after they are destroyed, how to get them back into the pool (like re-pooling them), DestroyIt doesn't actually have anything to support that. It's on our to-do list, but we have to first figure out how to convert a destroyed object back into its original un-destroyed prefab instance without deleting and re-instantiating it. And so far, we haven't figured out how to do that.

    So I would probably just run a FindAll() script that finds all objects tagged with DestroyItDebris and delete those objects when changing scenes. That should clean up any Destructible objects left in the scene. And if you reload the scene, it should re-initialize the Destructible scripts and ObjectPool, so they should be ready to be destroyed in the scene again.

    If you think a find-and-destroy script like that would help and need assistance writing it, let me know!
     
  19. suppertbw

    suppertbw

    Joined:
    Mar 16, 2016
    Posts:
    34
    I added structural support script to my prefab's parent node and press "Add Supports" button. Then I realized nothing happens, there is no joint added to the debris pieces, why?
     
  20. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @suppertbw,

    It sounds like you're trying to run the script on your prefab directly. You need to drag your prefab into the scene, attach the Structural Support script to it, and then click the "Add Supports" button. Then you can apply the changes back to your prefab by selecting Overrides => Apply All in the inspector (at the top).

    This is mentioned in the comment at the top of the StructuralSupport.cs script ("Note: if the object is a prefab, unpack it first"), but you'd only see that if you happened to look at the code. And the documentation mentions to "drag your destroyed prefab into the scene, and then add the StructuralSupport script", but it doesn't call out how important it is to do it this way. So I may need to add some text to the top of the script's editor to make it more noticeable.

    Hope that helps! Please let us know if you continue to have issues.
     
  21. suppertbw

    suppertbw

    Joined:
    Mar 16, 2016
    Posts:
    34
    Yes! It's the point I missed. Thank you for you help!!!
     
  22. suppertbw

    suppertbw

    Joined:
    Mar 16, 2016
    Posts:
    34
    I found a wired situation. I cut the model into pieces and every piece I add rigidbody and mesh collider. And then, I run the game, the model makes a explosion and each chunk flies away.
    However, the demo gives "Column Marble+Wood+Int DestDebris DEST" prefab and there is no such wired situation happing when I run the game. And each chunk of it has rigidbody and mesh collider as well. Why?
     
  23. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @suppertbw,

    My guess is that your debris pieces have concave shapes that fit together like puzzle pieces, so when you put mesh colliders on them, the colliders overlap each other. So when the game runs and the destroyed prefab is instantiated, the colliders are inside each other which causes them to fly apart violently when the physics simulation evaluates them.

    For the columns, we were careful not to have concave shapes on the inside of the model for this reason. I believe there is a setting in Blender's fracturing tool that will make it avoid concave shapes.

    Mesh Colliders:


    So you can look at your debris pieces and try to fix the concave pieces, or you can just remove the mesh colliders on those problem pieces and use compound box colliders instead. You can put multiple box colliders in place of the mesh collider and get almost the same general shape, but with way better performance.

    We actually did this for our "Column Marble+Wood+Int DEST" model, which is the model we use in the mass destruction nuke test scene. This destroyed model took a little more time to setup because of the box colliders, but performance is much better, and most people are not likely to notice that the box colliders don't always match the mesh shape exactly. It gave us fine control over how the pieces fit together, too.

    Box Colliders:


    So check out that model if you're interested in using box colliders. And you don't have to choose one or the other - you can use mostly mesh colliders and just fix a few of the problem pieces with box colliders.
     
  24. suppertbw

    suppertbw

    Joined:
    Mar 16, 2016
    Posts:
    34
    Not sure how to avoid concave shape. Our artist uses Houdini to fracture and he has no idea how to do it. Also I check blender cell fracture, it seems there is no such function. Maybe I need to modify mesh settings?

    cell fracture.png
     
  25. DeadlyAccurate

    DeadlyAccurate

    Joined:
    Apr 2, 2013
    Posts:
    186
    Zangad is out of town for the week and doesn't have access to his laptop. I'll try to help you. Depending on your model and what fracturing option you're choosing, it may not be possible to avoid concave shapes. I did a simple test in Modo with a cube, and the Uniform fracture didn't make any concave shapes with the default options, but with more complex shapes it's impossible to avoid some concavity.

    If you can't avoid concave shapes, your best option is to switch the colliders to box colliders (box colliders are also more performance friendly). As zangad mentioned, you can give everything a mesh collider and then find the few pieces that are causing trouble and switch those out.

    You can add the box colliders directly to the object, but one little trick I use is to add an empty child to the object and put the box colliders there. It's easier to manipulate them that way with the transform tools.

    I hope this helps. Let me know if you have any more questions.
     
  26. suppertbw

    suppertbw

    Joined:
    Mar 16, 2016
    Posts:
    34
    Yes, it's a solution. However, to add a box collider to each piece really depends on the numbers of pieces. Now we have to cut pieces as less as we can so that we can easily add a box collider to each piece.
     
  27. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    @zangad Im trying to make a sound occur when a destroyit object is hit, im trying to use the hit effect script. I have made an empty game object that with a audio source and an audioclip. i made this a prefab. i tried to plug this into the hit effect script, but nothing happens?

    upload_2021-12-6_18-25-42.png
    upload_2021-12-6_18-26-9.png
     
    zangad likes this.
  28. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @moltke,

    Thanks for reporting this - what you're doing should work, but the problem is a bug with the HitEffects code. I was able to update the code and fix the bug, which I'll include in future versions of DestroyIt.

    The issue was caused by the for loop in the HitEffects code - it was incorrectly exiting out on the first hit effect found, meaning that it only ever played the first one. To fix, just replace your code in HitEffects.cs with this:

    HitEffects.cs
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. namespace DestroyIt
    5. {
    6.     /// <summary>
    7.     /// This script allows you to assign particle system hit effects for each weapon type.
    8.     /// PlayEffect() will attempt to play the hit effect for the specified weapon type.
    9.     /// </summary>
    10.     [DisallowMultipleComponent]
    11.     public class HitEffects : MonoBehaviour
    12.     {
    13.         public List<HitEffect> effects;
    14.  
    15.         public void PlayEffect(HitBy weaponType, Vector3 hitPoint, Vector3 hitNormal)
    16.         {
    17.             foreach (var eff in effects)
    18.             {
    19.                 if ((eff.hitBy & weaponType) > 0)
    20.                 {
    21.                     if (eff.effect != null)
    22.                         ObjectPool.Instance.Spawn(eff.effect, hitPoint, Quaternion.LookRotation(hitNormal));
    23.                 }
    24.             }
    25.         }
    26.     }
    27. }
    Oh, and if you still don't hear the sound after applying the fix, make sure you don't have sound muted. This one got me! I fixed the code, but couldn't hear the Hit Effect sound because I somehow clicked the Mute Audio button in the Game window. Doh! o_O



    Please let me know if you still have issues after this fix.
     
  29. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109

    Haha! you fixed it! Man you can fix anything. Literally every time.
     
    EpicMcDude and zangad like this.
  30. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    Okay one more question, i think i may have something wrong like the tag or something, but I'm trying to prevent my destroyed trees/recourses from damaging each other.

    in this example the destroyed prefab of the tree is falling and damages the rock even though the destroyed tree prefab has the DontDoDamage script on the object with the rigidbody on it/

     
    zangad likes this.
  31. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @moltke,

    Thanks for the video and the good description of the issue, it helps a lot.

    I can't tell in the video, but I'm guessing your rock doesn't have a rigidbody on it. It shouldn't need one, but I think that might be what uncovered the bug. I was able to reproduce this issue by putting the DontDoDamage tag on the Cannonball weapon prefab, and firing the cannon at destructible objects in our demo scene. The destructible objects with rigidbodies were not damaged, as expected. But destructible objects that did not have rigidbodies (or static objects) took damage and were destroyed.

    So I looked at the code and applied a fix that seems to make the feature work as expected for all objects - with or without rigidbodies, whether static or non-static.

    Can you replace your ProcessDestructibleCollision() method in DestructibleExtensions.cs with this method below and see if it works for you? The method should be on or around line 100 in DestructibleExtensions.cs.

    DestructibleExtensions.cs, somewhere around line 100 (Replace your method with this):
    Code (CSharp):
    1.  
    2. public static void ProcessDestructibleCollision(this Destructible destructibleObj, Collision collision, Rigidbody collidingRigidbody)
    3. {
    4.     // Ignore collisions if collidingRigidbody is null
    5.     if (collidingRigidbody == null) return;
    6.  
    7.     // Check for DontDoDamage tag on the collidingRigidbody
    8.     if (collidingRigidbody.gameObject.HasTag(Tag.DontDoDamage)) return;
    9.  
    10.     // Ignore collisions if this object is destroyed.
    11.     if (destructibleObj.IsDestroyed) return;
    12.  
    13.     // Check that the impact is forceful enough to cause damage
    14.     if (collision.relativeVelocity.magnitude < destructibleObj.ignoreCollisionsUnder) return;
    15.  
    16.     if (collision.contacts.Length == 0) return;
    17.  
    18.     float impactDamage;
    19.     Rigidbody otherRbody = collision.contacts[0].otherCollider.gameObject.GetComponentInParent<Rigidbody>(true);
    20.  
    21.     // If we've collided with another rigidbody, use the average mass of the two objects for impact damage.
    22.     if (otherRbody != null)
    23.     {
    24.         if (otherRbody.gameObject.HasTag(Tag.DontDoDamage)) return;
    25.         float avgMass = (otherRbody.mass + collidingRigidbody.mass) / 2;
    26.         impactDamage = Vector3.Dot(collision.contacts[0].normal, collision.relativeVelocity) * avgMass;
    27.     }
    28.     else // If we've collided with a static object (terrain, static collider, etc), use this object's attached rigidbody.
    29.     {
    30.         Rigidbody rbody = destructibleObj.GetComponent<Rigidbody>();
    31.         impactDamage = Vector3.Dot(collision.contacts[0].normal, collision.relativeVelocity) * collidingRigidbody.mass;
    32.     }
    33.  
    34.     impactDamage = Mathf.Abs(impactDamage); // can't have negative damage
    35.  
    36.     if (impactDamage > 1f) // impact must do at least 1 damage to bother with.
    37.     {
    38.         //Debug.Log("Impact Damage: " + impactDamage);
    39.         //Debug.DrawRay(otherRbody.transform.position, collision.relativeVelocity, Color.yellow, 10f); // yellow: where the impact force is heading
    40.         ImpactDamage impactInfo = new ImpactDamage() { ImpactObject = otherRbody, DamageAmount = impactDamage, ImpactObjectVelocityFrom = collision.relativeVelocity * -1 };
    41.         destructibleObj.ApplyDamage(impactInfo);
    42.     }
    43. }
    Please let me know if everything seems to be functioning properly after this fix. If so, I'll include it in the next DestroyIt update.
     
    Last edited: Dec 9, 2021
  32. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    you fixed it! thanks again!
     
    zangad likes this.
  33. hm2337

    hm2337

    Joined:
    Jun 9, 2019
    Posts:
    9
    Does this have impact deformation onClick, where cursor clicks?
     
  34. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @hm2337,

    Thanks for your question. No, DestroyIt doesn't include any mesh deformation tools.
     
    hm2337 likes this.
  35. vertexx

    vertexx

    Joined:
    Mar 18, 2014
    Posts:
    379
    OK. It's now on sale albeit only for a short time. Reading the Asset Store reviews it seems as if nearly everyone has needed to reach out to the developer for help in some way?
    It would be very helpful if all of these problems, if indeed they were problems were stated and the Dev's answers given.
    At the moment it would appear that this asset is still in a development stage(?) or not really suitable for beginners?
    So ModelShark Studios, what mainly are these problems in the review sections and would they be common or just silly mistakes by the purchasers?
     
  36. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @vertexx,

    DestroyIt helps developers implement destruction in their games, which many customers want to integrate into other assets. We help customers with these asset integrations, which is why many reach out to us for assistance.

    Another reason customers contact us is for help integrating DestroyIt with their custom project. Not all assets play well together, and not everyone is comfortable making code changes to bridge the gaps. We don't consider these to be problems with DestroyIt, because everyone's project is unique and no scripting asset could ever anticipate all situations.

    Yes, DestroyIt is still in development, and has been since 2014. We're Asset Store customers, too, and we wouldn't want to purchase an asset that isn't in active development. And yes, we think DestroyIt is suitable for beginners. We include a demo scene that provides examples, starting with the simplest use case of dropping the Destructible script on an object which makes it destructible.

    Regarding our reviews for DestroyIt, they are actually better than we would have ever hoped for, and we greatly appreciate the feedback from our customers over the years. 96% of our reviews are 4- or 5-stars.
     
  37. the_unity_saga

    the_unity_saga

    Joined:
    Sep 17, 2016
    Posts:
    273
    good evening, Dev.

    what major differences are there between your asset and RayFire?

    from what Ive seen, Rayfire doesnt handle in-game product events, just destruction (complete, layered, even demolition), however yours does, and even includes progressive texture change for "object health", so I just realized owning one leaves you without substantial feature of the other??

    if I wanted to make a game about repairing stuff, would owning yours WITH rayfire be mandatory for complete demolition and repair experience, at least where unity assets are concerned?
     
  38. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @gRtVnAUoolam1492,

    I think the major difference between DestroyIt and RayFire is that RayFire is focused on mesh fracturing, and DestroyIt does not include mesh fracturing tools. DestroyIt saves you time by providing a ready-to-use highly performant destruction system. For that reason, I feel that both tools would complement each other very well.

    You could use DestroyIt to add quick particle-effect based destruction to your game, and then move on to other aspects of development. Later when you're ready to make another pass on destruction and add some polish, you could use RayFire to fracture your important set-piece objects into destructible prefabs and assign those to the DestroyIt scripts.

    DestroyIt would still handle things like too many destructible objects being destroyed at the same time (limiting the amount of debris spawned), limiting destruction to particle effects (or nothing at all) when the player cannot see it happening, cleaning up persistent debris, pooling prefabs to limit garbage collection, providing visual feedback via progressive damage textures, etc.

    I don't own RayFire yet (it's on my wishlist :)), so I can't speak for what it does and doesn't handle. I know you can use RayFire for runtime mesh fracturing, but I don't know how performant that would be. And yes, DestroyIt has progressive damage textures so you get visual feedback on an object's health, but then again, we don't provide any mesh fracturing tools, so you have to fracture your meshes yourself. This can be done in Blender for free using their Cell Fracturing tool (we made a video on it), but I would guess that RayFire makes this easier by handling it directly inside of Unity.

    I don't think owning either asset is mandatory for creating a game about repairing stuff. All assets are about saving you time and jumping you forward in your development, so you can focus on other things. DestroyIt could save you time by providing a destruction and repairing system, and RayFire could save you time by providing mesh fracturing so you don't have to learn 3D modeling tools.

    (One side-note: DestroyIt does provide repairing destructible objects, but only if they have not been destroyed. Once destroyed, the original object is gone and only a particle effect or debris remains, so repairing a destroyed object is not a feature that currently exists in DestroyIt. I like the idea, though...we might need to add that feature.)
     
    Last edited: Feb 12, 2022
    shyamarama and the_unity_saga like this.
  39. the_unity_saga

    the_unity_saga

    Joined:
    Sep 17, 2016
    Posts:
    273
    oh thanks

    I'll get your asset now.
     
  40. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    @zangad I have quite a few assets that all have their own object pooling solution which can make things cumbersome, now that Unity has a built-in internal pooling system (2021.2 & 2022.1 at the time of writing) will you eventually switch to that maybe when 2021 hits the LTS branch.
     
  41. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @ParadoxSolutions,

    Thanks for your suggestion. Yes, I think it would be a good idea for us to use Unity's built-in solution for object pooling. Especially since object pooling isn't the focus of our asset - it's just something we have to do if we're going to instantiate a lot of particle effects or destroyed objects.

    So I have added this to our to-do list for future releases (once we switch to Unity 2021, like you mentioned). Thanks again for the suggestion!
     
  42. EpicMcDude

    EpicMcDude

    Joined:
    Apr 15, 2013
    Posts:
    117
    Hello Zangad,

    I'm curious, is Destroyit capable of doing destruction like this - https://twitter.com/lucengame/status/1493816230838677504 ?
    Where an object, in this case cube, gets destroyed where it was hit but doesn't destroy the whole object. I know you have the example of the tower, but since those are poles it's probably easier to setup than an object with a lot of fractured meshes, like a wall too.
     
  43. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @EpicMcDude,

    That's neat looking destruction! No, DestroyIt doesn't provide a way to keep the original object intact and break off pieces of it where it was hit. The closest thing we have to that is the chip-away debris feature (the rebar column in the demo scene):



    But it's not really the same thing you're talking about - it's just the closest DestroyIt has to achieving that effect.

    I have seen similar destruction in Unity, but it requires prefacturing the object and putting it into the scene at runtime with kinematic rigidbodies on all the debris, so it looks like a solid object but is actually comprised of dozens of colliders, meshes, and rigidbodies. When something hits a corner of the object, it does a spherecast and removes IsKinematic on all the rigidbodies inside the spherecast and applies some random force, so debris flies and it looks like it broke the corner off. But the object at rest still takes up a large performance footprint, which is why we decided early on not to go that route.
     
    EpicMcDude likes this.
  44. Morcrist

    Morcrist

    Joined:
    May 7, 2015
    Posts:
    9
    Sorry for the belated response, but I just purchased the Asset and have been reading up on trying to solve my similar problem.

    What I ended up doing was just reducing the scale of each chunk by 75% (e.g., each chunk ended up being imported at scale (100,100,100) so I changed them to (75,75,75)).

    When I destroyed the main object and the chunky prefab was spawned, each chunk fell to the ground normally. I couldn't really notice anything out of the ordinary since it spawns so fast and the chunks are all in motion. But any larger and the chunks started launching into the air on spawn (especially at full scale lol!). Your results may vary obviously, depending on how your fractures turned out, but reducing the scale until the chunks stop flinging apart is the way to go .

    Unfortunately I couldn't find anything on the internet about how to mess around with Blender's cell fracture plugin to reduce concavity.

    I will eventually experiment with just using box colliders on each chunk, but for now this is a quick and easy fix since I can mass-select every chunk after import into Unity and change the scales all at once.
     
  45. ftejada

    ftejada

    Joined:
    Jul 1, 2015
    Posts:
    695
    Hi @zangad !! Destroyit Does it work for HDRP? Will it be in the near future?

    I want it to be used at runtime for AAA games... How is the performance with many interactable objects using Destroyit on screen?
    Works well for car destruction too?
    Do you have any notable limitations that I should know before buying?

    Regards
     
  46. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @ftejada,

    Actually, yes, DestroyIt works with HDRP out of the box, since most of what DestroyIt does is scripting/physics-based and isn't affected by the chosen render pipeline. The exception to this is progressive damage textures (visible damage like cracks that appear on damaged objects), which don't work with HDRP out of the box.

    However, we recently worked on a custom HDRP shader that you can use to get progressive damage textures in your HDRP project. We'll be including this in future versions of DestroyIt, but I'll go ahead and provide it here in case you or anyone needs it. It's done in ShaderGraph, so you can modify it to your specific needs.

    DestroyIt Custom HDRP Lit Shader:

    http://www.modelshark.com/content/misc/DestroyIt HDRP Lit Custom Shader.unitypackage

    And here's a video that shows how to use it:


    Yes, performance is good with many interactable objects on the screen, but of course it always depends on how many objects (there is always a limit you will hit) and what platform (mobile, tablet, console, desktop, VR). But high performance destruction is our main focus for DestroyIt.

    Car destruction is certainly doable, we even have a destructible SUV in our demo scene that ships with DestroyIt. However, you will need to either buy cars that have been designed with destruction in mind (something like this asset - note: I don't own the asset nor am I affiliated with it) or you will need to slice up your cars in a 3D modeling tool, which is what we did for the SUV in our demo scene.
     
    Auraion and ftejada like this.
  47. glangor

    glangor

    Joined:
    Mar 24, 2013
    Posts:
    15
    Hi there,

    Destroyit is just awesome, thanks for creating it. I'm using it to make dirt cubes crumble away and the way it make destroyed particles up looks great. Two quick questions:

    - How do I adjust how much outward velocity occurs? There's no partial destruction, I'm just setting hitpoints to 0 on the cube I want to destroy, but the debris flies out too fast and widely for my purpose.
    - With the effect prefabs called upon destruction, is there any way to affect their scale? No problem if not, I can always do that effect in code separately or adjust the prefab. Would be a handy option though, I'm using the epic toon FX which work nicely, but they can be too large/small for the situation.

    Thanks - Mark
     
  48. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi Mark,

    Thank you for the kind words, it means a lot to us!

    I would have to look at your destroyed prefab to know for sure, but my guess is that you have some overlapping mesh colliders, and that's causing it to forcefully explode apart when the destroyed prefab is created and wakes up.

    One way to test this is to put your destroyed prefab in the scene by itself and run the scene. This will rule out whether DestroyIt is somehow applying force to it, or if it's a problem with the prefab itself.

    So if you run the scene with the destroyed prefab in it, and it mostly stays put or slowly crumbles, then you've got your colliders positioned perfectly. If part of it explodes or it crumbles violently even though no force is being exerted on it and DestroyIt is not managing it, then you need to check your colliders.

    When inspecting your colliders, what you're looking for is a debris piece that has concavity, where another debris piece could fit inside of it. Check out this post for how to identify these problems and what to do about them. My preference is to replace the colliders on the trouble pieces with box colliders. And in my experience, fixing one or two of the worst offenders is usually all it takes.

    By "effect prefabs called upon destruction", are you referring to the Fallback Particle Effect or the Damage Effects? For the Fallback Particle Effect, we did add a section where you can adjust the scale of the particle effect when it spawns in. But the Damage Effects section doesn't currently allow you to scale the effects prefab:



    So if you'd like the ability to scale the Damage Effects from the Destructible script, I like that idea, and I think we can add it. I went ahead and put it on our to-do list, because I don't see any reason at this point not to do it. And if neither of these options is what you're talking about, please let me know and I'll take another look.
     
  49. Armyofonenft

    Armyofonenft

    Joined:
    Nov 15, 2021
    Posts:
    1


    hello your work is amazing, can you help me? after the MFPS 1.9 update I'm getting this error, they changed the bullet file, from the weapon folder, it's in another folder now, could it be that?
    upload_2022-3-17_20-7-42.png



    Screenshot_59.png
     
  50. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @gamershostiscg,

    It looks like the developers of MFPS removed the "Photon.Pun" using statement from their bl_Bullet.cs code, so our integration code throws and error now because it doesn't know what "Photon.Pun" is. To fix, please use this code in the bl_Bullet.cs OnHit() method, instead:

    Add this code to the OnHit() method in bl_Bullet.cs:
    Code (CSharp):
    1. DestroyIt.Destructible destObj = hit.collider.gameObject.GetComponentInParent<DestroyIt.Destructible>();
    2. if (destObj != null)
    3. {
    4.     Photon.Pun.PhotonView pv = destObj.GetComponent<Photon.Pun.PhotonView>();
    5.     pv.RPC("ApplyDamage", Photon.Pun.RpcTarget.All, bulletData.Damage);
    6. }
    Add it here:


    That piece of code above should fix the issue you're seeing and get you going again! :)

    It looks like there have been quite a few changes in both MFPS and Photon PUN, so I will follow this post up with a new set of step-by-step instructions for integrating MFPS 2.0 ver 1.9 with DestroyIt.