In air and ground explosions and dynamic gravity for grenades

Cheo

Active member
Hello everyone, this is yet one more thing that might sound a bit niche at first but that any modern game should be able to implement : different explosion prefabs for grenades depending on whether they're exploding in the air or on the ground, and ground explosions following a spherical object's normal ! Here are two quick videos of what I want help you achieve here :



To implement this, you'll first need to take a look at this post and modify the Object Spawn Info class : http://www.opsive.com/forum/index.p...-scale-parameters-to-object-spawn-info.10218/

If your vfx is shooting upwards, then you'll need to rotate it in a way that it follows the root transform's z axis.

Next, here is the code you should use instead of Grenade :

C#:
using Opsive.UltimateCharacterController.Objects;
using Opsive.UltimateCharacterController.Utility;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyGrenade : Grenade
{

    [SerializeField] protected ObjectSpawnInfo[] m_SpawnedObjectsOnDestructionInAir;
    public ObjectSpawnInfo[] SpawnedObjectsOnDestructionInAir { get { return m_SpawnedObjectsOnDestructionInAir; } set { m_SpawnedObjectsOnDestructionInAir = value; } }

    [SerializeField] protected LayerMask m_GroundLayers;
    public LayerMask GroundLayers { get { return m_GroundLayers; } set { m_GroundLayers = value; } }

    [SerializeField] protected float m_GroundDetectionRange = 0.2f;
    public float GroundDetectionRange { get { return m_GroundDetectionRange; } set { m_GroundDetectionRange = value; } }

    public override void Destruct(RaycastHit? hit)
    {
        RaycastHit groundCheck;

        if (!Physics.Raycast(transform.position, m_NormalizedGravity, out groundCheck, m_GroundDetectionRange, m_GroundLayers))
        {
            m_SpawnedObjectsOnDestruction = m_SpawnedObjectsOnDestructionInAir;
            base.Destruct(hit);
        }
        else
        {
            base.Destruct(groundCheck);
        }
        
    }

}

You'll also need to make an inspector script for it. To make sure there are no errors and that the scripts correctly detect one another, put them in the Opsive folder along the Grenade and Grenade Inspector scripts respectively.

C#:
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------

namespace Opsive.UltimateCharacterController.Editor.Inspectors.Objects
{
    using Opsive.UltimateCharacterController.Objects;
    using UnityEditor;
    using UnityEngine.UIElements;

    /// <summary>
    /// Custom inspector for the Grenade component.
    /// </summary>
    [CustomEditor(typeof(MyGrenade), true)]
    public class MyGrenadeInspector : GrenadeInspector
    {
        /// <summary>
        /// Draws the inspector fields for the object.
        /// </summary>
        protected override void DrawObjectFields(VisualElement container)
        {
            base.DrawObjectFields(container);

            PropertiesFoldout(container, "Grenade", m_ExcludeFields, new[]
            {
                "m_SpawnedObjectsOnDestructionInAir",
                "m_GroundLayers",
                "m_GroundDetectionRange"
            });
        }
    }
}

Make sure Use Normal is set to true for prefabs used for ground explosions, and you should be good to go !

You'll notice that thanks to m_NormalizedGravity, ground explosions can be spawned correctly on planets, like the ones from the demo scene ! There are however two limitations I haven't solved :
-Particles with rigidbodies are not affected by UCC's dynamic gravity. If someone can spare me the trouble of tinkering with this and share a way to have them follow a planet's gravity, I'd be grateful !
-When leaving a gravity zone, it is possible for the grenades to only spawn the air explosion prefab, something must be wrong in how the Align to gravity ability is stopped, as the thrown objects seem to use their thrower's gravity.

This actually brings us to a last point : unless I'm mistaken, it seems that grenades can't get caught in another gravity zone, and continually follow the thrower's gravity. I know this is perhaps an advanced feature, but I think I'll make this a feature request later on.

That's all for today, I hope I havent forgotten anything and that this will be helpful. I might make a video tutorial out of this.
 
Top