Clear proposed point allocation (or merchant cart) on window close?

I am trying to figure out the best way to tell if a window got closed so that I can perform clean up responsibilities. For example any staged points should go back to unallocated. Or maybe I want to wipe the “cart” in a merchant shop if I close the window.

The below is the best way I found but it feels a bit hacky to rely on a component’s state to tell if the whole game object got deactivated. Is there something more reliable?

Steps
Put this on Traits Window (the child object of the UI game object)

using System;
using UnityEngine;

namespace RPG.Core
{
    // Put this code on any gameobject where you want to receive notifications if it got deactivated
    // or activated. The events fired will make the assumption that this Monobehavior will only ge
    // enabled / disabled is the object is activated / deactivated, respectively.
    // Warning: It will trigger false positives if just the component state is modified.
    public class ObjectStateNotifier : MonoBehaviour
    {
        public Action GameObjectDeactivated;
        public Action GameObjectActivated;

        private void OnEnable()
        {
            GameObjectActivated?.Invoke();
        }
        
        private void OnDisable()
        {
            GameObjectDeactivated?.Invoke();
        }
    }
}

Modify TraitUI as below

using TMPro;
using RPG.Core;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;

namespace RPG.Stats
{
    public class TraitUI : MonoBehaviour
    {
        [SerializeField] private ObjectStateNotifier traitsUIWindow;

        private void OnEnable()
        {
            traitsUIWindow.GameObjectActivated += playerTraitStore.ClearUnassignedPoints;
        }
        
        private void OnDisable()
        {
            traitsUIWindow.GameObjectActivated -= playerTraitStore.ClearUnassignedPoints;
        }        
    }
}

Add the following method to PlayerTraitStore

        public void ClearUnassignedPoints()
        {
            stagedPoints.Clear();
        }

It’s actually a bit simpler than that.

void OnDisable()
{
    playerTraitStore.ClearUnassignedPoints();
}

Thanks. I was going to “but then you have to write a unique script for every window you want to have a cleanup procedure on” But that’s probably better than the mess above.

Ok so to make sure I got this, you would create a new script (e.g. TraitWindowCleanUp) and put it on the “Traits Window” object yeah?
image

It seems wild there is no built in generalized mechanism for getting notified when an object gets deactivated. I was trying to solve that problem but it doesn’t seem worth it.

Yes. A complete script simply gets a reference to the TraitStore in Awake() and has the OnDisable() method. Put it on the Traits Window object.

OnDisable() is the generalized method for making said determination. :slight_smile:

Well… kinda sorta. :slight_smile: When I was wishing for my generalized mechanism I was referring to the gameobject not the component. OnDisable tells if you if the component got disabled not if the gameobject got deactivated. Am I wrong? It feels like the gameobject class should have an event that you can subscribe to that lets you know if it got deactivated or not.

Unfortunately, there’s nothing on GameObject directly.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms