I’ve placed in the scene an object with a trigger and I want the console sends me a message detecting if the player is in or out of the trigger when I click a button . When I play, it only sends me a message when the player is into the trigger.
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapDetect : MonoBehaviour {
void OnTriggerStay(Collider other)
{
if (other.gameObject.tag == "Player") {
Debug.Log ("Map ON");
}
else {
if (other.gameObject.tag == "Player") {
Debug.Log ("Map OFF");
}
}
}
}
Use OnTriggerEnter and OnTriggerExit instead of OnTriggerStay to keep the current state:
public class MapDetect : MonoBehaviour {
private bool isTriggered;
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Player"))
isTriggered = true;
}
void OnTriggerExit(Collider other)
{
if (other.gameObject.CompareTag("Player"))
isTriggered = false;
}
void Update(){
if(Input.GetKey(KeyCode.Space)){
Debug.Log(isTriggered);
}
}
}
Your logic is totally wrong. You're only checking if the TRIGGER STAYS IN YOUR BOUNDS but still trying to log "Map OFF" message which will never happen.
Instead of OnTriggerStar method use OnTriggerEnter and OnTriggerExit. Then print the message only when needed ( or in debug mode ) :
void OnTriggerEnter(Collider other)
{
if ( other.gameObject.CompareTag("Player") )
{
m_IsPlayerOnTheMap = true;
}
}
void OnTriggerExit(Collider other)
{
if( other.gameObject.CompareTag("Player") )
{
m_IsPlayerOnTheMap = false;
}
}
void Update()
{
#if DEBUG
if ( m_IsPlayerOnTheMap )
{
Debug.Log("Map ON");
}
else
{
Debug.Log("Map OFF");
}
#endif
}
private bool m_IsPlayerOnTheMap = false;
Try:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapDetect : MonoBehaviour {
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Player"))
{
Debug.Log ("Map ON");
}
}
void OnTriggerExit(Collider other)
{
if (other.gameObject.CompareTag("Player"))
{
Debug.Log ("Map OFF");
}
}
}
This will switch it on when you enter and off when you exit (althout all it does right now is print the result).
Hope it helps.
Related
I am trying to make an object that teleports the player to a different scene when clicked.
I tried following this tutorial: https://youtu.be/PpLJq6AR2J0
This is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Table : MonoBehaviour
{
[SerializeField] private GameObject UiElement;
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
UiElement.SetActive(true);
if (Input.GetKeyDown(KeyCode.E))
{
SceneManager.LoadScene("Table1");
}
}
}
void Update()
{
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
UiElement.SetActive(false);
}
}
}
But when I tried it executes everything except
if (Input.GetKeyDown(KeyCode.E))
{
SceneManager.LoadScene("Table1");
}
The code is correct and it executes when it's inside the update function. Is there a fix to this?
The physics framerate update doesn't have to match the game framerate. The Input.GetKeyDown will be true only for one frame so it won't be called. You should put input checks like Input.GetKeyDown inside the update function.
This is not the best way to do it but only to show a way to do it:
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
UiElement.SetActive(true);
colliderHit = true;
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
if(colliderHit)
SceneManager.LoadScene("Table1");
}
}
Thanks, here is the solution:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Table : MonoBehaviour
{
private bool collided = false;
[SerializeField] private GameObject UiElement;
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
collided = true;
}
}
void Update()
{
if (collided == true)
{
UiElement.SetActive(true);
if (Input.GetKeyDown(KeyCode.E) && UiElement == true)
{
SceneManager.LoadScene("Table1");
}
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
collided = false;
UiElement.SetActive(false);
}
}
}
I just used a boolean called collided. That way u can check inside the Update() function.
I'm doing a football game and i want it to play a sound every time i score a goal but i can't hear any sound.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
public class gol : MonoBehaviour
{
public AudioClip audioclip;
public AudioSource audiosource;
public bool golmu = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
if (golmu == true && !audiosource.isPlaying)
{
audiosource.clip = audioclip;
audiosource.Play();
}
}
public void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "gol")
{
golmu = true;
}
else
{
golmu = false;
}
}
public void OnTriggerExit(Collider other)
{
if(other.gameObject.tag == "gol")
{
golmu = false;
}
}
}
I tried without using AudioClip but it's not working. Putting the AudioSource component in another object too. I tried every code I saw but it didn't work.
I made this little script that should turn the light of a point light off and on ... unfortunately only the off button works, after which it doesn't turn on again .... maybe there is some error in the script?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TurnLight : MonoBehaviour {
public GameObject light;
private bool on = true ;
void OnTriggerStay(Collider other) {
if (other.tag == "Player" && Input.GetKey(KeyCode.E) && !on)
{
light.SetActive(true);
on = true;
}
else if (other.tag == "Player" && Input.GetKey(KeyCode.E) && on)
{
light.SetActive(false);
on = false;
}
}
}
Please Check this link to understand OnTriggerStay Function
On Trigger Stay
Also Please check those to differentiate between
Get Key and
Get Key Down
the problem is calling of OnTriggerStay happens continuously and you are using GetKey functions which will return true all times if the player pressed.
So when you use GetKey this will cause Single press on E will be redden multiple times.
Here is my solution
public GameObject light;
bool isPlayerStandingNear = false;
private void Update()
{
if(isPlayerStandingNear)
{
//Debug.Log("isPlayerStandingNear");
if(Input.GetKeyDown(KeyCode.E))
{
Debug.Log("Light State : "+ light.active);
light.SetActive(!light.active);
}
}
}
void OnTriggerStay(Collider other)
{
if (other.tag == "Player")
{
isPlayerStandingNear = true;
}
}
private void OnTriggerExit(Collider other)
{
if (other.tag == "Player")
{
isPlayerStandingNear = false;
}
}
I want to log in console when a cube passes through an another cube, the another cube has mesh collider with Convex and isTrigger is set to true.
using UnityEngine;
public class score_addations : MonoBehaviour
{
//[SerializeField]
//private int SCORE = 0;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "score")
{
Debug.Log("Pass");
}
else
{
Debug.Log("Fail");
}
}
private void Start()
{
//Cursor.lockState = CursorLockMode.Locked;
//Cursor.visible = false;
}
}
Here is an image of my game
for triggers you use OnTriggerEnter(Collider) Use this code
private void OnTriggerEnter(Collider collision)
{
if (collision.gameObject.tag == "score")
{
Debug.Log("Pass");
}
else
{
Debug.Log("Fail");
}
}
I am trying to wait five seconds after the trigger is met then after the five seconds is up i want to go to the next scene. The problem is that once the trigger is met the it automatically goes to the next scene.
What I have tried
using UnityEngine;
using System.Collections;
public class DestroyerScript : MonoBehaviour {
IEnumerator WaitAndDie()
{
yield return new WaitForSeconds(5);
}
void Update()
{
StartCoroutine(WaitAndDie());
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
Update();
Application.LoadLevel("GameOverScene");
return;
}
}
}
I have also tried
using UnityEngine;
using System.Collections;
public class DestroyerScript : MonoBehaviour {
IEnumerator WaitAndDie()
{
yield return new WaitForSeconds(5);
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
StartCoroutine(WaitAndDie());
Application.LoadLevel("GameOverScene");
return;
}
}
}
Only call Application.LoadLevel after yield return :).
IEnumerator WaitAndDie()
{
yield return new WaitForSeconds(5);
Application.LoadLevel("GameOverScene");
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
StartCoroutine(WaitAndDie());
return;
}
}
}
This should work
using UnityEngine;
using System.Collections;
public class DestroyerScript : MonoBehaviour {
bool dead;
IEnumerator OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
yield return new WaitForSeconds(5);
Application.LoadLevel("GameOverScene");
dead = true;
return dead;
}
}
}