Small request for change in Interactable class

MartinD

New member
Problem statement:
Currently in order to make interactable object it is required:
  1. Add Interactable component to object
  2. Add IInteractableTarget component with logic that will do the actual job
  3. Fill ID for each single prefab object
This is not a problem if same ID is used by only a few prefabs although since in case change is needed it still needs to be changed in a few places and neither compiler nor Unity will shout about it. However in case for instance pickable items where in some games there may be for instance a few hundred types of weapons (see RPG games) managing it that way may be problematic. While Interact can be easily subclassed to do such automation in code still for some reason Interactable cannot by default. I have prepared change below in order enable this capability however if possible I would like this to be merged as I suppose this may be of some use also for others.

Basically two changes I have made:

  1. Changed Awake signature from private to protected so that it can be overriden while code in Interactable.Awake() can be still executed
  2. Moved array creation to the top of the method so that they are always available. As far as I can tell if they are present but empty then it is still fine (nothing broken) but at the same time no null pointers

C#:
protected virtual void Awake()
        {
            m_InteractableTargets = new IInteractableTarget[m_Targets.Length];
            m_IKTargets = GetComponentsInChildren<AbilityIKTarget>();

            if (m_Targets == null || m_Targets.Length == 0)
            {
                Debug.LogError("Error: An IInteractableTarget must be specified in the Targets field.");
                return;
            }

            for (int i = 0; i < m_Targets.Length; ++i)
            {
                if (m_Targets[i] == null || !(m_Targets[i] is IInteractableTarget))
                {
                    Debug.LogError("Error: element " + i + " of the Targets array is null or does not subscribe to the IInteractableTarget iterface.");
                }
                else
                {
                    m_InteractableTargets[i] = m_Targets[i] as IInteractableTarget;
                }
            }

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            m_NetworkInteractable = gameObject.GetCachedComponent<INetworkInteractableMonitor>();
#endif
        }
 
Last edited:
Top