How can I make a song play when an NPC gets within a certain range of the player?
So what I'm trying to do is to get the current playing song to fade out and be replaced with another track when an npc gets within a certain distance of the player, even if the player doesn't see them right away. Is there a way to do this using a C# script?
For example, the player is walking around and the NPC is about 20 feet away, the current BG music would fade out and play the chase music. Once the player gets far away from the NPC and they stop following the player, it would go back to the previous track that was playing.
I'm wondering if I should put an audio source on the NPC that would trigger when they start chasing the player but coding wise I don't really know what to put.
Any and all advice would be greatly appreciated :)
Answer by whereswaldo · Jan 29, 2017 at 02:46 AM
There are many ways you could do this, but the easiest and quickest way is with triggers and an OnTriggerEnter script linked to your audio. It should go something like this:
public AudioClip music;
void OnTriggerEnter(Collider collider)
{
if (collider.tag == "player")
{
music.Play();
}
else {
music.Stop();
}
That worked really well but the chase theme keeps playing even when the player escapes and the current game level's BG music keeps playing during this. Do you know how to make the current BG music stop playing when the player gets close?
Right now I have an audio source attached to the player and another attached to the NPC. The game's BG music is attached to the player(as I can't hear it when it's just in the level) and the chase theme is of course on the NPC.
This might help explain it,
I hope that helped explain it P:
Edit: I realised the audio just plays even when the player isn't even close P:
this should do everything perfectly. Just add this to a c# script called PlayRange
public class PlayRange: $$anonymous$$onoBehaviour
{
public AudioClip music;
void OnTriggerEnter(Collider collider)
{
if (collider.tag == "player")
{
music.Play();
}
}
void OnTriggerExit(Collider collider)
{
if (collider.tag == "player")
{
music.Stop();
}
}
}
And do I add this to the audio source as well or just the NPC? (sorry for all the questions, I just want to make sure I don this right and don't waste anyone's time as I applied this to the NPC and while it did work in the inspector, the audio didn't play)
It isn't working because you dont have a trigger attached to the npc. create one and edit the distance size as you please. The smaller the trigger (a trigger is a box (or any) collider with the 'is trigger' box ticked) the smaller the distance will have to be between the player and the npc before the music is playing. Drag the music you want to play into the 'music' box on the script in the inspector. also: when you created the script you put a space between the words 'Play' and 'Range' rather than na$$anonymous$$g it 'PlayRange' like I said. This will cause errors.
just do these things and it should work perfectly!
That's strange, the script is called PlayRange, I don't know why it suddenly has a space in the name in the inspector.
Also I tried to add a sphere collider but it I'm still not getting it to trigger the PlayRange script :/
Add a box collider to the same object you have the PlayRange script attached to. Tick the box that says 'Is Trigger'
Answer by UnityCoach · Jan 23, 2017 at 11:24 PM
You need to "watch" the distance between the NPC and the Player, this can be done in Update : Put this in a script on the NPC. Note that it'll work with one NPC, if you want more NPC, you'll have to start working on a "audio manager class".
float _distance;
public float minDistance = 5f;
Transform player;
AudioSource _audio;
void Awake ()
{
player = FindObjectWithTag ("Player").transform;
_audio = GetComponent<AudioSource>();
}
void Update ()
{
_distance = Vector3.Distance (transform, player);
if (distance <= minDistance)
_audio.Play ();
}
I tried to put it in my script but it caused errors. Do I copy and paste this below void start on my script?
This is what my script looks like for the NPC:
using UnityEngine; using System.Collections;
public class Fog$$anonymous$$an : $$anonymous$$onoBehaviour {
// Use this for initialization
void Start () {
}
//The target player
public Transform target;
//At what distance will the enemy walk towards the player?
public float walkingDistance = 10.0f;
//In what time will the enemy complete the journey between its position and the players position
public float smoothTime = 10.0f;
//Vector3 used to store the velocity of the enemy
private Vector3 smoothVelocity = Vector3.zero;
//Call every frame
void Update()
{
//Look at the player
transform.LookAt(target);
//Calculate distance between player
float distance = Vector3.Distance(transform.position, target.position);
//If the distance is smaller than the walkingDistance
if(distance < walkingDistance)
{
//$$anonymous$$ove the enemy towards the player with smoothdamp
transform.position = Vector3.SmoothDamp(transform.position, target.position, ref smoothVelocity, smoothTime);
}
}
}
@veugeljame Whenever I try to assign the script to the model character I get those errors and then it won't even play unfortunately.
I'm also having trouble with my pause menu that was working just fine until I got the option to update the API(this is related, let me explain) I backed up my game onto an external hard drive and before that the menu worked but afterwards it stuffed up my pause menu so when I add the buttons, the pause menu doesn't show up.
I'm wondering if the API could be affecting this script too? Since even the backup copies of my script have been affected since I did that. If so, do you think that if I were able to undo the changes to the API that were done, would this script plus my other scripts start working again? P: I mean I think the placement of the code in the NPC's script for the audio is correct but it's still not working for me :/
There might be a curly bracket missing the Fog$$anonymous$$an script or one of the other scripts you have. Likely to be Fogman.
@UnityCoach, wouldn't it be easier to use a RayCast event that points directly at the player, the ray only being a certain length and then if the object it touches is the same as the player, queue the audio file?
@Sora$$anonymous$$ahiro Ray casting is expensive and can greatly slow down a games performance if there are too many running at the same time. So should be avoided if possible.
Your answer
Follow this Question
Related Questions
Can a Trigger object utilize the OnTriggerEnter() Function? 2 Answers
How do I not trigger animation during play state of the triggered animation. 1 Answer
2D Power up script not working 0 Answers
Help me with gui please (C#) 2 Answers
How do I hide/show an object, when the player enters a trigger zone? 2 Answers