diff --git a/Cluster.cs b/Cluster.cs index a2bc161..315d2f8 100644 --- a/Cluster.cs +++ b/Cluster.cs @@ -38,39 +38,45 @@ public class Cluster : Nucleus { private void ClonePrefab() { Nucleus[] prefabNuclei = this.prefab.nuclei.ToArray(); // first clone the nuclei without their connections - foreach (Nucleus nucleus in this.prefab.nuclei) + foreach (Nucleus nucleus in this.prefab.nuclei) { + Debug.Log($"prefab clone {nucleus.name}"); nucleus.ShallowCloneTo(this); + } + Debug.Log(" complete"); Nucleus[] clonedNuclei = this.clusterNuclei.ToArray(); // Now clone the connections for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) { Nucleus prefabNucleus = prefabNuclei[nucleusIx]; - Nucleus clonedReceptor = clonedNuclei[nucleusIx]; - if (clonedReceptor == null) + if (prefabNucleus is not Neuron prefabNeuron) + continue; + + Nucleus clonedNucleus = clonedNuclei[nucleusIx]; + if (clonedNucleus == null || clonedNucleus is not Neuron clonedNeuron) continue; // Copy the receivers, which will also create the synapses // Clusters do not have receivers... - // foreach (Nucleus receiver in prefabNucleus.receivers) { - // int ix = GetNucleusIndex(prefabNuclei, receiver); - // if (ix < 0) - // continue; + foreach (Nucleus receiver in prefabNeuron.receivers) { + int ix = GetNucleusIndex(prefabNuclei, receiver); + if (ix < 0) + continue; - // if (clonedNuclei[ix] is not Nucleus clonedReceiver) - // continue; + if (clonedNuclei[ix] is not Nucleus clonedReceiver) + continue; - // // Find the synapse for the weight - // float weight = 1; - // foreach (Synapse synapse in receiver.synapses) { - // // Find the weight for this synapse - // if (synapse.nucleus == prefabNucleus) { - // weight = synapse.weight; - // break; - // } - // } + // Find the synapse for the weight + float weight = 1; + foreach (Synapse synapse in receiver.synapses) { + // Find the weight for this synapse + if (synapse.nucleus == prefabNucleus) { + weight = synapse.weight; + break; + } + } - // clonedReceptor.AddReceiver(clonedReceiver, weight); - // } + clonedNeuron.AddReceiver(clonedReceiver, weight); + } } // Copy nucleus arrays @@ -180,9 +186,50 @@ public class Cluster : Nucleus { name = this.name, clusterPrefab = this.clusterPrefab, }; + // This cloned the prefab with the clusternuclei, + // but did not clone the receivers outside the cluster + RestoreExternalReceivers(clone, this.clusterPrefab, parent); + return clone; } + protected void RestoreExternalReceivers(Cluster clone, ClusterPrefab prefabParent, Cluster clonedParent) { + for (int nucleusIx = 0; nucleusIx < this.clusterNuclei.Count; nucleusIx++) { + Nucleus prefabNucleus = this.clusterNuclei[nucleusIx]; + if (prefabNucleus is not Neuron prefabNeuron) + continue; + + Nucleus clonedNucleus = clone.clusterNuclei[nucleusIx]; + if (clonedNucleus == null || clonedNucleus is not Neuron clonedNeuron) + continue; + + // Copy the receivers, which will also create the synapses + foreach (Nucleus receiver in prefabNeuron.receivers) { + int ix = GetNucleusIndex(prefabParent.nuclei, receiver); + if (ix < 0) + continue; + + //if (clone.clusterNuclei[ix] is not Nucleus clonedReceiver) + if (clonedParent.clusterNuclei[ix] is not Nucleus clonedReceiver) + continue; + + // Find the synapse for the weight + float weight = 1; + foreach (Synapse synapse in receiver.synapses) { + // Find the weight for this synapse + if (synapse.nucleus == prefabNucleus) { + weight = synapse.weight; + break; + } + } + + clonedNeuron.AddReceiver(clonedReceiver, weight); + } + } + + + } + protected int GetNucleusIndex(Nucleus[] nuclei, Nucleus nucleus) { for (int i = 0; i < nuclei.Length; i++) { if (nucleus == nuclei[i]) diff --git a/ClusterPrefab.cs b/ClusterPrefab.cs index ada3553..90db0db 100644 --- a/ClusterPrefab.cs +++ b/ClusterPrefab.cs @@ -114,4 +114,4 @@ public class ClusterPrefab : ScriptableObject { } return -1; } -} \ No newline at end of file +} diff --git a/ClusterReceptor.cs b/ClusterReceptor.cs index 8e13779..8b409bc 100644 --- a/ClusterReceptor.cs +++ b/ClusterReceptor.cs @@ -20,6 +20,11 @@ public class ClusterReceptor : Cluster, IReceptor { clusterPrefab = this.clusterPrefab, array = this.array }; + + // This cloned the prefab with the clusternuclei, + // but did not clone the receivers outside the cluster + RestoreExternalReceivers(clone, this.clusterPrefab, parent); + return clone; } @@ -44,7 +49,7 @@ public class ClusterReceptor : Cluster, IReceptor { continue; foreach (Nucleus receiver in output.receivers) - clonedOutput.AddReceiver(receiver); + clonedOutput.AddReceiver(receiver); } return clone; } diff --git a/Editor/NanoBrain_Editor.cs b/Editor/NanoBrain_Editor.cs index 376e9f0..4dcb4c5 100644 --- a/Editor/NanoBrain_Editor.cs +++ b/Editor/NanoBrain_Editor.cs @@ -36,7 +36,8 @@ public class NanoBrainComponent_Editor : Editor { root.Add(brainField); } - ClusterInspector.CreateInspector(root, brain.prefab, brain.defaultOutput, component.gameObject); + if (brain != null) + ClusterInspector.CreateInspector(root, brain.prefab, brain.defaultOutput, component.gameObject); if (Application.isPlaying == false) serializedObject.ApplyModifiedProperties();