diff --git a/Assets/NanoBrain/Cluster.cs b/Assets/NanoBrain/Cluster.cs index 079279c..85d3214 100644 --- a/Assets/NanoBrain/Cluster.cs +++ b/Assets/NanoBrain/Cluster.cs @@ -10,6 +10,7 @@ public class Cluster : ScriptableObject, INucleus { [SerializeReference] public List nuclei = new(); + public List subClusters = new(); public INucleus output => this.nuclei[0] as INucleus; @@ -33,6 +34,18 @@ public class Cluster : ScriptableObject, INucleus { public NucleusArray array { get; set; } + public List receivers { + get { return this.output.receivers; } + set { this.output.receivers = value; } + } + public List clusterReceivers { + get { return this.output.clusterReceivers; } + set { this.output.clusterReceivers = clusterReceivers; } + } + public IEnumerable allReceivers { + get => output.allReceivers; + } + public INucleus Clone() { Cluster clone = CreateInstance(); // Lots to add here... @@ -48,19 +61,27 @@ public class Cluster : ScriptableObject, INucleus { new Neuron(this, "Output"); // Every cluster should have at least 1 neuron } - public void AddReceiver(INucleus receiver) { - output.AddReceiver(receiver); + public void AddReceiver(INucleus receivingNucleus) { + //output.AddReceiver(receiver); + this.output.receivers.Add(receivingNucleus); + receivingNucleus.AddClusterSynapse(this); + } + public void AddClusterReceiver(Cluster clusterReceiver) { + this.output.clusterReceivers.Add(clusterReceiver); + clusterReceiver.AddClusterSynapse(this); } public void RemoveReceiver(INucleus receiver) { output.RemoveReceiver(receiver); } - public List receivers { - get => output.receivers; - } public Synapse AddSynapse(IReceptor sender) { - Synapse synapse = new(sender, 1.0f); + Synapse synapse = new(sender); + synapses.Add(synapse); + return synapse; + } + public Synapse AddClusterSynapse(Cluster sender) { + Synapse synapse = new(sender); synapses.Add(synapse); return synapse; } @@ -89,9 +110,9 @@ public class Cluster : ScriptableObject, INucleus { } nucleus.synapses.RemoveAll(synapse => visitedSynapses.Contains(synapse) == false); } - if (nucleus.receivers != null) { + if (nucleus.allReceivers != null) { HashSet visitedReceivers = new(); - foreach (INucleus receiver in nucleus.receivers) { + foreach (INucleus receiver in nucleus.allReceivers) { if (receiver != null && receiver != null) { visitedReceivers.Add(receiver); visitedNuclei.Add(receiver); diff --git a/Assets/NanoBrain/INucleus.cs b/Assets/NanoBrain/INucleus.cs index 3ff6947..19938ed 100644 --- a/Assets/NanoBrain/INucleus.cs +++ b/Assets/NanoBrain/INucleus.cs @@ -1,7 +1,4 @@ using System.Collections.Generic; -using UnityEngine; -using Unity.Burst; -using Unity.Collections; using Unity.Mathematics; public interface INucleus : IReceptor { @@ -14,6 +11,7 @@ public interface INucleus : IReceptor { // Senders public List synapses { get; } public Synapse AddSynapse(IReceptor sender); + public Synapse AddClusterSynapse(Cluster clusterSender); public NucleusArray array { get; set; } @@ -35,8 +33,12 @@ public interface IReceptor { public string name { get; set; } // Receivers - public List receivers { get; } + public List receivers { get; set; } + public List clusterReceivers { get; set; } + public IEnumerable allReceivers { get; } + public void AddReceiver(INucleus receiver); + public void AddClusterReceiver(Cluster clusterReceiver); public void RemoveReceiver(INucleus receiverNucleus); #endregion static diff --git a/Assets/NanoBrain/Identity.asset b/Assets/NanoBrain/Identity.asset new file mode 100644 index 0000000..3d62c75 --- /dev/null +++ b/Assets/NanoBrain/Identity.asset @@ -0,0 +1,60 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 60a957541c24c57e78018c202ebb1d9b, type: 3} + m_Name: Identity + m_EditorClassIdentifier: Assembly-CSharp::Cluster + nuclei: + - rid: 2243601242842202169 + references: + version: 2 + RefIds: + - rid: 2243601242842202169 + type: {class: Neuron, ns: , asm: Assembly-CSharp} + data: + _name: Output + _synapses: [] + _receivers: [] + _array: + rid: 2243601242842202170 + _curvePreset: 0 + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + - serializedVersion: 3 + time: 1000 + value: 1000 + inSlope: 1 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + curveMax: 1 + average: 0 + - rid: 2243601242842202170 + type: {class: NucleusArray, ns: , asm: Assembly-CSharp} + data: + nuclei: + - rid: 2243601242842202169 + name: Output diff --git a/Assets/NanoBrain/Identity.asset.meta b/Assets/NanoBrain/Identity.asset.meta new file mode 100644 index 0000000..b2382a6 --- /dev/null +++ b/Assets/NanoBrain/Identity.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5f4d2ea0d0115b3549f8e9aa5e669163 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NanoBrain/Neuron.cs b/Assets/NanoBrain/Neuron.cs index 67fed76..2d5d5aa 100644 --- a/Assets/NanoBrain/Neuron.cs +++ b/Assets/NanoBrain/Neuron.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using UnityEngine; using Unity.Mathematics; using static Unity.Mathematics.math; @@ -20,7 +21,25 @@ public class Neuron : INucleus { [SerializeReference] private List _receivers = new(); - public List receivers => _receivers; + public List receivers { + get { return _receivers; } + set { _receivers = value; } + } + private List _clusterReceivers = new(); + public List clusterReceivers { + get { return _clusterReceivers; } + set { _clusterReceivers = value; } + } + public IEnumerable allReceivers { //=> _receivers.Concat(_clusterReceivers); + get { + if (_receivers == null) + return _clusterReceivers; + else if (_clusterReceivers == null) + return _receivers; + else + return _receivers.Concat(_clusterReceivers); + } + } [SerializeReference] private NucleusArray _array; @@ -133,28 +152,32 @@ public class Neuron : INucleus { Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus); clonedSynapse.weight = synapse.weight; } - foreach (INucleus receiver in this.receivers) { + foreach (INucleus receiver in this.allReceivers) { clone.AddReceiver(receiver); } return clone; } public virtual void AddReceiver(INucleus receivingNucleus) { - this.receivers.Add(receivingNucleus); + this._receivers.Add(receivingNucleus); receivingNucleus.AddSynapse(this); } + public void AddClusterReceiver(Cluster receivingCluster) { + this._clusterReceivers.Add(receivingCluster); + receivingCluster.AddSynapse(this); + } public void RemoveReceiver(INucleus receiverNucleus) { - this.receivers.RemoveAll(receiver => receiver == receiverNucleus); + this._receivers.RemoveAll(receiver => receiver == receiverNucleus); receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this); } public static void Delete(INucleus nucleus) { foreach (Synapse synapse in nucleus.synapses) { if (synapse.nucleus is Neuron synapse_nucleus) { - if (synapse_nucleus.receivers.Count > 1) { + if (synapse_nucleus._receivers.Count > 1) { // there is another nucleus feeding into this input nucleus - synapse_nucleus.receivers.RemoveAll(r => r == nucleus); + synapse_nucleus._receivers.RemoveAll(r => r == nucleus); } else { // No other links, delete it. @@ -162,7 +185,7 @@ public class Neuron : INucleus { } } } - foreach (INucleus receiver in nucleus.receivers) { + foreach (INucleus receiver in nucleus.allReceivers) { if (receiver != null && receiver.synapses != null) receiver.synapses.RemoveAll(s => s.nucleus == nucleus); } @@ -174,7 +197,12 @@ public class Neuron : INucleus { } public Synapse AddSynapse(IReceptor sendingNucleus) { - Synapse synapse = new(sendingNucleus, 1.0f); + Synapse synapse = new(sendingNucleus); + this.synapses.Add(synapse); + return synapse; + } + public Synapse AddClusterSynapse(Cluster sendingCluster) { + Synapse synapse = new(sendingCluster); this.synapses.Add(synapse); return synapse; } @@ -222,7 +250,7 @@ public class Neuron : INucleus { // } this.outputValue = result; - foreach (INucleus receiver in this.receivers) + foreach (INucleus receiver in this.allReceivers) receiver.UpdateState(); } diff --git a/Assets/NanoBrain/NucleusArray.cs b/Assets/NanoBrain/NucleusArray.cs index 27f8194..426aac9 100644 --- a/Assets/NanoBrain/NucleusArray.cs +++ b/Assets/NanoBrain/NucleusArray.cs @@ -5,6 +5,7 @@ using UnityEngine; public class NucleusArray { [SerializeReference] public INucleus[] nuclei; + public Cluster[] clusters; public string name; public NucleusArray(INucleus nucleus) { diff --git a/Assets/NanoBrain/Receptor.cs b/Assets/NanoBrain/Receptor.cs index 1a3a0af..cd3bdbf 100644 --- a/Assets/NanoBrain/Receptor.cs +++ b/Assets/NanoBrain/Receptor.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Collections.Generic; using UnityEngine; using Unity.Mathematics; @@ -25,17 +26,30 @@ public class Receptor : IReceptor { [SerializeReference] private List _receivers = new(); - public List receivers => _receivers; + public List receivers { + get { return _receivers; } + set { _receivers = value; } + } + private List _clusterReceivers = new(); + public List clusterReceivers { + get { return _clusterReceivers; } + set { _clusterReceivers = value; } + } + public IEnumerable allReceivers => _receivers.Concat(_clusterReceivers); protected int[] thingIds; // every receiver can handle a thing with this id public virtual void AddReceiver(INucleus receivingNucleus) { - this.receivers.Add(receivingNucleus); + this._receivers.Add(receivingNucleus); receivingNucleus.AddSynapse(this); } + public void AddClusterReceiver(Cluster receivingCluster) { + this._clusterReceivers.Add(receivingCluster); + receivingCluster.AddSynapse(this); + } public void RemoveReceiver(INucleus receiverNucleus) { - this.receivers.RemoveAll(receiver => receiver == receiverNucleus); + this._receivers.RemoveAll(receiver => receiver == receiverNucleus); receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this); } @@ -88,7 +102,7 @@ public class Receptor : IReceptor { receptor.AddReceiver(nucleus); } } - if (receptor.receivers.Count == 0) + if (receptor._receivers.Count == 0) return null; else return receptor; @@ -97,12 +111,12 @@ public class Receptor : IReceptor { public virtual void ProcessStimulus(int thingId, Vector3 newLocalPositionVector, string thingName = null) { this.localPosition = newLocalPositionVector; - thingIds ??= new int[this.receivers.Count]; + thingIds ??= new int[this._receivers.Count]; int receiverIx = 0; INucleus selectedReceiver = null; int selectedReceiverIx = 0; - foreach (INucleus receiver in this.receivers) { + foreach (INucleus receiver in this.allReceivers) { // selectedReceiver = receiver; // receiverIx++; diff --git a/Assets/NanoBrain/Synapse.cs b/Assets/NanoBrain/Synapse.cs index ef42fb5..9f4b1d5 100644 --- a/Assets/NanoBrain/Synapse.cs +++ b/Assets/NanoBrain/Synapse.cs @@ -4,12 +4,16 @@ using UnityEditor; [Serializable] public class Synapse { - //[NonSerialized] - [SerializeReference] - public IReceptor nucleus; + // Support access to cluster of basic nucleus + public IReceptor nucleus => clusterNucleus != null ? clusterNucleus : basicNucleus; + [SerializeReference] + private IReceptor basicNucleus; + // The Cluster is a ScriptableObject and can therefore not be serialized using [SerializeReference] + private Cluster clusterNucleus; + public Cluster cluster; - //public int nucleusId; + public float weight; public enum CurvePresets { @@ -19,55 +23,16 @@ public class Synapse { Reciprocal, Custom } - // public CurvePresets curvePreset; - // public AnimationCurve curve; public float curveMax = 1.0f; - public Synapse(IReceptor nucleus, float weight) { - this.nucleus = nucleus; - //this.nucleusId = nucleus.id; + public Synapse(IReceptor nucleus, float weight = 1.0f) { + this.basicNucleus = nucleus; + this.weight = weight; + } + public Synapse(Cluster cluster, float weight = 1.0f) { + this.clusterNucleus = cluster; this.weight = weight; } - - // public void Rebuild(NanoBrain brain) { - // // if (brain == null) { - // // return; - // // } - - // // foreach (Nucleus nucleus in brain.nuclei) { - // // if (nucleus.id == this.nucleusId) { - // // this.nucleus = nucleus; - // // return; - // // } - // // } - // // foreach (Perceptoid perceptoid in brain.perceptei) { - // // if (perceptoid.id == this.nucleusId) { - // // this.nucleus = perceptoid; - // // return; - // // } - // // } - // // Debug.LogError($"Synapse deserialization error: could not find nucleus with id {this.nucleusId}"); - // } - - // public AnimationCurve GenerateCurve() { - // switch (this.curvePreset) { - // case CurvePresets.Linear: - // this.curveMax = this.weight; - // return Presets.Linear(this.weight); - // case CurvePresets.Power: - // this.curveMax = this.weight; - // return Presets.Power(2.0f, this.weight); - // case CurvePresets.Sqrt: - // this.curveMax = this.weight; - // return Presets.Power(0.5f, this.weight); - // case CurvePresets.Reciprocal: - // this.curveMax = 1 / 0.01f * this.weight; - // return Presets.Reciprocal(this.weight); - // default: - // this.curveMax = weight; - // return AnimationCurve.Constant(0, 1, weight); - // } - // } public static class Presets { private const int samples = 32; diff --git a/Assets/NanoBrain/VisualEditor/Editor/BrainPickerWindow.cs b/Assets/NanoBrain/VisualEditor/Editor/BrainPickerWindow.cs index 6e7a849..66ef404 100644 --- a/Assets/NanoBrain/VisualEditor/Editor/BrainPickerWindow.cs +++ b/Assets/NanoBrain/VisualEditor/Editor/BrainPickerWindow.cs @@ -3,15 +3,13 @@ using UnityEngine; using System; using System.Linq; -public class BrainPickerWindow : EditorWindow -{ +public class BrainPickerWindow : EditorWindow { private Vector2 scroll; private Cluster[] items = new Cluster[0]; private Action onPicked; private string search = ""; - public static void ShowPicker(Action onPicked, string title = "Select NanoBrain") - { + public static void ShowPicker(Action onPicked, string title = "Select Cluster") { var w = CreateInstance(); w.titleContent = new GUIContent(title); w.minSize = new Vector2(360, 320); @@ -22,9 +20,8 @@ public class BrainPickerWindow : EditorWindow private void OnEnable() => RefreshList(); - private void RefreshList() - { - var guids = AssetDatabase.FindAssets("t:NanoBrain"); + private void RefreshList() { + var guids = AssetDatabase.FindAssets("t:Cluster"); items = guids .Select(g => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(g))) .Where(b => b != null) @@ -32,11 +29,10 @@ public class BrainPickerWindow : EditorWindow .ToArray(); } - private void OnGUI() - { + private void OnGUI() { EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); - EditorGUILayout.LabelField("Choose NanoBrain:", EditorStyles.boldLabel); + EditorGUILayout.LabelField("Choose Cluster:", EditorStyles.boldLabel); if (GUILayout.Button("Refresh", GUILayout.Width(80))) RefreshList(); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); @@ -46,15 +42,13 @@ public class BrainPickerWindow : EditorWindow EditorGUILayout.Space(); scroll = EditorGUILayout.BeginScrollView(scroll); - foreach (var it in items) - { + foreach (var it in items) { if (!string.IsNullOrEmpty(search) && it.name.IndexOf(search, StringComparison.OrdinalIgnoreCase) < 0) continue; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(EditorGUIUtility.ObjectContent(it, typeof(Cluster)), GUILayout.Height(20)); - if (GUILayout.Button("Select", GUILayout.Width(70))) - { + if (GUILayout.Button("Select", GUILayout.Width(70))) { onPicked?.Invoke(it); Close(); return; diff --git a/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs b/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs index 9535e72..260a84d 100644 --- a/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs +++ b/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs @@ -156,8 +156,8 @@ public class ClusterInspector : Editor { return; NeuroidLayer currentLayer = new() { ix = layerIx }; - if (selectedNucleus.receivers != null) { - foreach (INucleus receiver in selectedNucleus.receivers) { + if (selectedNucleus.allReceivers != null) { + foreach (INucleus receiver in selectedNucleus.allReceivers) { INucleus outputNeuroid = receiver; if (outputNeuroid != null) { AddToLayer(currentLayer, outputNeuroid); @@ -201,19 +201,6 @@ public class ClusterInspector : Editor { } - // void OnMouseDown(MouseDownEvent e) { - // if (e.button == 2) { draggingCanvas = true; lastMouse = e.mousePosition; e.StopPropagation(); } - // } - // void OnMouseMove(MouseMoveEvent e) { - // if (draggingCanvas) { - // var delta = e.mousePosition - lastMouse; - // pan += delta; - // //content.style.left = pan.x; - // //content.style.top = pan.y; - // lastMouse = e.mousePosition; - // } - // } - // void OnMouseUp(MouseUpEvent e) { if (e.button == 2) draggingCanvas = false; } public void OnIMGUI() { if (currentNucleus == null) @@ -285,12 +272,12 @@ public class ClusterInspector : Editor { } private void DrawReceivers(INucleus nucleus, Vector3 parentPos, float size) { - int nodeCount = nucleus.receivers.Count; + int nodeCount = nucleus.allReceivers.Count(); // Determine the maximum value in this layer // This is used to 'scale' the output value colors of the nuclei float maxValue = 0; - foreach (INucleus receiver in nucleus.receivers) { + foreach (INucleus receiver in nucleus.allReceivers) { if (receiver is Neuron neuroid) { float value = length(neuroid.outputValue); if (value > maxValue) @@ -303,7 +290,7 @@ public class ClusterInspector : Editor { float margin = 10 + spacing / 2; int row = 0; - foreach (INucleus receiver in nucleus.receivers) { + foreach (INucleus receiver in nucleus.allReceivers) { INucleus receiverNucleus = receiver; if (receiverNucleus == null) continue; @@ -414,9 +401,14 @@ public class ClusterInspector : Editor { } else { style.alignment = TextAnchor.UpperCenter; - Vector3 labelPos = position - Vector3.down * (size + 0.2f); // below disc along up axis + Vector3 labelPos = position - Vector3.down * (size + 10f); // below disc along up axis Handles.Label(labelPos, nucleus.name, style); } + + if (nucleus is Cluster cluster) { + Handles.color = Color.white; + Handles.DrawWireDisc(position, Vector3.forward, size + 10); + } } else { style.alignment = TextAnchor.UpperCenter; @@ -592,7 +584,7 @@ public class ClusterInspector : Editor { return; if (nucleus.cluster != null) this.currentNucleus = nucleus.cluster.output; - foreach (INucleus receiver in nucleus.receivers) { + foreach (INucleus receiver in nucleus.allReceivers) { if (receiver != null) { this.currentNucleus = receiver; break; @@ -606,9 +598,9 @@ public class ClusterInspector : Editor { BrainPickerWindow.ShowPicker(brain => OnClusterPicked(nucleus, brain), "Select Cluster"); } - private void OnClusterPicked(INucleus nucleus, Cluster brain) { - Cluster brainInstance = Instantiate(brain); - brainInstance.AddReceiver(nucleus); + private void OnClusterPicked(INucleus nucleus, Cluster cluster) { + Cluster clusterInstance = Instantiate(cluster); + clusterInstance.AddReceiver(nucleus); } // Connect to another nucleus in the same cluster diff --git a/Assets/Scenes/Boids/New Cluster.asset b/Assets/Scenes/Boids/New Cluster.asset new file mode 100644 index 0000000..cf65675 --- /dev/null +++ b/Assets/Scenes/Boids/New Cluster.asset @@ -0,0 +1,62 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 60a957541c24c57e78018c202ebb1d9b, type: 3} + m_Name: New Cluster + m_EditorClassIdentifier: Assembly-CSharp::Cluster + nuclei: + - rid: 2243601242842202217 + subClusters: [] + references: + version: 2 + RefIds: + - rid: 2243601242842202217 + type: {class: Neuron, ns: , asm: Assembly-CSharp} + data: + _name: Output + _synapses: [] + _receivers: [] + _array: + rid: 2243601242842202218 + _curvePreset: 0 + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + - serializedVersion: 3 + time: 1000 + value: 1000 + inSlope: 1 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + curveMax: 1 + average: 0 + - rid: 2243601242842202218 + type: {class: NucleusArray, ns: , asm: Assembly-CSharp} + data: + nuclei: + - rid: 2243601242842202217 + clusters: [] + name: Output diff --git a/Assets/Scenes/Boids/New Cluster.asset.meta b/Assets/Scenes/Boids/New Cluster.asset.meta new file mode 100644 index 0000000..40fbc5e --- /dev/null +++ b/Assets/Scenes/Boids/New Cluster.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4160a4557d16d7c03833982ab779d28e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Boids/Scripts/Boid.cs b/Assets/Scenes/Boids/Scripts/Boid.cs index 5c99655..61c9a08 100644 --- a/Assets/Scenes/Boids/Scripts/Boid.cs +++ b/Assets/Scenes/Boids/Scripts/Boid.cs @@ -32,7 +32,6 @@ public class Boid : MonoBehaviour { // boidVelocityReceptor = Receptor.GetReceptor(nanoBrain.brain, BoidVelocityType); boundaryReceptor = Receptor.CreateReceptor(nanoBrain.brain, "Avoidance"); boundaryReceptor.name = "Boundary"; - boundaryReceptor.receivers[0].synapses[0].weight = -1; boidReceptor = Receptor.CreateReceptor(nanoBrain.brain, "Boid"); boidVelocityReceptor = Receptor.CreateReceptor(nanoBrain.brain, "Alignment");