Home > Software engineering >  Instantiated gameObject's self-written component is not working
Instantiated gameObject's self-written component is not working

Time:12-20

I'm trying to implement chest mechanic in my game. When a user touches to chest, chest disappears and heart shows up. When player touches the instantiated heart, it must disappear and add 1 to life value, but the script is not working.

Chest.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Chest : MonoBehaviour
{
    public GameObject heart;
    public GameObject _heart; //Instantiated heart.
    void OnTriggerEnter2D(Collider2D col){
        if (col.gameObject.tag == "Player"){
            Vector3 insPos = transform.position;
            _heart = Instantiate(heart,new Vector3(insPos.x,insPos.y 0.5f,insPos.z),Quaternion.identity);
            _heart.AddComponent<Heart>();
            _heart.GetComponent<Heart>().ls = GameObject.FindGameObjectWithTag("Player").GetComponent<LifeSystem>();
            Destroy(gameObject);
        }
    }
}

Heart.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Heart : MonoBehaviour
{
    public LifeSystem ls;

    void OnTriggerEnter2D(Collider2D col){
        if (col.gameObject.tag == "Player"){
            SoundManager.PlaySound("CollectCoinSound");
            ls.lifes  = 1;
            Destroy(gameObject);
        }
    }
}

I check the components of the instantiated heart when player touches the chest and I can see that life system reference is added and so heart script is.

Thanks for your time.

CodePudding user response:

You need to meet these conditions in order for OnTriggerEnter2D to be called on the spawned Hearth:

  1. At least one between Player and Hearth need to have a Rigidbody2D component
  2. Both Player and Hearth need to have a collider with IsTrigger = true
  3. Player and Hearth GameObjects need to be on two interacting layers in the collision matrix
  4. The Hearth component needs to be either on the same GameObject with a collider or on the same GameObject with the RigidBody2D

I actually simplified rules 1 and 2 a bit to show the most common use-case: if you want to know the actual rules for collisions, you can find them here (see the matrix at the bottom).

CodePudding user response:

Besides the general collision rules I would make sure your fields have the correct type in the first place and already attach the Heart component to your prefab.

Also there is no need for find .. You already know the reference to the player you are colliding with

public class Chest : MonoBehaviour
{
    public Heart heartPrefab;

    void OnTriggerEnter2D(Collider2D col)
    {
        if (col.CompareTag("Player"))
       {
            Instantiate(heart, transform.position   Vector3.up * 0.5f), Quaternion.identity);

            Destroy(gameObject);
        }
    }
}

and then simply do

public class Heart : MonoBehaviour
{
    private void OnTriggerEnter2D(Collider2D col)
    {
        if (col.TryGetComponent<LifeSystem>(out var ls))
        {
            SoundManager.PlaySound("CollectCoinSound");
            ls.lifes  = 1;
            Destroy(gameObject);
        }
    }
}

and rather have the LifeSystem attached to your player object.

In general I would kind of expect both eventually triggered at the same time since the heart might be already triggered if spawning right where the player is

  • Related