0

I'm new to Unity

I have multiple objects(all sharing same script) in scene and the player object(own script).

I want to implement custom listener who will inform player every time when single object do some action ( lets say some int value is 10 )

Can someone give me tip for this.

Thanks

2 Answers 2

3

I'd recommend using delegates and events. Have the event fire a function that calls a function in your player script.

(From the link)

EventManager

using UnityEngine;
using System.Collections;

public class EventManager : MonoBehaviour 
{
    public delegate void ClickAction();
    public static event ClickAction OnClicked;

    
    void OnGUI()
    {
        if(GUI.Button(new Rect(Screen.width / 2 - 50, 5, 100, 30), "Click"))
        {
            if(OnClicked != null)
                OnClicked();
        }
    }
}

TeleportScript (using the event from the EventManager)

using UnityEngine;
using System.Collections;

public class TeleportScript : MonoBehaviour 
{
    void OnEnable()
    {
        EventManager.OnClicked += Teleport;
    }
    
    
    void OnDisable()
    {
        EventManager.OnClicked -= Teleport;
    }
    
    
    void Teleport()
    {
        Vector3 pos = transform.position;
        pos.y = Random.Range(1.0f, 3.0f);
        transform.position = pos;
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for answer, I need to pass as parameter gameobject who send this event. is good practice to pass parameter in delegate and Teleport ?
Yes, should be fine.
1

You indeed want to use event so that any entity can broadcast info to any others:

public class BroadcastingEntity : MonoBehaviour
{
     public static event Action<BroadcastingEntity> RaiseLowHealth,
     protected void OnLowHealth()
     {
          if(RaiseLowHealth != null) { RaiseLowHealth(this); }
     }
     public static event Action<BroadcastingEntity> RaiseDeath,
     protected void OnDeath()
     {
          if(RaiseDeath!= null) { RaiseDeath(this); }
     }
}

then you have the actual entity:

public class Entity : BroadcastingEntity
{
    private int health = 50;
    public int Health
    {
        get{ return this.health; }
        set
        {
             this.health += value;
             if(this.health <= 0) 
             { 
                 OnDeath(this); 
                 return;
             }
             if(this.health < 10) { OnLowHealth(this); } 
        }
    }
}

finally, you'd have a centralized system to listen to that, let's say your player.

public class Player : MonoBehaviour
{
    void Start()
    {
         BroadcastingEntity.RaiseLowHealth += EntityLowHealth;
         BroadcastingEntity.RaiseDeath += EntityDeath;
    }
    void OnDestroy()
    {
         BroadcastingEntity.RaiseLowHealth -= EntityLowHealth;
         BroadcastingEntity.RaiseDeath -= EntityDeath;
    }
    private void EntityLowHealth(BroadcastingEntity entity){ }
    private void EntityDeath(BroadcastingEntity entity){ }
}

The event is static but the parameter is a reference to the entity that triggers the event. So you can print name or get some other component on it. You can do :

    private void EntityLowHealth(BroadcastingEntity entity)
    {
         print(entity.GetType());
    }

this will give the actual subtype of the entity, so you can perform all kind of actions

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.