Checking player is not in scene(Not working) - c#

I have a game that I want a restart button to appear if you die (The game object destroys itself).
This is what I have. This is the script attached to the button:
public GameObject Player;
public GameObject Button;
bool player;
public void RestartGame(){
SceneManager.LoadScene("SampleScene");
}
void Start(){
player = true;
}
void Update(){
if (!Player){
player = false;
}
if(player == true) {
Button.SetActive(false);
}
if(player == false){
Button.SetActive(true);
}
}
And this is the code attached to the object that gets deleted:
void OnTriggerEnter(Collider other)
{
Destroy(gameObject);
}
When it starts the Button is disabled but when I die nothing appears. I have tried many things like checking if it is == null and all of that stuff but it still doesn't work. My goal is to make the restart button appear once the object is destroyed.

From what I understand you are checking if player get destroyed or not. However you are destroying trigger.
There must be a tag on player object use that. On your trigger object use this code. Pass player and button on inspector.
public GameObject Player;
Public GameObject Button;
void OnTriggerEnter(Collider other)
{
if (other.gameobject.comparetag("Player"))
{
Destroy (Player);
Button.SetActive(true);
}
}
For this to work both objects player and trigger must have colliders
and at least one of them must have rigidbody , and player tag must be Player

Related

Unity Animator not entering entry state

I am trying to make a very simple animation in unity where an element fades in and out based on if a character enters a box collider of an NPC. When running the game, I have my Animator window open, and the blue horizontal line that normally appears under the entry state isn't even showing up. When looking at the previews of my animations the sprite I'm animating fades in and out so I know that isn't the problem. For some reason my entry state isn't even being reached and I can't figure out why.
I have the animation clips set up for an open and close state, I have a script that takes a public Animator and dragged the gameobject with the animator into the respective slot in the editor.
Here's the file that triggers the animation: (PS: I've inserted Debug.Log statements and know for a fact I am entering the if(playerInRange) condition.
public class DialogueTrigger : MonoBehaviour {
[SerializeField] private GameObject visualCue;
[SerializeField] private TextAsset inkJSON;
public Animator animator;
bool playerInRange;
void Awake() {
playerInRange = false;
visualCue.SetActive(false);
}
void Update() {
if (playerInRange) {
animator.SetBool("IsOpen", true);
if (InputManager.GetInstance().GetInteractPressed()) {
Debug.Log(inkJSON.text);
}
}
else {
animator.SetBool("IsOpen", false);
}
}
void OnTriggerEnter2D(Collider2D other) {
if (other.gameObject.tag == "Player") {
playerInRange = true;
}
}
void OnTriggerExit2D(Collider2D other) {
if (other.gameObject.tag == "Player") {
playerInRange = false;
}
}
}
UPDATE: aaaaand of course the second I post on stack overflow I figure it out. I needed to remove the visualCue.SetActive("False") line as that was disabling the sprite I was trying to animate, had that in there from a tutorial I was following earlier.

How to disable a script with void OnTriggerEnter2D?

So I have this script that disables my movement when I enter a certain area, how do I make my animation go from whatever animation they are in to my idle animation only when I enter the collider? Thanks!
using System.Collections.Generic;
using UnityEngine;
public class endLevel : MonoBehaviour
{
public void OnTriggerEnter2D(Collider2D collision)
{
GetComponent<CharacterController2d>().enabled = false;
Debug.Log("Level Cleared");
}
}
you have to specify that object is Player
first set your player Object Tag or Layer
set to "Player" and go to your script
if(collision.CompareTag("Player"))
or
int PlayerLayer;
void Start()
PlayerLayer = layer.NametoLayer("Player")
if(collision.gameObject.layer == PlayerLayer)
if collided gameObject is player. get player script's Animator to stop function.
collision.gameObject.GetComponent<Animator>().enabled = false;
"[...] make my animation go from whatever animation they are in to my idle animation only when I enter the collider[...]"
Use Animator.CrossFade. Example:
public void OnTriggerEnter2D(Collider2D collision)
{
GetComponent<Animator>().CrossFade("your_idle_state", 0.5f);
}
For performance reasons, I recommend caching the Animator reference in a private variable, initialized in Start(). If you are unsure if the object actually has an Animator Component, use TryGetComponent().

OnCollisionExit is not being called

Why is OnCollisionExit not being called? I am using both OnCollisionEnter and OnCollisionExit but unfortunately only OnCollisionEnter is being called.
public bool HandleCollided = false;
public void OnCollisionEnter(Collision col)
{
if(col.gameObject.name == "RightHandAnchor")
{
HandleCollided = true;
}
}
public void OnCollisionExit(Collision col)
{
if(col.gameObject.name == "RightHandAnchor")
{
HandleCollided = false;
}
}
It's impossible to tell why your code isn't working based the given snippet - this code depends on the configuration of each of the GameObjects' inspector windows in the editor.
Both the GameObject that this script is attached to and the colliding GameObject must have one Collider component attached to each of them (for example, a BoxCollider component or a SphereCollider component). Both Colliders must have their isTrigger checkboxes disabled. The GameObject that this script is attached to must also have a Rigidbody component attached.
In order to debug this situation, add Debug.Log() statements in your functions. This is generally good practice, and it might be that the function is being called but the conditional statement is not true.
Here are some additional ideas on what might be going wrong:
You may be changing the name of the colliding GameObject somewhere else in your code.
You may be destroying the GameObject.
It might be that neither function was being called and HandleCollided was being changed elsewhere in your code.
It might be that the parameter, col, is not what you expect.
public void OnCollisionEnter(Collision col)
{
Debug.Log("Collision Enter!");
Debug.Log(col.gameObject.name);
}
public void OnCollisionExit(Collision col)
{
Debug.Log("Collision Exit!");
Debug.Log(col.gameObject.name);
}
So you said "There are two objects that collides with each other. One has sphere collider attached to it and another has box collider. One of the objects have rigidbody attached as well." On which one is the code? and yes this matters! only 1 of the objects will keep track of the exit meaning that if it's the non-kinematic it will not work.
Unfortunately using OnCollisionExit did not work so instead I used OnTriggerEnter and OnTriggerExit. I activated "isTrigger" for both objects.
public void OnTriggerEnter(Collider col)
{
Debug.Log("entered");
if (col.gameObject.name == "RightHandAnchor")
{
HandleCollided = true;
}
}
public void OnTriggerExit(Collider other)
{
Debug.Log("exit");
if (other.gameObject.name == "RightHandAnchor")
{
print("No longer in contact with " + other.transform.name);
HandleCollided = false;
}
}
You need a non-kinematic rigidbody attached to your object to get the event for OnCollisionExit
Try to use OnCollisionEnter() and OnTriggerExit() !!
Example:
void OnCollisionEnter(Collision collision)
{
if((collision.gameObject.GetComponent<AttributeManager>().attributes & doorType) != 0)
{
this.GetComponent<BoxCollider>().isTrigger = true;
}
}
private void OnTriggerExit(Collider other)
{
this.GetComponent<BoxCollider>().isTrigger = false;
}

Destroy particle system when initalised programmatically

I have a game with a player and an enemy.
I also have a particle system for when the player dies, like an explosion.
I have made this particle system a prefab so I can use it multiple times per level as someone might die a lot.
So in my enemy.cs script, attached to my enemy, I have:
public GameObject deathParticle;
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.name == "Player" && !player.dead){
player.dead = true;
Instantiate(deathParticle, player.transform.position, player.transform.rotation);
player.animator.SetTrigger("Death");
}
}
So this plays my particle system when the player gets killed by an enemy. Now on my player script, I have this. This specific function gets played after the death animation:
public void RespawnPlayer()
{
Rigidbody2D playerBody = GetComponent<Rigidbody2D>();
playerBody.transform.position = spawnLocation.transform.position;
dead = false;
animator.Play("Idle");
Enemy enemy = FindObjectOfType<Enemy>();
Destroy(enemy.deathParticle);
}
This respawns the player like normal but in my project each time I die I have a death (clone) object which I don't want. The last 2 lines are meant to delete this but it doesn't.
I have also tried this which didn't work:
Enemy enemy = FindObjectOfType<Enemy>();
ParticleSystem deathParticles = enemy.GetComponent<ParticleSystem>();
Destroy(deathParticles);
There is no need to Instantiate and Destroy the death particle, that will create a lot of overhead, you can simply replay it when you want it to start and stop it, when you dont need it
ParticleSystem deathParticleSystem;
private void OnTriggerEnter2D(Collider2D collision)
{
#rest of the code
deathParticleSystem.time = 0;
deathParticleSystem.Play();
}
public void RespawnPlayer()
{
//rest of the code
deathParticleSystem.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
}
or you can enable and disable the gameObject associated with your particle prefab
public GameObject deathParticlePrefab;
private void OnTriggerEnter2D(Collider2D collision)
{
#rest of the code
deathParticlePrefab.SetActive(true);
}
public void RespawnPlayer()
{
//rest of the code
deathParticlePrefab.SetActive(false);
}
You could always create a new script and assign it to the prefab that destroys it after a certain amount of time:
using UnityEngine;
using System.Collections;
public class destroyOverTime : MonoBehaviour {
public float lifeTime;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
lifeTime -= Time.deltaTime;
if(lifeTime <= 0f)
{
Destroy(gameObject);
}
}
}
So in this case you would assign this to your deathParticle. This script is useful in a multitude of scenarios if you're instantiating objects so that you don't have a load of unnecessary objects.

Audio play issue on button click

I'm working with unity and have problem with audio. Here is scenario when user click on button, Object falls on ground and destroy. When click on button sound effect of object falling is play. And destroy, Object is instantiate again then same click sound effect is play again. But when one object is falling and does not collide at this time user click again that button sound play again. I want that when one object is complete destroy than again click happen and sound is play.
Code CubeScript:
public class Cube : MonoBehaviour {
Rigidbody2D body;
void Start () {
body = GetComponent<Rigidbody2D>();
body.isKinematic = true;
}
}
Code ColliderScript:
public class Ground : MonoBehaviour {
private Button bt;
public GameObject cube;
public AudioSource source;
public AudioClip clip;
void Start () {
bt = GameObject.FindGameObjectWithTag ("Button").GetComponent<Button> ();
bt.onClick.AddListener (() => Fall ());
}
void OnCollisionEnter2D(Collision2D col) {
Destroy (col.gameObject);
Instantiate (cube,new Vector3(0f,4.19f,0f),Quaternion.identity);
}
public void Fall(){
GameObject.FindGameObjectWithTag ("Player").GetComponent<Rigidbody2D> ().isKinematic = false;
source.PlayOneShot(clip);
}
}
void OnCollisionEnter2D(Collision2D col) {
Destroy (col.gameObject);
Instantiate (cube,new Vector3(0f,4.19f,0f),Quaternion.identity);
isFalling = false; // here
}
private bool isFalling = false; // here
public void Fall()
{
GameObject.FindGameObjectWithTag ("Player").GetComponent<Rigidbody2D> ().isKinematic = false;
if(isFalling == false){
source.PlayOneShot(clip);
isFalling = true; // here
}
}
Pretty much when you press, it calls Fall, if nothing is falling down, the sound happens. On Collision, the isFalling is reset. Tho I am not entirely sure about your logic.

Categories