I asked this question in the Answers tab a week ago and haven’t got any reply so i figure that maybe someone here can help me out here.
Hi guys, I was wondering if anyone can please help me out with a script that triggers a component at a certain depth. Basically I’m trying to do a drowning script. I already have the swimming script that triggers with the collider of the player but I can’t do the same because I can’t add a collider to the camera. Basically I want a breath meter I created to trigger below a “Y” axis height and to reset once you go above the “Y” axis but I can’t figure out how to do this. Can some please help me with how I should declare the value and how to start this script? I can do the rest but I just don’t know how to do the y axis portion.
I will use 2 separate script. 1 for swimming (done) and 1 for holding the breath. once both re complete I’ll try to put them together.
public float waterLevel;
public float drownTime;
private float drownTimer;
if (transform.position.y < waterLevel) //Checks the y-position
{
drownTimer += Time.deltaTime;
}
else
{
drownTimer = 0;
}
if (drownTimer > drownTime)
{
//Mercilessly drown the player character here (you monster)
}
It increments the time spent underwater when under the water level, and resets it to 0 when above it. If you spend more than drownTime under the water level, you call the drowning logic.
Hmm that sort of works but i just realized that i can’t use y axis as well because i have different water section at different altitudes. I had an idea of using a whole new trigger box and placing it about 6 feet below the swimming trigger. With that i managed to make the player basically made the body (not the head) of the player enter a whole new trigger that triggers the underwater fiction of the hold breath script. Now i’m trying to figure out how i can make the meter regenerate when the player exits the collider. Maybe you can help me with that section? below are the two scripts i;m using to preform this task. If anyone has an easier way of doing this and would like to share it please do. I will appreciate it. Also please excuse my code if it’s kind of messy but I’m a C# noob.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
[RequireComponent(typeof(AudioSource))]
public class DrowningScript : MonoBehaviour
{
Image fillImg;
public float timeAmt = 35;
float time;
public AudioClip DrownDeathSfx;
public AudioClip BreathSfx;
void Start()
{
fillImg = this.GetComponent();
time = timeAmt;
}
public void UnderWater(){
if (time > 0) {
time -= Time.deltaTime;
fillImg.fillAmount = time / timeAmt;
if (time <= 0) {
GetComponent ().clip = DrownDeathSfx;
GetComponent ().Play ();
}
}
}
public void AboveWater(){
fillImg.fillAmount = 35f; //sets the meter back to 35 but will start from last update when enter the water
}
}
It’s easier if you set your variable ‘fillmg.fillAmount’ to be ‘time / timeAmt’ in the update Method.
Then in the ‘AboveWater’ method, simply do this to slowly regenerate your ‘time’ veriable:
private float regenSpeed = 0.5f;
public void AboveWater()
{
if (time <= timeAmt)
{
time += regenSpeed;
}
else
{
time = timeAmt;
}
}
void Update()
{
fillmg.fillAmount = time / timeAmt;
}
I haven’t tested it, message me if you get any errors or something is not working.
Of so i was able to go around the issue that the regeneration stopped about less than 1 sec after stepping away of the trigger. I basically made it regenerate instantly by making the regenSpeed the same amount as the timeAmt.
Hmm. the script works flawless with the meter but the audio is now broken. I believe it’s because it set to the Update function. I tried using the playoneshot method but it still loops constantly. I also tried setting the playoneshot to run when (time <=0) but the loops keeps on. below is what i tried.
If it isn’t, then you could call a function which then plays the sound.
if (time > 0)
{
time -= Time.deltaTime;
if (time<=0)
{
playSound();
}
}
void playSound() //place this outside the update function
{
audio.PlayOneShot(DrownDeathSfx, 1F);
}
Okay, then it’s really unclear how you meant it, either you don’t understand when you call methods in the Update method they’ll be ran every frame, or you made it really unclear. Your example clearly shows the method inside the update method. Your note makes no sense.
The whole thing, what do you want to be placed ‘outside’ the update function?
Remember, calling functions that aren’t litterally ‘in’ the Update function but are ‘called’ in the Update function will behave the same as if it was ‘in’ the Update function.
Example to clearup what we’re talking about:
void Update()
{
NotInUpdate(); // Called in the update function
}
void NotInUpdate()
{
if (value)
return;
//This is still inside the update function.
}
This is the exact same as if you would write it like this:
void Update()
{
if (value)
return; //The same as above, inside the Update function.
}
I know there could be several ways to make this work. That’s why programming is great. I do have to say that the sound now works fine with the small fix melle suggested. The sound plays 1 time and doesn’t loop anymore. Below is the portion of the script i updates with melles info.
void Update()
{
if (inWater)
{
if (time > 0)
{
time -= Time.deltaTime; if (audio.isPlaying) return;
if (time <= 0) {
audio.PlayOneShot (DrownDeathSfx, 1F);
}
}
}
else
{
if (time >= timeAmt)
return;
time += regenSpeed;
}
fillImg.fillAmount = time / timeAmt;
}
@melle well seeing as my note is placed directly next to the function, I would assume that you had the initiative to realise that the function needs to be placed outside the Update() function. And what, so your saying that a function that isn’t inside the update function will still behave like it is, makes sense that :')