I have a simple script which I can drag onto any GameObject to get control over OnPointerEnter/Exit behavior for it:
using UnityEngine;
using UnityEngine.EventSystems;
public class OnPointerEnterExitBehavior : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler {
bool inContext;
GameObject myGO;
private void Awake() {
myGO = gameObject;
}
void Update() {
if (Input.GetMouseButtonDown(0) && !inContext) {
myGO.SetActive(inContext);
GameObject.Destroy(gameObject);
}
}
public void OnPointerEnter(PointerEventData eventData) {
inContext = true;
}
public void OnPointerExit(PointerEventData eventData) {
inContext = false;
}
}
In that script it will simply destroy the item if you click outside it (eg. for a menu).
I also have a script for creating a menu programmatically from instantiation of a prefab which would most simply be:
public class GenerateAndOpenVenueMenu : MonoBehaviour
{
public Canvas ParentCanvas;
public void GenerateAndOpenVenuMenu() {
GameObject newMenu = Instantiate(Resources.Load<GameObject>("MENU WINDOW")) as GameObject;
newMenu.transform.SetParent(ParentCanvas.transform, false);
newMenu.SetActive(true);
}
}
I can control OnPointerEnter/Exit behavior by dragging the first script onto the prefab “MENU WINDOW” so it’s built into the prefab. But then if I want different OnPointerEnter/Exit behaviors for different menus this is less ideal.
I am wondering if there is some way to write the first script’s code into the second script so that I can handwrite in the second script what the OnPointerEnter/Exit behaviors should be for the GameObject “newMenu”.
Thanks again. I understand I can add the existing static script that way. But that is just as you said a “predefined method.” I would then have to create many of those “OnPointerEnterExitBehavior” scripts (one for each menu) if I want different behaviors on different menus.
What I am trying to do is what you described in the second sentence: “make it configurable by using delegates and events instead of predefined methods.”
How would I change the second script I posted (the one where the menu is instantiated) to add capacity to control what happens to the menu object when the mouse is over or not? I am not sure how to do this.
ie. I want to get rid of the first script completely and re-write the essence into the second script so I have control over what happens there.
Be aware that C# events do not serialize (if you care about serialization), and if you want them to serialize or configure in editor, you’d need to use UnityEvents instead and AddListener interface.
Wow C# is interesting. I didn’t know you could do that. I understood enough from that to get it working.
For the first script I wrote:
using UnityEngine;
using UnityEngine.EventSystems;
public class OnPointerEnterExitBehavior : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler {
bool inContext;
GameObject myGO;
public event System.Action OnExit;
private void Awake() {
myGO = gameObject;
}
void Update() {
if (Input.GetMouseButtonDown(0) && !inContext) {
OnExit.Invoke();
}
}
public void OnPointerEnter(PointerEventData eventData) {
inContext = true;
}
public void OnPointerExit(PointerEventData eventData) {
inContext = false;
}
}
And for the second script:
public class GenerateAndOpenVenueMenu : MonoBehaviour
{
public Canvas ParentCanvas;
public void GenerateAndOpenVenuMenu() {
GameObject newMenu = Instantiate(Resources.Load<GameObject>("MENU WINDOW")) as GameObject;
newMenu.transform.SetParent(ParentCanvas.transform, false);
newMenu.SetActive(true);
newMenu.GetComponent<OnPointerEnterExitBehavior>().OnExit +=()=> {
GameObject.Destroy(gameObject);
}
}
}
And this works. So what I understand is that “newMenu.GetComponent().OnExit +=()=> {” is creating a lambda event handler on the fly. Then I can specify anything I want there.
The “OnPointerEnterExitBehavior” class thus becomes a generic one I can leave as part of the prefab and customize the behavior of on each menu made from it nicely.
Generic has a specific meaning in C#, and your class isn’t it. You can read more about generic classes and function on microsoft docs or in books about C#.[/QUOTE]