Some editor performance improvements

This commit is contained in:
Pascal Serrarens 2026-05-22 15:01:07 +02:00
parent ffa1581f54
commit 62bacfb1c0
7 changed files with 52 additions and 108 deletions

View File

@ -109,7 +109,7 @@ namespace NanoBrain.Unity {
public Nucleus selectedSynapseNeuron = null; public Nucleus selectedSynapseNeuron = null;
public Nucleus selectedOutput; public Nucleus selectedOutput;
public bool isOpen = true; public bool isOpen = true;
public bool initialized; public bool initialized = false;
#region Focus Graph #region Focus Graph

View File

@ -1,69 +0,0 @@
using System;
using UnityEngine;
/*
namespace NanoBrain.Unity {
/// <summary>
/// A NanoBrain which can be used to control a gameobject
/// </summary>
/// A NanoBrain is a small neural network which can be used to implement functional behaviour.
/// The network consists of neurons which are connected together with synapses.
/// The output values of the neurons are of type Vector3 to support spatial computing.
///
/// This component is basically a Unity representation of a nanobrain cluster.
/// \sa
/// - \ref NanoBrain::Cluster "Cluster"
/// - \ref NanoBrain::Neuron "Neuron"
[HelpURL("https://passer.life/documentation/nanobrain/Documentation/html/class_nano_brain_1_1_unity_1_1_brain.html")]
public class Brain : MonoBehaviour {
/// <summary>
/// The Cluster prefab from which the cluster is created
/// </summary>
public ClusterPrefab brainPrefab;
[NonSerialized]
private Cluster brainInstance;
/// <summary>
/// The cluster isntance
/// </summary>
public Cluster brain {
get {
if (brainInstance == null && brainPrefab != null) {
brainInstance = new Cluster(brainPrefab) {
name = brainPrefab.name
};
} else if (brainInstance != null && brainPrefab == null) {
brainInstance = null;
}
return brainInstance;
}
}
// public Cluster InitializeBrain() {
// brainInstance = new Cluster(brainPrefab) {
// name = brainPrefab.name
// };
// return brainInstance;
// }
/// <summary>
/// Update the weight for all Synapses coming from the Neuron with the given name
/// </summary>
/// <param name="brain">The cluster in which the synapses are updated</param>
/// <param name="name">The name of the Neuron for which the weights are updated</param>
/// <param name="weight">The new Synapse weight</param>
public static void UpdateWeight(Cluster brain, string name, float weight) {
Neuron root = brain.defaultOutput;
foreach (Synapse synapse in root.synapses) {
if (synapse.neuron.name == name) {
if (synapse.weight != weight) {
synapse.weight = weight;
// Debug.Log($"Updated weight for {name}");
}
}
}
}
}
}
*/

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 92f34a5e4027a1dc39efd8ce63cf6aba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -24,6 +24,9 @@ namespace NanoBrain {
/// Cluster should always be created from prefabs /// Cluster should always be created from prefabs
public ClusterPrefab prefab; public ClusterPrefab prefab;
//[HideInInspector]
public int version;
/// <summary> /// <summary>
/// The base name of the cluster. I don't think this is actively used at this moment /// The base name of the cluster. I don't think this is actively used at this moment
/// </summary> /// </summary>
@ -44,6 +47,7 @@ namespace NanoBrain {
/// The value instanceCount determines how many instances will be present at runtime. /// The value instanceCount determines how many instances will be present at runtime.
//[NonSerialized] //[NonSerialized]
[SerializeReference] [SerializeReference]
[HideInInspector]
public Cluster[] instances; public Cluster[] instances;
/// <summary> /// <summary>
@ -63,6 +67,7 @@ namespace NanoBrain {
/// All nuclei in this cluster /// All nuclei in this cluster
/// </summary> /// </summary>
[SerializeReference] [SerializeReference]
[HideInInspector]
public List<Nucleus> nuclei = new(); public List<Nucleus> nuclei = new();
// the nuclei sorted using topological sorting // the nuclei sorted using topological sorting
// to ensure that the cluster is computer in the right order // to ensure that the cluster is computer in the right order
@ -78,6 +83,7 @@ namespace NanoBrain {
/// <param name="parent">The cluster in which this new cluster will be placed</param> /// <param name="parent">The cluster in which this new cluster will be placed</param>
public Cluster(ClusterPrefab prefab, Cluster parent) { public Cluster(ClusterPrefab prefab, Cluster parent) {
this.prefab = prefab; this.prefab = prefab;
this.version = prefab.version;
this.name = prefab.name; this.name = prefab.name;
this.parent = parent; this.parent = parent;
@ -94,6 +100,7 @@ namespace NanoBrain {
/// <param name="parent">The prefab in which the new copy is placed</param> /// <param name="parent">The prefab in which the new copy is placed</param>
public Cluster(ClusterPrefab prefab, ClusterPrefab parent = null) { public Cluster(ClusterPrefab prefab, ClusterPrefab parent = null) {
this.prefab = prefab; this.prefab = prefab;
this.version = prefab.version;
this.name = prefab.name; this.name = prefab.name;
if (parent != null) if (parent != null)
this.parent = parent.cluster; this.parent = parent.cluster;
@ -109,11 +116,10 @@ namespace NanoBrain {
/// Strange that this does not take any parameters or return values. /// Strange that this does not take any parameters or return values.
/// Where which the clone be found??? /// Where which the clone be found???
private void ClonePrefab() { private void ClonePrefab() {
this.name += " " + Time.time; //Debug.Log($"Clone Prefab {this.prefab.name} -> {this.name}");
Debug.Log($"Clone Prefab {this.prefab.name} -> {this.name}");
if (this.prefab == null || this.prefab.cluster == null || this.prefab.cluster.nuclei == null) if (this.prefab == null || this.prefab.cluster == null || this.prefab.cluster.nuclei == null)
return; return;
Nucleus[] prefabNuclei = this.prefab.cluster.nuclei.ToArray(); Nucleus[] prefabNuclei = this.prefab.cluster.nuclei.ToArray();
// first clone the nuclei without their connections // first clone the nuclei without their connections
@ -168,35 +174,34 @@ namespace NanoBrain {
} }
//if (Application.isPlaying) { //if (Application.isPlaying) {
// Only create cluster siblings at runtime // Only create cluster siblings at runtime
foreach (Nucleus clonedNucleus in clonedNuclei) { foreach (Nucleus clonedNucleus in clonedNuclei) {
if (clonedNucleus is not Cluster clonedCluster) if (clonedNucleus is not Cluster clonedCluster)
continue; continue;
List<Cluster> siblings = new() { List<Cluster> siblings = new() {
clonedCluster clonedCluster
}; };
for (int instanceIx = 1; instanceIx < clonedCluster.instanceCount; instanceIx++) { for (int instanceIx = 1; instanceIx < clonedCluster.instanceCount; instanceIx++) {
// Create another sibling // Create another sibling
Cluster sibling = new(clonedCluster.prefab, this) { Cluster sibling = new(clonedCluster.prefab, this) {
name = $"{clonedCluster.baseName}: {instanceIx} [{Time.time}]", name = $"{clonedCluster.baseName}: {instanceIx}",
parent = this.parent, parent = this.parent,
instanceCount = this.instanceCount, instanceCount = this.instanceCount,
}; };
Debug.Log($"create {clonedCluster.prefab.name} sibling: {sibling.name}"); siblings.Add(sibling);
siblings.Add(sibling); CopyAllExternalReceivers(clonedCluster, sibling, clonedCluster.prefab, this);
CopyAllExternalReceivers(clonedCluster, sibling, clonedCluster.prefab, this);
}
Cluster[] siblingClusters = siblings.ToArray();
foreach (Cluster sibling in siblings)
sibling.instances = siblingClusters;
} }
Cluster[] siblingClusters = siblings.ToArray();
foreach (Cluster sibling in siblings)
sibling.instances = siblingClusters;
}
// Ensure that all neurons are computed to initialize bias // Ensure that all neurons are computed to initialize bias
foreach (Nucleus clonedNucleus in clonedNuclei) { foreach (Nucleus clonedNucleus in clonedNuclei) {
if (clonedNucleus is not Cluster) if (clonedNucleus is not Cluster)
clonedNucleus.UpdateStateIsolated(); clonedNucleus.UpdateStateIsolated();
} }
//} //}
} }

View File

@ -42,6 +42,7 @@ namespace NanoBrain {
/// </summary> /// </summary>
/// The bias which a value which is always added to the combined value of the neuron /// The bias which a value which is always added to the combined value of the neuron
/// It does not have a synapse and therefore no weight of source nucleus /// It does not have a synapse and therefore no weight of source nucleus
[HideInInspector]
public Vector3 bias = Vector3.zero; public Vector3 bias = Vector3.zero;
#region Synapses #region Synapses
@ -111,6 +112,7 @@ namespace NanoBrain {
/// <summary> /// <summary>
/// The type of combinator used for this Neuron /// The type of combinator used for this Neuron
/// </summary> /// </summary>
[HideInInspector]
public CombinatorType combinator = CombinatorType.Sum; public CombinatorType combinator = CombinatorType.Sum;
/// <summary> /// <summary>
@ -130,6 +132,7 @@ namespace NanoBrain {
/// The activation function /// The activation function
/// </summary> /// </summary>
[SerializeField] [SerializeField]
[HideInInspector]
public ActivationType _activator; public ActivationType _activator;
/// <summary> /// <summary>
/// The activation funtion /// The activation funtion
@ -144,10 +147,12 @@ namespace NanoBrain {
/// <summary> /// <summary>
/// The curve representing the activation function /// The curve representing the activation function
/// </summary> /// </summary>
[HideInInspector]
public AnimationCurve curve; public AnimationCurve curve;
/// <summary> /// <summary>
/// The maximum value of the curve /// The maximum value of the curve
/// </summary> /// </summary>
[HideInInspector]
public float curveMax = 1.0f; public float curveMax = 1.0f;
/// <summary> /// <summary>
@ -287,6 +292,7 @@ namespace NanoBrain {
/// <summary> /// <summary>
/// The output value of the neuron /// The output value of the neuron
/// </summary> /// </summary>
[HideInInspector]
protected float3 _outputValue; protected float3 _outputValue;
/// <summary> /// <summary>
/// The output value of the neuron /// The output value of the neuron
@ -369,6 +375,7 @@ namespace NanoBrain {
/// <summary> /// <summary>
/// The time at which the last update has been done /// The time at which the last update has been done
/// </summary> /// </summary>
[HideInInspector]
public float lastUpdate = 0; public float lastUpdate = 0;
/// <summary> /// <summary>
/// Time in seconds after the last update the neuron can go to sleep /// Time in seconds after the last update the neuron can go to sleep
@ -737,6 +744,7 @@ namespace NanoBrain {
/// The nuclei which have a synapse to this neuron /// The nuclei which have a synapse to this neuron
/// </summary> /// </summary>
[SerializeReference] [SerializeReference]
[HideInInspector]
private List<Nucleus> _receivers = new(); private List<Nucleus> _receivers = new();
/// <summary> /// <summary>
/// The nuclei which have a synapse to this neuron /// The nuclei which have a synapse to this neuron

View File

@ -14,12 +14,14 @@ namespace NanoBrain {
/// <summary> /// <summary>
/// The name of the Nucleus /// The name of the Nucleus
/// </summary> /// </summary>
[HideInInspector]
public string name; public string name;
/// <summary> /// <summary>
/// The cluster instance in which the nucleus is located /// The cluster instance in which the nucleus is located
/// </summary> /// </summary>
[SerializeReference] [SerializeReference]
[HideInInspector]
public Cluster parent; public Cluster parent;
/// <summary> /// <summary>

View File

@ -14,6 +14,9 @@ namespace NanoBrain.Unity {
/// </summary> /// </summary>
public Cluster cluster; public Cluster cluster;
//[HideInInspector]
public int version;
/// <summary> /// <summary>
/// Retrieve a nucleus in this cluster /// Retrieve a nucleus in this cluster
/// </summary> /// </summary>
@ -36,6 +39,12 @@ namespace NanoBrain.Unity {
new Neuron(this.cluster, "Output"); // Every cluster should have at least 1 neuron new Neuron(this.cluster, "Output"); // Every cluster should have at least 1 neuron
this.cluster.instanceCount = 1; this.cluster.instanceCount = 1;
} }
#if UNITY_EDITOR
private void OnValidate() {
version++;
}
#endif
} }
} }