Easiest way to do it would be to add a huge collision sphere to the player set to overlap all, add a begin overlap event for it, and check if overlapped actor has a tag like “metal” which you would assign to any detectable actors. If it finds something. add it to an array variable, and check the distance periodically (either in tick or a timer event and play sounds/display any ui info based on distance to actor.
Check out my posts and example project in this topic about making a geiger counter. Could repurpose code and change the tags a bit to turn it into a metal detector.
I’ve tried to do your method but since i’m new to blueprint i didn’t suceed but here’s where i am now.
I’ve made a system that every second look for the nearest object in my scene with the tag “Metal” and i’ve made that if the distance is less than my variable it’s playing a specific sound so if the player is far it’s play one sound and near the object an another and if the player is on the object an another one.
But my problem now it’s my “Set timer by event” influence my sound also and every second the sound play again and superpose and i don’t know how to fix that.
get all actors of class is bit expensive, how often do you update that check? or how does it work? just scan with detector then only whats in range you get all actors?
The “Set timer by event” update it every 1 seconds and it supposed to take all actor “BP_MetalObject” and calculate which one is the closest every 1 seconds.
I’ve done this in the player blueprint since i don’t have a detector yet
So there is couple of aspect that we should take care of and make some decisions around it.
Detector
-Gets some tagged actors around, a collision sphere
–OnBeginOverlap->IF(Tags Match or Class) -> AddToArray (CurentMetalsAroundMe)
–OnEndOverlap->IF(Tags Match or Class)-> RemoveFromArray(CurentMetalsAroundMe)
So we know the actors now around us, you can set a size to collision, set maybe overllap all as channell in begin play and good to have that once with update overlaps ticket since on begin play if you already overlapping a metal you can know about it.
Feedback To Player
-There coulld be couple of use cases, where many metals around and maybe single metal. When its single its good however on multiple ones i am pretty sure it will get messy with the audio.
-In that terms just to start doing it nicely i will recommend selecting the most relevant one (will explalin this later)
Current distance 99999 for default and gets lower in callcuation if there is a metal around, when If(CurentMetalsAroundMe.Length > 0 is false you can set back to 9999 somenumber.
Now you have the ClosestMetal. When this turns valid simply you can run a timer of your choice 0.5 and set volume/pitch of your audio according to current distance again using same vector distance method, you can lerp volume pitch etc 0.5 1.5
Design Wise
I recommend going with a single source of focus since mulltiple sources can be sometimes not understandablle for players. If there is more than one the closest one is focused.
If you prefer geiger type of counter you can just prefer tick operation with distance check and kick a sound timer rate for that distance.
I suggest still using some ui, diegetic, haptic feedback in the detection since some players can be hearing disabled, deficient, playing without sound, llistening to music.
Maybe start with first event of collision: OnOverlapBegin/End and get actors around you correctly then let us know if you get stuck, we help.
I’ve tried but failed all the code need to be in my BP_MetalObject or my character ?
The variable “CurentMetalsAroundMe” is an Actor in array ? I’m not so familiar with types of variables.
Same for the rest of the variables i’m not sure of what types i need.
The code i tried doesn’t seems to work and don’t detect the BP metal near me.
For the design side and feedback my goal is to have multiple metal object bur far from each other so no overlap and maybe a radar in UI if the player can’t play with sound.
A sphere trace would be optimal for gathering objects. You can filter out by class and set the source of the sphere to be the end of the metal detector.
Instead of looping through the array and checking each distance, you can feed the array to a Find Nearest Actor node, and it will return the closest one and its distance.
Also, as in teh screen, I would suggest using Get Actors With Tag instead of class. Then you can just tag new bp actors later instead of redoing the code to filter for extra classes.
Using overlap event to test would probably be better too. Getting all actors could be expensive since it will be checking every object on the map.
As for the code being on the player or not. You could make a new component class blueprint and add the component to player(click make new BP like making an actor, but chose component for the base/parent class). With a component, you can also change its tick rate to, say 1s and fire the check in component’s tick event instead of mucking with timers.
In my level created some stuff like a static mesh or actor or your metall bp whatever.. on their detaills added an actor tag as MetalSource . Now whatever i tag with this name it can be detected
Now extended my logic a step further.. deleted debug prints and make over tick . loop actors and get distance and compare them if something matches added to CurrentClosestMetalActor variable. OnComplete created a custom event and named as CalculateSignal..
Converted CurrentClosestMetalActor to validate get and print out its name just to debug
Now onto making a nice audio feedback. Since i did this much i will make a Geiger type of audio feedback simulllation. Now actually added a distance mapped to 0.1 to 10 value as 'GeigerCoefficient`
I made a new function as play sound made a timelline 1sec. check if its playing, play timelline so we can be sure that it kicks random, created a lloop with the coefficient to randomize kicks of alpha particle added some randomization to dellaly and to rate. Used this sound Freesound - Walkie-talkie end of transmission by LukaCafuka mixed with
additonallly started audio loop here but you can change as you llike, and delays, fake sounds can be alllso simullalted using unrealls audio system however this is the raw logic / a quick proto, you can play and push further for sure.
Areas of improvement
Instead of a quick compare rule on distance , distances can be sort and prioritized.
Instead of loopiong audio an audio script can run without the timelines and delays.
Mulltiple actors can be prioritized but sound design wise lllowest sounds can be omitted or llower volume, ofcourse a nice audio design and good format sounds can be tweaked.