Unity3D OnTriggerEnter2D is never called - c#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PickupCoin : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Player"))
{
Destroy(this.gameObject);
Debug.Log("Coin was picked up");
}
}
}
Script is assigned to randomly spawned sprites, but player cannot interact with them, and Debug is never called. This means method is never called for reasons unknown to me.
If you need additional info I can provide it.

First, just check if the player and the created sprites have a Box Collider component.

Related

Respawn code not working in Unity, Can anyone help me?

My code doesn't work. The player is supposed to respawn when a player with the tag "Player" interacts with an object with this code. Can someone help me, thanks in advance! Code ☟
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class KillPlayerLava : MonoBehaviour
{
public int Respawn;
public float Seconds;
public MonoBehaviour script;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public IEnumerator OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Player"))
{
yield return new WaitForSeconds(Seconds);
SceneManager.LoadScene(Respawn);
script.enabled = false;
}
}
}
Here are something which might help you find the answer, the code you posted looks fine but there can be other things causing the issue.
Does your gameobject have a 2D collider?
Does one of the objects that it's colliding with have a Rigidbody2D?
Note: Trigger events are only sent if one of the Colliders also has a Rigidbody2D attached. Trigger events are sent to disabled MonoBehaviours, to allow enabling Behaviours in response to collisions.
Source docs : MonoBehaviour.OnTriggerEnter2D(Collider2D)
Does your play have the Player tag set?

Why wont the code print in Unitys console?

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
the stuff at the top is just stuff unity adds i am just adding this because my post has too much code apparently
void Update()
{
This tells it to print hi in the console
if (Input.GetKeyDown(KeyCode.Space)) ;
{
Debug.Log("hi.");
}
}
}
hmm, may be your problem is in your code, just clear the ; element
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("hi.");
}
}
The compiler will show you a red error and also in unity editor.
If you have done my instruction but still can not do it, create a gameobject in the hierarchy and drag the script you have written to the gameobject

Why in Editor type script it's never get to the break point?

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class GetPrefabs : Editor
{
public GameObject[] prefabs;
// Start is called before the first frame update
void Start()
{
prefabs = (GameObject[])Resources.LoadAll("Assets/Test/Animations/");
}
// Update is called once per frame
void Update()
{
prefabs = (GameObject[])Resources.LoadAll("Assets/Test/Animations/");
}
}
First I tried to put the script inside Assets/Test/Editor but it didn't work then I moved the script to Assets/Editor but it's not working either it's never get to the break point I put on the line in the Update or in the Start.
GetPrefabs derives from Editor. The Start() and Update() are MonoBehaviour methods (i.e. Unity looks for them if you derive from MonoBehaviour). You should look at Unity docs for the Editor class and pick appropriate methods from its list - https://docs.unity3d.com/ScriptReference/Editor.html

Calling a script from NPCs in Unity to trigger dialogue

I have followed Brackeys tutorial on Youtube (https://www.youtube.com/watch?v=_nRzoTzeyxU) on how to create a dialogue system for a game. I am currently attempting to adapt this system to where the player can walk up to an NPC and press the "Submit" button to access their dialogue, instead of clicking a button on the canvas/UI like the video shows. To those who have played games like Super Mario64, The Legend of Zelda: Ocarina of time, or most games with text dialogue you may recognize this.
The Interactable script I created detects whether the player is within the collision sphere or not that the NPC has, and allows the player to press the "Submit" button on what is supposed to call the dialogue for the NPC in range. I'm just not sure how to call the script that I named DialogueTrigger that holds the dialogue for the NPC. That, or what I'm trying to accomplish is not being accomplished in the way that I am trying. Any help would be appreciated.
Interactable Script: `
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Interactable : MonoBehaviour {
private GameObject triggeringNpc;
private bool triggering;
public DialogueTrigger Diag;
void Start()
{
}
void Update()
{
if(triggering)
{
Debug.Log("Within Range");
if (Input.GetButtonDown("Submit"))
{
Debug.Log("Pressed the Interact Button");
Diag.TriggerDialogue();
}
}
}
void OnTriggerEnter(Collider other)
{
if(other.tag == "NPC")
{
triggering = true;
triggeringNpc = other.gameObject;
}
}
void OnTriggerExit(Collider other)
{
if(other.tag == "NPC")
{
triggering = false;
triggeringNpc = null;
}
}
}
`
Right now I can put a script for one NPC in the script and it works, but I would rather it call whatever Dialogue Trigger Script that the NPC has. I'm sure there's something I'm missing here.
This one is for Dialogue Trigger
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DialogueTrigger : MonoBehaviour
{
public Dialogue dialogue;
public void TriggerDialogue ()
{
FindObjectOfType<DialogueManager>().StartDialogue(dialogue);
Debug.Log("dm called"); } else { Debug.Log("dm is null"); }
}
}
Solved this as soon as I posted it. Turns out I just needed to combine the Interactable script with the dialogue triggers script and rearranging the collision tags to hit the player that was tagged "Player" rather than having a separate script that detected collision to the NPC.

Go to next level when Key is grabbed by Player Unity 2d

I need some help with a feature I'm implementing for a game made in Unity 2D.
The player must take a key in order to unlock a door (maybe showing an animation) and when the player go in front of that door if he has the key, he will automatically go to the next level.
I need help, cause the door is not letting go to the next level.
Here is the KEY code/script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class KeyScript : MonoBehaviour {
//public AudioSource coinSoundEffect;
public AudioClip key1;
void Awake () {
//source = GetComponent<AudioSource>();
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnCollisionEnter2D (Collision2D other) {
Debug.Log("Chiave Presa");
if(other.gameObject.tag =="Player")
GameObject.Find("KeyDoor").SendMessage("HitKey");
SoundManager2D.playOneShotSound(key1);
}
}
Here is the DOOR code/script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class DoorScript : MonoBehaviour {
public bool key = false;
public string nextLevelName;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void HitKey (){
Debug.Log("La porta è sbloccata");
key = true;
Destroy (GameObject.Find ("Key"));
}
void OnCollisionEnter2D (Collision2D other){
if(other.gameObject.tag == "Player"){
if (key == true){
Application.LoadLevel(nextLevelName);
//Destroy(gameObject);
//GameObject.Find("Key").SendMessage("DestroyKey"); //If you also want to destroy the key
//GoToNextLevel ();
}
}
}
void OnTriggerEnter2D (Collision2D other)
{
Application.LoadLevel(nextLevelName);
}
public virtual void GoToNextLevel()
{
//loadingImage.SetActive(true);
Application.LoadLevel(nextLevelName);
}
}
The code works but when the player goes in front of the door, he is not passing to the next level.
Any help or hint appreciated.
Cheers
First of all, you're missing one thing:
unity is Component based engine
This means you should make interactions between Components, not GameObjects.
In your script there's a public field public bool key which should not be accessible from the outside. But if you're looking for simple and wrong answer that will work then you can just replace this line :
GameObject.Find("KeyDoor").SendMessage("HitKey");
Into this one :
GameObject.Find("KeyDoor").GetComponent<DoorScript>().key = true;
In that case you'll end up with messy code and unstable game. What I can recommend to you as an good alternative is to rewrite your logic a bit.
Instead of making a MonoBehaviour which is not needed you can just create a Component :
public class KeyComponent : Component
{
[SerializeField]
AudioClip m_KeyPickupSound;
[SerializeField]
bool m_IsPickedUp;
public bool PickedUp
{
get { return m_IsPickedUp; }
}
public void PickUp()
{
m_IsPickedUp = true;
SoundManager2D.playOneShotSound(m_KeyPickupSound);
}
}
Now attach this into your Player's Components list and in your door script do:
void OnCollisionEnter2D (Collision2D other)
{
if(other.GetComponent<KeyComponent>() != null && other.GetComponent<KeyComponent>().PickedUp)
{
SceneManager.LoadScene(2);
}
}
Now only thing left is to update your Player's MonoBehaviour and add simple collision check :
void OnCollisionEnter2D(Collision2D other)
{
if(other.tag == "TAG_FOR_KEY")
GetComponent<DoorScript>().PickUp();
}
Now you're interacting with Components and not GameObject which then require less effort changing some scripts.
First off, you should change Application.LoadLevel to SceneManager.LoadScene. The first is obsolete in the newer versions of unity.
Second you need to make sure that your scenes are actually registered in File -> BuildSettings and the parameter you pass to LoadScene matches either the index in that list or the name as string.
Make sure your player needs to have a Rigidbody2D and a Collider2D and the door has a Collider2D component
If your doors Collider2D is a trigger you must use void OnTriggerEnter2D(Collider2D other).
Another problem may be that "Level 2" isn't added to your build settings, make sure that it is added to the level's list.
Answering your last comment as it seemed the problem was that the Collider2D on the door, you can make this in a lot of ways, the easiest way is this:
Add a public string variable called nextLevelName in your Door's script, then when calling LoadLevel, use this variable. You can change the value from the inspector in each level. The problem with this is that if you rearrange the levels then you need to change the strings in each level.
The best solution in that case is this one:
int currentLevelNum = SceneManager.GetActiveScene().buildIndex;
SceneManager.LoadScene(currentLevelNum+1);
This way if you have your levels in order in your build settings you don't need to do anything else.

Categories