07 Nested Objects

This example shows you how to use nested objects in a blackboard.

These files can be found in the /Examples/[example] and /Blackboards/Examples folders.

NestedObjectBlackboard.cs

using System;
using CrashKonijn.Blackboard.Contracts;
using UnityEngine;

namespace CrashKonijn.BlackboardPro.Blackboards.Examples
{
    public enum GunType
    {
        Pistol,
        Rifle,
        Shotgun
    }
    
    // Make sure the class is partial and uses [Serializable] attribute
    // The IAllAreSignals interface is used to mark the class as a signal container
    // With IAllAreSignals all valid fields are signals
    [Serializable]
    public partial class Gun : IAllAreSignals
    {
        private GunType _type;
    }
    
    // Make sure the class is partial and uses [Serializable] attribute
    // The ISomeAreSignals interface is used to mark the class as a signal container
    // With ISomeAreSignals you must manually mark fields as signals
    [Serializable]
    public partial class Bullets : ISomeAreSignals
    {
        
        // This won't be generated as a signal
        // The serializefield makes sure it's saved in the editor
        [SerializeField]
        private int clipSize = 5;
        
        // You manually have to mark the field as a signal
        [Signal]
        [Blackboard.Contracts.Min(0)]
        private int inGun = 5;
        
        // This marks it as a computed signal
        [Signal]
        private static bool _isEmpty(Signals.InGun inGun) => inGun.Value <= 0;

        // Methods won't collide with generated code
        public void Shoot()
        {
            // Make sure you use the property instead of the field
            // Updating the field won't do anything
            this.InGun--;
        }

        public void Reload()
        {
            this.InGun = this.clipSize;
        }
    }
    
    public partial class NestedObjectBlackboard : BlackboardBehaviour
    {
        // This is a nested object.
        private Bullets _bullets;
        
        // This is a nested object
        private Gun _gun;
    }
}

NestedObjectBehaviour.cs

using CrashKonijn.Blackboard.Contracts;
using CrashKonijn.BlackboardPro.Blackboards.Examples;
using UnityEngine;

namespace CrashKonijn.BlackboardPro.Examples._07_nested_objects
{
    [RequireComponent(typeof(NestedObjectBlackboard))]
    public class NestedObjectBehaviour : MonoBehaviour
    {
        /* Simple hack to show a button in the editor */
        [Header("Shoots a bullet.")]
        [Button(nameof(Shoot))]
        public string shootButton;
        
        /* Simple hack to show a button in the editor */
        [Header("Reloads the gun")]
        [Button(nameof(Reload))]
        public string reloadButton;
        
        private NestedObjectBlackboard blackboard;
        public NestedObjectBlackboard Blackboard
        {
            get
            {
                if (this.blackboard == null)
                {
                    this.blackboard = this.GetComponent<NestedObjectBlackboard>();
                }

                return this.blackboard;
            }
        }

        private void OnEnable()
        {
            this.Blackboard.Bullets.InGunSignal.OnValueChanged.AddListener(this.OnBulletsChange);
        }

        private void OnDisable()
        {
            this.Blackboard.Bullets.InGunSignal.OnValueChanged.RemoveListener(this.OnBulletsChange);
        }

        private void OnBulletsChange(int bullets)
        {
            Debug.Log($"Bullets changed: {bullets}");
        }

        public void Shoot()
        {
            this.Blackboard.Bullets.Shoot();
        }

        public void Reload()
        {
            this.Blackboard.Bullets.Reload();
        }
    }
}

Last updated