Accessing a MonoBehavior from Surface Effect

Cheo

Active member
Hello, I made a simple script dedicated to sound detection which contains a function using a sphere cast to detect nearby enemies that may hear a sound made by the player. I managed to use it in a weapon module, but I can't manage to use it with the Surface Effect script - my initial idea was to add noise detection parameters on surface effects (preventing the sphere cast on some and increasing the radius on others), and then call my custom script either in CharacterFootEffects' Footstep or SurfaceEffect's SpawnEffectInternal, but I can't manage to access my custom script from either of those two.
So that leads me to two questions : is there a way to access a simple MonoBehavior from this kind of script ? And is there maybe a better way to handle range checks based on surfaces ? Thanks in advance.
 
I haven't tried this but you may be able to subclass the SurfaceEffect and assign that object in the inspector. From there you can override the SpawnFootStep method and provide your new code.
 
Thanks for the suggestion, but I haven't gotten very far - I tried making a new script inheriting from SurfaceEffect, it can override SpawnFootprint (is this what you were making reference to ?), but that's about it, I can't use GetComponent to get access to one of my components from it, and it remains a Scriptable Object.

C#:
using Opsive.UltimateCharacterController.SurfaceSystem;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MySurfaceEffect : SurfaceEffect
{
    public override void SpawnFootprint(RaycastHit hit, Vector3 gravityDirection, float timeScale, GameObject originator, bool spawnDecals, Vector3 footprintDirection, bool flipFootprint)
    {
        base.SpawnFootprint(hit, gravityDirection, timeScale, originator, spawnDecals, footprintDirection, flipFootprint);
    }
}

Also I can't find this scriptable object type in the Create list without using the CreateAssetMenuAttribute, and it doesn't have all the values and foldouts the SurfaceEffectInspector gives to SurfaceEffect, is there a simple way to get all that for subclasses of existing Opsive Scriptable Objects ?
Sorry I'm no expert in programming, I need more guidance on this please !
 
Hello, I made a simple script dedicated to sound detection which contains a function using a sphere cast to detect nearby enemies that may hear a sound made by the player. I managed to use it in a weapon module, but I can't manage to use it with the Surface Effect script - my initial idea was to add noise detection parameters on surface effects (preventing the sphere cast on some and increasing the radius on others), and then call my custom script either in CharacterFootEffects' Footstep or SurfaceEffect's SpawnEffectInternal, but I can't manage to access my custom script from either of those two.
So that leads me to two questions : is there a way to access a simple MonoBehavior from this kind of script ? And is there maybe a better way to handle range checks based on surfaces ? Thanks in advance.
This sounds sooo close to an AI system I developed back some time ago, it would "alert" enemies in said hearing range, and would be passed onward to any other as they called out the random enemy detected lines. You could also "radio in" AI reinforcements of your own, at a cost. Although I did only rely on when a shot was fired, not where it hit. Also had some stealth stuff, maybe worth integrating with v3 ;)
In theory there's likely "an event for that". For footstep detection you may be able to subscribe and use to fire Globally. that way you can include any params you like and AI can "sense" it.
 

As far as I know there is no ready to use event for this kind of thing in UCC's code, so I made my own !

We simply need to add this at the end of both SpawnEffectInternal bools in SurfaceManager :

C#:
EventHandler.ExecuteEvent<RaycastHit, Collider, GameObject, SurfaceImpact, SurfaceEffect>("OnSurfaceImpact", hit, hitCollider, originator, surfaceImpact, surfaceEffect);

And here is what my script looks like :

C#:
using UnityEngine;
using Opsive.Shared.Events;
using Opsive.UltimateCharacterController.SurfaceSystem;
using Opsive.UltimateCharacterController.Character;
public class MySurfaceEffectTest : MonoBehaviour
{
    public LayerMask soundMask;
    public void Awake()
    {
        EventHandler.RegisterEvent<RaycastHit, Collider, GameObject, SurfaceImpact, SurfaceEffect>("OnSurfaceImpact", OnSurfaceImpact);
    }
    private void OnSurfaceImpact(RaycastHit hit, Collider hitCollider, GameObject originator, SurfaceImpact surfaceImpact, SurfaceEffect surfaceEffect)
    {
        GameObject uccOriginator = originator.GetComponentInParent<UltimateCharacterLocomotion>().gameObject;

        if (uccOriginator != null)
        {
            RaycastHit[] soundHit;

            soundHit = Physics.SphereCastAll(hit.point, surfaceEffect.SoundSpreadRange, hit.normal, surfaceEffect.SoundSpreadRange, soundMask);

            foreach (RaycastHit h in soundHit)
            {
                if (h.transform.GetComponent<MyAgentScript>())
                {
                    if (h.transform.GetComponent<MyAgentScript>().m_SoundDetection)
                    {
                        h.transform.GetComponent<MyBehavior>().SoundDetectionObject(uccOriginator);
                    }
                }
            }
        }

    }

    public void OnDestroy()
    {
        EventHandler.UnregisterEvent<RaycastHit, Collider, GameObject, SurfaceImpact, SurfaceEffect>("OnSurfaceImpact", OnSurfaceImpact);
    }
}

It can definitely be optimized a bit, I have two scripts dedicated to agents that I should combine, but the results are here !
So now surface effects can cause sound detection for both footsteps and bullet impacts. Thank you very much for setting me in the right direction @FastSkillTeam <3
 
Top