- Home /
How to stop an emission from another object
Hi, I have this scene where if the player is in a collision zone and they press a button then the emission of water should stop, wait 3 seconds then turn back on again. If the player is in the water zone whilst the emission is on then they get reset. I think I have most of the code done, just struggling to find how to turn off the water. Thanks
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class waterTrigger : MonoBehaviour
{
public bool WaterOn = true;
void start()
{
StartCoroutine(ChangeWater());
}
void OnCollisionEnter(Collision gameObjectInformation) //if player is in area and x is pressed turn water off
{
if (gameObjectInformation.gameObject.name == "player")
{
if (Input.GetKeyDown(KeyCode.Joystick1Button2))
{
WaterOn = false;
}
}
}
public IEnumerator ChangeWater()
{
if (WaterOn == true)
{
yield return new WaitForSeconds(3f);// time it takes for water to turn back on
WaterOn = false;
}
}
}
and WaterfallCol:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WaterfallCol : MonoBehaviour
{
private waterTrigger WaterTrigger;
public ParticleSystem water;
// Start is called before the first frame update
void Start()
{
WaterTrigger = GameObject.Find("InteractZone").GetComponent<waterTrigger>();
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.name == "player" && WaterTrigger.WaterOn == true) // If player is in water zone and water is on reset player
{
water.Emit;
collision.transform.position = new Vector3(0f, 2.5f, 0f);
}
}
}
Answer by IvanDrake · Jan 26, 2019 at 12:08 AM
Assuming I understand right.... try this.
In your waterTrigger script: 1) If your trigger zone is a "trigger" you need to use OnTrigger, not OnCollision. Try OnTriggerStay. 2) Move your StartCoroutine out of Start and put it in your buttondown if statement. 3) Swap the states of WaterOn in your coroutine. "if(WaterOn == false) ... yield ... WaterOn = true;
In your WaterfallCol script: 1) Again, if this is a trigger, you should use OnTrigger. 2) Might need to add an else statement that stops the water emission if WaterOn is false.
Hi this still doesnt seem to work, do you have any other ideas? Ive also changed water.emt to water.Play as this is supposed to work?
Here, I got this to work:
public class WaterfallCol : $$anonymous$$onoBehaviour
{
/*private*/public WaterTrigger WaterTrigger;
public ParticleSystem water;
// Start is called before the first frame update
void Start()
{
//WaterTrigger = GameObject.Find("InteractZone").GetComponent<WaterTrigger>(); // <==== If these scripts are permanently linked, this is unnecessary
}
void Update(){
if(water.isStopped && WaterTrigger.WaterOn == true)
{
water.Play();
}
else if(WaterTrigger.WaterOn == false){
water.Stop();
}
}
//void OnCollisionEnter(Collision collision)
void OnTriggerStay(Collider col)
{
// If player is in water zone and water is on reset player
if (/*collision.gameObject.name*/col.gameObject.tag == "Player" && water.isEmitting){
Debug.Log("Player entered water zone.");
col.transform.position = new Vector3(0f, 2.5f, 0f);
}
}
}
public class WaterTrigger : $$anonymous$$onoBehaviour
{
public bool WaterOn = true;
void start()
{
// StartCoroutine(ChangeWater());
}
//void OnCollisionEnter(Collision gameObjectInformation) //if player is in area and x is pressed turn water off
void OnTriggerStay(Collider col)
{
if (/*gameObjectInformation.gameObject.name*/col.tag == "Player") // <======= Would recommend using "Player" tag, ins$$anonymous$$d of name. Unless you're using the gameobject tag for something else.
{
//Debug.Log("Player in trigger zone");
if (Input.GetButtonUp("Fire1"))//Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Joystick1Button2)) // <======= Recommend using Input buttons, rather than specific keys
{
//WaterOn = false;
Debug.Log("Player pressed button.");
StartCoroutine(ChangeWater()); // <==========
}
}
}
/*public*/ IEnumerator ChangeWater()
{
/* if (WaterOn == false)
{
*/
WaterOn = false;
yield return new WaitForSeconds(3f);// time it takes for water to turn back on
WaterOn = true;
// }
}
}
Answer by Bonfire-Boy · Jan 26, 2019 at 05:25 PM
A few things jump out at me...
void start()
{
StartCoroutine(ChangeWater());
}
Is the above supposed to be a (capitalised) MonoBehaviour Start
function? (if yes then capitalise it, no then I'd recommend renaming it, you'll only confuse things giving it that name).
water.Emit;
What's the above supposed to do? This isn't a function call and WaterTrigger
has no field or property with that name. Did you mean to call water.start()
there? (if so then see point 1 and rename start
to something like TurnWaterOffTemporarily
because it looks that's what it's supposed to do)
You never set WaterOn
to true except on initialisation. So (if you were calling the function properly) the collision turns the water off but it never gets turned on again. I suspect that ChangeWater
should look like this...
public IEnumerator ChangeWater()
{
if (WaterOn)
{
WaterOn = false;
yield return new WaitForSeconds(3f);// time it takes for water to turn back on
WaterOn = true;
}
}
Finally, add some Debug.Log
lines so you know what functions are being called and when. Always a good idea when dealing with collisions so that you know whether the problems are related to the code or the set-up (ie are the collision callbacks doing the wrong thing, or just not getting called?) When you've got it working, comment the logging lines out so it's easy to reinstate them if it goes wrong again.
Hi Im still stuck on this, do you have any other ideas? I have used the debugs which seems to be showing that the WaterOn function starts on then turns to false ., also the particle effect doesnt stop?
Ive added an image of my scene if that helps, there is a collider by the interact zone which will have the trigger script. I want it so that the player has to be in the zone to stop the water, have a certain amount of time to complete the course before the water turns back on. Thanks
Are you actually disabling and reenabling the particle effect somewhere? Just changing that flag won't do that on its own. You probably don't need the flag at all. On reflection, it's not clear to me why you have both the classes you've shown. Try starting with something simpler like this.
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.name == "player" && water.enabled )
{
StartCoroutine(StopWaterTemporarily());
}
}
IEnumerator StopWaterTemporarily()
{
water.enabled = false;
yield return new WaitForSeconds(3f);
water.enabled = true;
}
Your answer
Follow this Question
Related Questions
Emission not working on model 0 Answers
Is it possible to make emissive dice in Unity? 1 Answer
How to bake metallic reflexion from self illuminated static objects ? 0 Answers
How to get Bloom effect only on emissive materials HDRP Volume component 0 Answers
Using a sequence of frames as a material emissive map. 0 Answers