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
    Hi everyone,

    We just updated DestroyIt to version 1.11. It's mostly a performance update, but also brings the asset current to Unity 2019.3.7f1, and addresses a few fixes we had on our backlog.

    Here's the full changelog:
    v1.11 (Apr 2020)
    • Updated for Unity 2019.3.7f1 compatibility
    • Improved memory performance for progressive damage and destroyed prefab material transfers by modifying MaterialPropertyBlocks instead of directly changing materials at runtime
    • Removed the MaterialPreloader script entirely, as it is no longer needed to boost performance by creating hundreds of material variations at runtime
    • Removed the need to put progressive damage materials in the Resources\Material_Preload folder. You can put them anywhere now, and they will work fine
    • You can now make objects destructible even when they have no colliders or rigidbodies (see Scenario #29 in the Main Demo Scene). You can still apply damage to these objects through the normal ApplyDamage() method. Useful for things like scripted or far-off damage effects that the player cannot interact with
    • Fixed "missing GUI Layer" warning on Main Camera component in QuickStart scene (Unity 2019-related)
    • Fixed an issue with detail masks and texture maps being incorrectly used by the Material Preloader for progressive damage textures (Unity 2019-related)
    • Fixed "Check Winding" error caused by one of the SUV meshes
    • Added option to backup terrain in TreeManager because of "The specified path is not of a legal form (empty)" bug in Unity (Unity 2019-related)
    • Repackaged DestroyIt-Ready as a separate package bundle to prevent build-time errors
    • Fixed "Couldn't create a Convex Mesh from source mesh 'rock_low' within the maxinum polygons limit (256)" error (Unity 2019-related)
    Notes:
    • If you are applying this update to an existing project, you may get a "missing script" warning for the MaterialPreloader component. You can safely remove this component, as it is no longer needed
    • While we were able to improve memory performance for progressive damage and destroy prefab material transfer operations, we were not able to improve material transfers to mesh particle effects. Destructible objects that spawn particle effects that have materials transferred over to them will still create one material per renderer, per effect. This is due to a bug in Unity that causes MaterialPropertyBlock changes to not take affect on ParticleSystemRenderers that are set to RenderMode:Mesh. If you want to keep your material usage super-clean, manually assign your fallback particle effects rather than relying on the defaults (example: Scenario #4 - The Exploding Barrel in the Main Demo Scene).

    Known Issues:

    • When importing the DestroyIt asset package, you may get an error message "A tree couldn't be loaded because the prefab is missing", even though there are no missing tree prefabs on the terrain in question. In this case, it is not a real error and can be ignored. Best we can tell, this is happening because we use a customized version of the SpeedTree shader for destructible trees, because it thinks the prefab doesn't have any valid mesh renderers when it actually does. It works fine, though, both in the editor and building the scene.
    • If you turn on the Backup Terrain feature on the TreeManager script and you have the solution open in Visual Studio, you may get an error message "The specified path is not of a legal form (empty)" thrown from the TreeManager script. This error is not a real error and can be ignored.

    One thing we would like to provide more details on is this change:
    Basically, before this update DestroyIt relied on the Material Preloader script to inspect all of your progressive damage materials in the Resources folder, and create new materials for each variation (based on the number of detail masks). So for example, if you had 20 progressive damage materials, and they all used a detail mask with 10 different variations, it would create 200 materials and have them ready to go when the scene is built. Performance-wise, this was not bad, but memory-wise, it was not ideal.

    With this update, it now simply changes the progressive damage detail masks at runtime using Material Property Blocks. This method is not only better for memory management, but it also performs better, since swappping materials at runtime is more costly. It also avoids another downside of material swapping, which is the need to clean up the old materials that got swapped out. Over time, and with a large project, these leftover materials could add up to a significant memory leak.

    To illustrate the impact of the change, take a look at the number of materials created in our Main Scenarios Demo Scene when the scene is first loaded, and then after everything in the scene is destroyed:





    As you can see, fewer materials were created when the scene starts, and fewer materials were leaked when objects were destroyed.

    And here's a before/after comparison of performance. It wasn't a huge difference in our relatively small demo scene, but could be quite noticeable in larger, more complex scenes with hundreds of destructible objects. This stress-test comparison shows frames per second right at the moment the nuke destroys everything in the scene:



    And lastly, another bonus of this change is we were able to completely remove the Material Preloader script and the Resources\Material_Preload folder, which simplifies your setup. You can now put progressive damage materials anywhere, and they will work fine. One less thing to troubleshoot! :)
     
    Last edited: Apr 12, 2020
    julianr likes this.
  2. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    @zangad
    I added Destroyit script to the overall parent (A Keep) so that any damage done to a gate would also add into the parent's damage, so that as each tower and gate is destroyed it simultaneously adds into the parent's overall damage so that if enough damage is done to the individual children (gates and towers) that it would destroy the parent keep

    but instead it is only taking into account damage done to the parent and ignores the damage to the scripts on the children.

    Any suggestions on a way around this? I made a video to better explain.

     
    Last edited: Apr 12, 2020
    zangad likes this.
  3. zangad

    zangad

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

    Thank you for posting your question and providing the video describing what you're trying to accomplish - it was very helpful.

    The easiest way I can think of to do this is to hook onto the Damaged() event, so when one of your child objects (such as the towers or gates) is damaged, it will find the destructible parents of that object and apply the same damage to them as well.

    Please try the following:
    1) Create a new script file called WhenDamagedDamageParents.cs
    2) Replace the code inside it with this:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace DestroyIt
    4. {
    5.     /// <summary>
    6.     /// Put this script on a GameObject that has the Destructible script.
    7.     /// When this object is damaged, it will also apply that damage to all of its parent Destructible objects.
    8.     /// </summary>
    9.     [RequireComponent(typeof(Destructible))]
    10.     public class WhenDamagedDamageParents : MonoBehaviour
    11.     {
    12.         private Destructible _destObj;
    13.  
    14.         private void Start()
    15.         {
    16.             // Try to get the Destructible script on the object. If found, attach the OnDamaged event listener to the DamagedEvent.
    17.             _destObj = gameObject.GetComponent<Destructible>();
    18.             if (_destObj != null)
    19.                 _destObj.DamagedEvent += OnDamaged;
    20.         }
    21.  
    22.         private void OnDisable()
    23.         {
    24.             // Unregister the event listener when disabled/destroyed. Very important to prevent memory leaks due to orphaned event listeners!
    25.             if (_destObj == null) return;
    26.             _destObj.DamagedEvent -= OnDamaged;
    27.         }
    28.  
    29.         /// <summary>When the Destructible object is repaired, the code in this method will run.</summary>
    30.         private void OnDamaged()
    31.         {
    32.             // Get a reference to all the Destructible parents of this object
    33.             Destructible[] destructibleParents = gameObject.GetComponentsInParent<Destructible>();
    34.  
    35.             // Loop through the destructible parent objects and apply damage
    36.             for (int i = 0; i < destructibleParents.Length; i++)
    37.             {
    38.                 if (destructibleParents[i] == _destObj) continue; // Ignore the current destructible object
    39.                 destructibleParents[i].ApplyDamage(_destObj.LastDamagedAmount); // Apply the damage to only parent objects
    40.             }
    41.         }
    42.     }
    43. }
    3) Put this script on each child object you want this effect on.

    I made a quick video of the process:

    I hope that helps! Please let us know if you have more questions.

    (Side note: If you're only wanting to apply damage to the parent castle when a child is destroyed, then you can use the same script, but hook onto the OnDestroyed() event instead. See the WhenDestroyed.cs script in DestroyIt for an example.)
     
    Last edited: Apr 12, 2020
    Fibonaccov likes this.
  4. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    Wow... I cannot believe you took the time to do this for me. It worked perfectly! thank you so much!
     
    zangad likes this.
  5. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    Hey Zangdad, If I update will it mess up the custom progressive damage materials i made by duplicating yours and placing the materials of the prefabs im using?
     
  6. zangad

    zangad

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

    Short answer is, I'm not entirely sure if an update would overwrite your custom progressive damage materials.

    Long answer, is, I think it would be okay, because we didn't actually change the materials, we just moved them to another folder. It all depends on the AssetIds, if they match, and which one is considered newer. If you made a copy of our materials before customizing them for your game, you should be fine, because the copies should have new AssetIds and not be overwritten on import. However, if you just modified our original materials, then the AssetIds will be the same, and there is a chance your materials would be overwritten. I still think your modified materials would be considered "newer" by Unity and it wouldn't overwrite them, but I wouldn't risk it.

    What I would suggest is, make a backup copy of your project first. Either zip up the entire project directory, or select everything you want to export in the Unity editor's Project window and Export as a package, including all dependencies. Then, once you have a backup stored safely somewhere, update to the new DestroyIt version and check your materials. If they got overwritten, fetch your customized materials from your backup, or just delete the updated project and revert to your backup.
     
    moltke likes this.
  7. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    Alright thank you again! You are always very kind.
     
    Last edited: Apr 15, 2020
    DeadlyAccurate likes this.
  8. MaxKMadiath

    MaxKMadiath

    Joined:
    Dec 10, 2016
    Posts:
    69
    After copy-paste the above script i am getting the following error.
    upload_2020-4-21_21-39-37.png
     
  9. zangad

    zangad

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

    Thanks for posting. It looks like Opsive changed the OnObjectImpact event method signature in UFPS.

    Below are updated instructions on how to make objects destructible using DestroyIt and Ultimate Character Controller/UFPS. (Note: Everything is the same except the DamageOnImpact code - I'm just posting the complete step-by-step for anyone else who needs it. Also Note: This version of DamageOnImpact.cs also handles explosive damage like grenades.)

    Steps:
    1) Create a new project
    2) Import Ultimate Character Controller and DestroyIt asset packages
    3) Open the \Opsive\UltimateCharacterController\Demo\UFPSDemo scene
    4) Create a new C# script called DamageOnImpact.cs and replace the code inside it with the code provided below
    5) Select the white crate at the end of the hallway and add the Destructible script to it
    6) Also add the DamageOnImpact script to the white crate
    7) From the Unity top menu, choose Window -> DestroyIt -> Setup - Minimal
    8) Run the demo scene, pick up the assault rifle, and shoot the crate

    DamageOnImpact.cs
    Code (CSharp):
    1.  
    2. using DestroyIt;
    3. using Opsive.Shared.Events;
    4. using Opsive.UltimateCharacterController.Items.Actions;
    5. using Opsive.UltimateCharacterController.Objects;
    6. using UnityEngine;
    7. using Destructible = DestroyIt.Destructible;
    8.  
    9. public class DamageOnImpact : MonoBehaviour
    10. {
    11.     public void Awake()
    12.     {
    13.         EventHandler.RegisterEvent<float, Vector3, Vector3, GameObject, object, Collider>(gameObject, "OnObjectImpact", OnImpact);
    14.     }
    15.  
    16.     private void OnImpact(float amount, Vector3 position, Vector3 direction, GameObject attacker, object weapon, Collider hitCollider)
    17.     {
    18.         Destructible destructible = hitCollider.GetComponentInParent<Destructible>();
    19.         if (destructible == null) return;
    20.  
    21.         switch (weapon)
    22.         {
    23.             case Explosion explosion:
    24.             {
    25.                 ExplosiveDamage explosiveDamage = new ExplosiveDamage {
    26.                     BlastForce = explosion.ImpactForce,
    27.                     DamageAmount = explosion.DamageAmount,
    28.                     Position = explosion.transform.position,
    29.                     Radius = explosion.Radius,
    30.                     UpwardModifier = 1.5f
    31.                 };
    32.                 destructible.ApplyDamage(explosiveDamage);
    33.                 Debug.Log(name + " hit by " + attacker.name + " using explosive for " + amount + " damage in a " + explosion.Radius + "m range.");
    34.                 break;
    35.             }
    36.             case ShootableWeapon shootableWeapon:
    37.                 destructible.ApplyDamage(amount);
    38.                 Debug.Log(name + " hit by " + attacker.name + " using " + shootableWeapon.name + " for " + amount + " damage.");
    39.                 break;
    40.             case Projectile projectile:
    41.                 destructible.ApplyDamage(amount);
    42.                 Debug.Log(name + " hit by " + attacker.name + " using " + projectile.name.Replace("(Clone)", "") + " for " + amount + " damage.");
    43.                 break;
    44.         }
    45.     }
    46.  
    47.     public void OnDestroy()
    48.     {
    49.         EventHandler.UnregisterEvent<float, Vector3, Vector3, GameObject, object, Collider>(gameObject, "OnObjectImpact", OnImpact);
    50.     }
    51. }
    Results:


     
    Last edited: May 9, 2020
  10. Max_VRAB

    Max_VRAB

    Joined:
    Mar 13, 2014
    Posts:
    5
    Hi!
    I just bought DestroyIt from the Asset store and wanted to integrate it to my project, which is using MFPS. However I am receiving an error message when doing so. One of it is that when I am shooting at the Column I get "PhotonView with ID 7 has no (non-static) method "ApplyDamage" that takes 0 argument(s); Can you help me with this?
     
  11. MaxKMadiath

    MaxKMadiath

    Joined:
    Dec 10, 2016
    Posts:
    69
    Thanks it now working :)
     
  12. Max_VRAB

    Max_VRAB

    Joined:
    Mar 13, 2014
    Posts:
    5
    I just want to say that I followed the Tutorial guide that was in Lovatto's website. If you can please check as I am searching for a solution all day and still nothing :/
     
  13. zangad

    zangad

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

    It looks like the MFPS code has changed since we provided the tutorial. Please try adding this code instead for the MFPS bl_Bullet.cs script:

    MFPS\Scripts\Weapon\Projectiles\bl_Bullet.cs


    The only difference is the way bullet damage is referenced. Instead of a float variable called "damage", they now use a "bulletData" variable with a "Damage" property.
     
  14. paulojsam

    paulojsam

    Joined:
    Jul 2, 2012
    Posts:
    575
    is destroy it compability ready with
    Modular Multiplayer FPS Engine (Photon 2) (MMFPSE)?
     
  15. Max_VRAB

    Max_VRAB

    Joined:
    Mar 13, 2014
    Posts:
    5
    THANK YOU SO MUCH!!!
     
  16. zangad

    zangad

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

    Yes, DestroyIt works with Modular Multiplayer FPS Engine (Photon 2) (MMFPSE). Below are step-by-step instructions on how to modify the bullet script in MMFPSE to do damage to DestroyIt objects.

    How to Integrate DestroyIt with MMFPSE Photon 2
    1. Create a new Unity project
    2. Import Modular Multiplayer FPS Engine (Photon 2) (MMFPSE)
    3. Open the \314 Arts\MarsFPSKit\Scenes\MainMenu scene
    4. Import Photon PUN 2 (Free)
    5. Login to Photon Cloud, setup a new Photon PUN project, and copy the AppId into the PUN Wizard


    6. Import DestroyIt
    7. From the Unity top menu, choose Window => DestroyIt => Setup - Minimal


    8. Select a game object in the scene Hierarchy that you want to be destructible (for example, the orange Cyliders). In the Inspector for this game object:
      * Add Component => Destructible
      * Add Component => Photon View
      * Drag your game object to the Observed Components field under Photon View (see image below)
      * Check the Synchronize Position and Rotation checkboxes on the Photon Transform View component


    9. Open the \DestroyIt\Scripts\Behaviors\Destructible.cs script and add the [Photon.Pun.PunRPC] attribute to the ApplyDamage method
      Destructible.cs


    10. Open the \314 Arts\MarsFPSKit\Scripts\Player\Weapons\Kit_ModernBullet.cs script and add the section of code below to the first OnHit() method
      Code (CSharp):
      1. DestroyIt.Destructible destObj = hit.collider.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, settings.damage);
      6. }
      Kit_ModernBullet.cs


    11. Run the scene, host a new game, join the game by selecting a team, and go shoot the game object you added the Destructible script to. It should take damage and be destroyed.
     
    Last edited: Apr 25, 2020
  17. paulojsam

    paulojsam

    Joined:
    Jul 2, 2012
    Posts:
    575
    ooh wonderfull thank you very much!!!
     
  18. MaxKMadiath

    MaxKMadiath

    Joined:
    Dec 10, 2016
    Posts:
    69
    [/QUOTE]
    When i try to destruct object using grenade i am getting following errror. Any idea why. upload_2020-4-24_19-2-58.png
     
  19. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hey @MaxKMadiath,

    Here's an updated version of the DamageOnImpact.cs script that also handles explosives (like grenades) when integrating UFPS/Opsive UCC with DestroyIt. Please replace your DamageOnImpact.cs code with this:

    DamageOnImpact.cs
    Code (CSharp):
    1. using DestroyIt;
    2. using Opsive.Shared.Events;
    3. using Opsive.UltimateCharacterController.Items.Actions;
    4. using Opsive.UltimateCharacterController.Objects;
    5. using UnityEngine;
    6. using Destructible = DestroyIt.Destructible;
    7.  
    8. public class DamageOnImpact : MonoBehaviour
    9. {
    10.     public void Awake()
    11.     {
    12.         EventHandler.RegisterEvent<float, Vector3, Vector3, GameObject, object, Collider>(gameObject, "OnObjectImpact", OnImpact);
    13.     }
    14.  
    15.     private void OnImpact(float amount, Vector3 position, Vector3 direction, GameObject attacker, object weapon, Collider hitCollider)
    16.     {
    17.         Destructible destructible = hitCollider.GetComponentInParent<Destructible>();
    18.         if (destructible == null) return;
    19.  
    20.         switch (weapon)
    21.         {
    22.             case Explosion explosion:
    23.             {
    24.                 ExplosiveDamage explosiveDamage = new ExplosiveDamage {
    25.                     BlastForce = explosion.ImpactForce,
    26.                     DamageAmount = explosion.DamageAmount,
    27.                     Position = explosion.transform.position,
    28.                     Radius = explosion.Radius,
    29.                     UpwardModifier = 1.5f
    30.                 };
    31.                 destructible.ApplyDamage(explosiveDamage);
    32.                 Debug.Log(name + " hit by " + attacker.name + " using explosive for " + amount + " damage in a " + explosion.Radius + "m range.");
    33.                 break;
    34.             }
    35.             case ShootableWeapon shootableWeapon:
    36.                 destructible.ApplyDamage(amount);
    37.                 Debug.Log(name + " hit by " + attacker.name + " using " + shootableWeapon.name + " for " + amount + " damage.");
    38.                 break;
    39.             case Projectile projectile:
    40.                 destructible.ApplyDamage(amount);
    41.                 Debug.Log(name + " hit by " + attacker.name + " using " + projectile.name.Replace("(Clone)", "") + " for " + amount + " damage.");
    42.                 break;
    43.         }
    44.     }
    45.  
    46.     public void OnDestroy()
    47.     {
    48.         EventHandler.UnregisterEvent<float, Vector3, Vector3, GameObject, object, Collider>(gameObject, "OnObjectImpact", OnImpact);
    49.     }
    50. }
    51.  
    And here's a screenshot of the results. I stacked 3 crates, put both the Destructible and DamageOnImpact scripts on them, and threw a grenade at it.
     
    Last edited: May 9, 2020
  20. MaxKMadiath

    MaxKMadiath

    Joined:
    Dec 10, 2016
    Posts:
    69
    @zangad Thanks for your quick support it works fine.
     
  21. BunnyViking

    BunnyViking

    Joined:
    Nov 28, 2019
    Posts:
    17
    Has anyone tried this asset with vegetation studio, i.e. spawning prefabs with veggy studio after setting them up for destruction and having them behave properly (get destroyed / not respawn)
     
  22. donkey0t

    donkey0t

    Joined:
    Oct 23, 2016
    Posts:
    71
    Hi, is there any plans to support HDRP with the Destroy It terrain tree shader or is there a workaround to get them working with HDRP?
     
  23. gearedgeek

    gearedgeek

    Joined:
    Jun 19, 2015
    Posts:
    236

    The latest version of Opsive (Version 2.2) has broken this integration. The EventHandler has been changed which broke it. Is it possible to get this fixed?
     
  24. gearedgeek

    gearedgeek

    Joined:
    Jun 19, 2015
    Posts:
    236
    I believe I have got it fixed but it may need to be cleaned up.

    Code (CSharp):
    1. using DestroyIt;
    2. using UnityEngine;
    3. using Opsive.Shared.Events;
    4.  
    5. public class DamageOnImpact : MonoBehaviour
    6. {
    7.     public void Awake()
    8.     {
    9.         //EventHandler.RegisterEvent<float, Vector3, Vector3, GameObject, Collider>(gameObject, "OnObjectImpact", OnImpact);
    10.         EventHandler.RegisterEvent<float, Vector3, Vector3, GameObject, object, Collider>(gameObject, "OnObjectImpact", OnObjectImpact);
    11.     }
    12.  
    13.     //private void OnImpact(float amount, Vector3 position, Vector3 direction, GameObject attacker, Collider hitCollider)
    14.     private void OnObjectImpact(float amount, Vector3 position, Vector3 forceDirection, GameObject attacker, object attackerObject, Collider hitCollider)
    15.     {
    16.         Destructible destructible = hitCollider.GetComponentInParent<Destructible>();
    17.         if (destructible != null)
    18.             destructible.ApplyDamage(amount);
    19.  
    20.         Debug.Log(name + " hit by " + attacker.name + " for " + amount + " damage.");
    21.     }
    22.  
    23.     public void OnDestroy()
    24.     {
    25.         //EventHandler.UnregisterEvent<float, Vector3, Vector3, GameObject, Collider>(gameObject, "OnObjectImpact", OnImpact);
    26.         EventHandler.UnregisterEvent<float, Vector3, Vector3, GameObject, object, Collider>(gameObject, "OnObjectImpact", OnObjectImpact);
    27.     }
    28. }
     
  25. SpaceRay

    SpaceRay

    Joined:
    Feb 26, 2014
    Posts:
    455
    Hello, I have bought this asset but I am sorry that I forgot how to use it with mobile touch.

    Please, I want to have simple plain cubes and spheres on the floor and that you can destroy them just by touching them. How would I do it ?
    I have Easy Touch asset and other mobile touch controller if needed.

    Congratulations for keeping updating it and making it even better each time and surely is the best way available to destruct things with sounds attached and realistic physics, and also for all the support you give here on the forum

    Thanks very much and wish you all the best and that this asset keeps growing and be even more popular each time and more people use it and it keeps being profitable
     
    Last edited: Apr 30, 2020
    zangad likes this.
  26. MaxKMadiath

    MaxKMadiath

    Joined:
    Dec 10, 2016
    Posts:
    69
    @zangad It will not work if i use projectile instead of raycast :)
     
  27. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    @zangad

    I was having issues with the destructible script, i downloaded an asset called medieval village. I started upgrading all my asset buildings with their prefabs. All my buildings in the scene are always a child of the primary building (which holds the scripts and contains the entire information of the building)

    previously I had your script on the parent so that I could delete everything when the building is destroyed.

    I noticed that when I changed over to using this new asset under the child which contained the building pieces that the fire that would appear at certain % of damage stopped appearing. But I found out if i removed the script from the overall parent and moved it to the child building then the fires would appear on the building. However this causes me a problem as I can delete the building, but all the information for that building stays in the scene, such as the healthbar etc.

    I attempted to get around this by using your script that does damage to the parent if the child is damaged, but this didn't seem to solve my issue.

    Here is a video explaining my problem.



    I sent you an email with the scene, hopefully there aren't any errors as i cut some things out so it wouldnt be a huge file
     
    Last edited: May 3, 2020
  28. zangad

    zangad

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

    Thanks for the video and sending me your project. I was able to reproduce the issue and troubleshoot it. I found a couple of issues and provided workarounds. I will clean the workarounds up and implement the fixes in our future versions of DestroyIt. Please let me know if you have further issues.
     
  29. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hi @SpaceRay, thank you for the kind words.

    I don't have the Easy Touch asset, but I did notice on its Asset Store page that it supports PlayMaker actions. So I'm thinking the easiest way to do what you want, would be to use Easy Touch with PlayMaker to capture the user's touch input on the game object, then use our DestroyIt PlayMaker action ("DamageObject", below) to do damage to it. You can configure (or pass in to the action) how much damage you want to do on each touch.

    Here's an updated version of our DamageObject PlayMaker action. You can use this action to do damage to any DestroyIt destructible object. Just drop this script in your \Assets\PlayMaker\Actions\GameObject folder, and you'll be able to select it as an Action in PlayMaker:

    DamageObject.cs

    Code (CSharp):
    1. using DestroyIt;
    2.  
    3. namespace HutongGames.PlayMaker.Actions
    4. {
    5.     [ActionCategory(ActionCategory.GameObject)]
    6.     [Tooltip("Causes damage to a Destructible object.")]
    7.     public class DamageObject : FsmStateAction
    8.     {
    9.         [Tooltip("The amount of damage to cause.")]
    10.         public FsmInt damage;
    11.  
    12.         public override void Reset()
    13.         {
    14.             damage = 0;
    15.         }
    16.  
    17.         public override void OnEnter()
    18.         {
    19.             // Find the first available Destructible object.
    20.             Destructible dest = Fsm.GameObject.GetComponentInChildren<Destructible>();
    21.             if (dest == null) return;
    22.  
    23.             dest.ApplyDamage(damage.Value);
    24.             Finish();
    25.         }
    26.     }
    27. }
    And here's a screenshot of a simple PlayMaker FSM state transition using the DamageObject action. In my ObjectTouched state, I'm just listening for the Tab key up, but in your case, you would use Easy Touch to listen for the user touch state on a game object.



    I hope that helps!
     
    gearedgeek likes this.
  30. zangad

    zangad

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

    We recently updated our instructions for integrating Opsive's UFPS/Ultimate Character Controller with DestroyIt. Please check this post (above) and let us know if you're still having an issue after trying those steps.

    Edit: Just saw your post where you figured it out. Yes, that looks good to me. You may still want to check out the script I posted above if you also want grenade damage, too.
     
  31. zangad

    zangad

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

    The terrain tree shader we provide with DestroyIt is just a minor modification of the regular SpeedTree shader. The only thing we added was a small piece of code to expose the tint variety color, so the destroyed prefabs could be spawned in with the same tint as what the destroyed tree had when it was part of the terrain. If you're wondering if our modified SpeedTree shader will work with HDRP, I'm not sure. I've seen instructions for converting existing SpeedTree shaders to HDRP, but that process didn't work for me, I got pink textures for everything. (If anyone has had luck converting existing SpeedTree shaders to HDRP, I'd be interested to try your process and test out converting our DestroyIt version of the SpeedTree shader.)

    If you're wondering in general if DestroyIt will work with trees that use HDRP materials, then yes, that works. I downloaded the Fontainebleau HDRP demo and converted some of the birch trees in it to destructible trees, and it worked fine. The trees in that demo are not terrain trees, but I didn't see anything that would prevent it from working with terrain trees. The shaders don't really matter, unless you're using a specific feature of the shader (such as variety tinting, in the case of SpeedTree) that must be transferred from the terrain tree instance to the destroyed prefab game object.

    Here's a video of a few trees being destroyed in the Fontainebleau HDRP demo. The explosion effect that destroys the trees isn't visible because I don't have any good HDRP Visual Effects to use at the moment, but that's not relevant to your question.


    Hope that helps!
     
    Last edited: May 9, 2020
  32. unity_DarkAngel

    unity_DarkAngel

    Joined:
    Sep 21, 2018
    Posts:
    8
    hi, I am adding DamageOnImpact script to all object of SUV but just TIREs destroying, what can I do to receive damage to all part of SUV with OPSIVE third-person Shooter?
    Thanks
     
  33. zangad

    zangad

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

    Here's an updated version of the DamageOnImpact.cs script that also handles projectiles (like arrows) when integrating UFPS/Opsive UCC with DestroyIt. Please replace your DamageOnImpact.cs code with the updated code below.

    DamageOnImpact.cs
    Code (CSharp):
    1. using DestroyIt;
    2. using Opsive.Shared.Events;
    3. using Opsive.UltimateCharacterController.Items.Actions;
    4. using Opsive.UltimateCharacterController.Objects;
    5. using UnityEngine;
    6. using Destructible = DestroyIt.Destructible;
    7.  
    8. public class DamageOnImpact : MonoBehaviour
    9. {
    10.     public void Awake()
    11.     {
    12.         EventHandler.RegisterEvent<float, Vector3, Vector3, GameObject, object, Collider>(gameObject, "OnObjectImpact", OnImpact);
    13.     }
    14.  
    15.     private void OnImpact(float amount, Vector3 position, Vector3 direction, GameObject attacker, object weapon, Collider hitCollider)
    16.     {
    17.         Destructible destructible = hitCollider.GetComponentInParent<Destructible>();
    18.         if (destructible == null) return;
    19.  
    20.         switch (weapon)
    21.         {
    22.             case Explosion explosion:
    23.             {
    24.                 ExplosiveDamage explosiveDamage = new ExplosiveDamage {
    25.                     BlastForce = explosion.ImpactForce,
    26.                     DamageAmount = explosion.DamageAmount,
    27.                     Position = explosion.transform.position,
    28.                     Radius = explosion.Radius,
    29.                     UpwardModifier = 1.5f
    30.                 };
    31.                 destructible.ApplyDamage(explosiveDamage);
    32.                 Debug.Log(name + " hit by " + attacker.name + " using explosive for " + amount + " damage in a " + explosion.Radius + "m range.");
    33.                 break;
    34.             }
    35.             case ShootableWeapon shootableWeapon:
    36.                 destructible.ApplyDamage(amount);
    37.                 Debug.Log(name + " hit by " + attacker.name + " using " + shootableWeapon.name + " for " + amount + " damage.");
    38.                 break;
    39.             case Projectile projectile:
    40.                 destructible.ApplyDamage(amount);
    41.                 Debug.Log(name + " hit by " + attacker.name + " using " + projectile.name.Replace("(Clone)", "") + " for " + amount + " damage.");
    42.                 break;
    43.         }
    44.     }
    45.  
    46.     public void OnDestroy()
    47.     {
    48.         EventHandler.UnregisterEvent<float, Vector3, Vector3, GameObject, object, Collider>(gameObject, "OnObjectImpact", OnImpact);
    49.     }
    50. }
    51.  
    And here's a screenshot of the results. I put both the Destructible and DamageOnImpact scripts on the archery target, and fired arrows at it.

     
  34. zangad

    zangad

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

    What Opsive weapon are you using to do damage to the SUV?
     
  35. unity_DarkAngel

    unity_DarkAngel

    Joined:
    Sep 21, 2018
    Posts:
    8
    I tested with all of that , they work on all of the objects except SUV Glass and SUV body.
    is it possible to create damage shader for URP in shader Graph?
     
  36. unity_DarkAngel

    unity_DarkAngel

    Joined:
    Sep 21, 2018
    Posts:
    8
    AssaultRifle not working on glass (raycast) but bow working!
     
  37. unity_DarkAngel

    unity_DarkAngel

    Joined:
    Sep 21, 2018
    Posts:
    8
  38. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    @zangad I just want to thank you so much for working through my project and fixing my issues. Everything has been going so smoothly now thank you very much.
     
    zangad likes this.
  39. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    Hey @unity_DarkAngel,

    Try putting the DamageOnImpact script on the SUV's Body object, as well as on all the colliders of the model. The reason for doing this is because of the way the hitscan and explosive weapons work in Opsive's UFPS/UCC.

    The SUV uses compound colliders with one rigidbody on the Body parent object. The hitscan guns in UFPS return the Body object even though a window collider was hit. So putting the DamageOnImpact script on the Body and colliders makes sure the OnImpact event gets fired on the right object, no matter what.

    Video:


    Hope that helps!
     
    Last edited: May 9, 2020
  40. unity_DarkAngel

    unity_DarkAngel

    Joined:
    Sep 21, 2018
    Posts:
    8
    Thanks, it's working. Is it Possible to add a URP Damage shader to the project ?
     
  41. zangad

    zangad

    Joined:
    Nov 17, 2012
    Posts:
    357
    @unity_DarkAngel,

    Yes, we are planning to add visible damage (i.e., cracks/dents/scratches) support for URP and HDRP in the form of custom shaders. It's on our backlog, and I've been working on it, but I don't consider what I've created quite ready yet.

    However, you're welcome to have my work-in-progress URP PBR shader here:
    http://www.modelshark.com/content/misc/DestroyIt-URP-PBR-Shader.unitypackage

    Two things about the shader I'm not happy with yet: (1) I don't like that it has fewer surface inputs and features than the simple lit URP shader. But I'm not sure at this point how to get an exact 1:1 copy of the Simple Lit URP shader and extend it to add the Detail Mask and Secondary Maps. (2) I feel like my graph uses too many operations to extract the cracks/dents texture from the neutral gray backgrounds and apply them to the surface albedo and normal map textures.

    In case you didn't know, DestroyIt will automatically show visible damage effects on any shader that exposes three properties: _DetailMask, _DetailAlbedoMap, and _DetailNormalMap. The standard shader already exposes those properties, but the URP shaders don't. So you can create a new shader based off the URP PBR graph shader, and use Shader Graph to add those properties and wire them up.

    Speaking of wiring it up, here's how the custom DestroyIt URP PBR shader (above) is wired up in Shader Graph (keep in mind, I'm no shader expert...):


    And here's how it looks in the Unity UI when you assign textures (it's kind of ugly, and doesn't have many inputs/features):


    And here's the results - the paint bucket in the URP demo scene has the visible cracks after shooting it a few times with the gun. (It still looks "off" to me - a little too shiny/flat):


    Anyway, I hope that helps. Whenever we're happy with the custom shader, we'll include it with future versions of DestroyIt, but for now it doesn't feel "ready". But feel free to use it as a starting point to create your own custom URP shader with visible damage effects. :)
     
    Last edited: May 12, 2020
  42. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    I was just curious if your asset was able to produce a hit marker when cutting down a tree, like as you hit the trunk of a tree is there way to apply a translucent effect or scratch of some sort?
     
  43. zangad

    zangad

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

    Thanks for the question, I think what you're looking for is decals.

    We have it on our backlog to look at adding decals to DestroyIt, so when you shoot an object with the gun, it would leave a bullet hole decal, when you chop something with the axe, it would leave a deep gouge mark, and the cannonball would leave a circular black decal with cracks going outward.

    However, there's a lot to consider when creating a decal system - decals need to wrap around objects when the hit is very close to the edge, otherwise you get a decal that sticks out past the object. Performance is also a concern, as each decal projector adds rendering overhead. We would also need to support both URP/HDRP decals, too. So we haven't implemented this feature yet, because it would be a larger effort to get it right.

    So no, DestroyIt doesn't have decals at this time. However, there are several dedicated decal assets on the Asset Store you might want to take a look at.
     
  44. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    @zangad

    Thank you for the explanation it helped me better understand what I am doing. I appreciate your response.
     
  45. YesWayJose

    YesWayJose

    Joined:
    Jan 16, 2020
    Posts:
    1
    @zangad

    Im currently having trouble with the destroyed prefab version of my characters head spawning where it is not supposed to. I have attached a video of the issue. The destroyed prefab breaks as intended, the only issue is the location where it shows up.
     
  46. DeadlyAccurate

    DeadlyAccurate

    Joined:
    Apr 2, 2013
    Posts:
    186
    Bring both the undestroyed and destroyed prefabs into the scene and copy the transforms from the undestroyed prefab to the destroyed prefab and see if they line up. Most likely, you just need to zero out the transforms on the head either in your 3D modeling tool or by parenting the mesh under an empty child game object.

    You can send us link to a clean copy of your project if you're having trouble getting it to work.
     
  47. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    do you know why i am unable to make a build with the first person controller?
     
  48. DeadlyAccurate

    DeadlyAccurate

    Joined:
    Apr 2, 2013
    Posts:
    186
    I'm not sure what you mean. Can you clarify? Are you trying to build the project and it's failing? Is the console throwing an error message? Are the DestroyIt-Ready scripts in the package when you're trying to build? (Those need to be deleted first).
     
  49. moltke

    moltke

    Joined:
    Apr 28, 2019
    Posts:
    109
    yes i put the first person controller in the scene, but when i delete the ones that say its safe to be deleted the scripts are gone from the first person controller in the scene
     
  50. DeadlyAccurate

    DeadlyAccurate

    Joined:
    Apr 2, 2013
    Posts:
    186
    The first person controller is in the Safe to Delete folder, so if you delete anything in that folder that you're using in your build, it'll throw errors. Reimport the Safe To Delete folder from the DestroyIt package and only delete the stuff you're not using.
     
    moltke likes this.