diff --git a/Assets/NanoBrain/NanoBrain.cs b/Assets/NanoBrain/NanoBrain.cs index a8e557b..9fca89a 100644 --- a/Assets/NanoBrain/NanoBrain.cs +++ b/Assets/NanoBrain/NanoBrain.cs @@ -5,18 +5,18 @@ public class NanoBrain : MonoBehaviour { // public NucleusObj rootNucleus; - public List neuroids = new(); + // public List neuroids = new(); - public Neuroid AddNeuron(string name) { - Neuroid neuroid = new(this, name); - return neuroid; - } + // public Neuroid AddNeuron(string name) { + // Neuroid neuroid = new(this, name); + // return neuroid; + // } - public void UpdateNeurons() { - foreach (Neuroid neuroid in neuroids) { - neuroid.stale++; - if (neuroid.isSleeping) - neuroid.outputValue = Vector3.zero; - } - } + // public void UpdateNeurons() { + // foreach (Neuroid neuroid in neuroids) { + // neuroid.stale++; + // if (neuroid.isSleeping) + // neuroid.outputValue = Vector3.zero; + // } + // } } diff --git a/Assets/NanoBrain/Neuroid.cs b/Assets/NanoBrain/Neuroid.cs index 3c45ddd..c2a2a30 100644 --- a/Assets/NanoBrain/Neuroid.cs +++ b/Assets/NanoBrain/Neuroid.cs @@ -5,13 +5,13 @@ public class Neuroid : Nucleus { public bool inverse = false; public float exponent = 1.0f; - public Neuroid(NanoBrain brain, string name) : base(null, name) { - this.brain = brain; - if (this.brain != null) - this.brain.neuroids.Add(this); - else - Debug.LogError("No neuroid network"); - } + // public Neuroid(NanoBrain brain, string name) : base(null, name) { + // this.brain = brain; + // if (this.brain != null) + // this.brain.neuroids.Add(this); + // else + // Debug.LogError("No neuroid network"); + // } public Neuroid(NanoBrainObj brain, string name) : base(brain, name) { } diff --git a/Assets/NanoBrain/Nucleus.cs b/Assets/NanoBrain/Nucleus.cs index 034e304..d78418e 100644 --- a/Assets/NanoBrain/Nucleus.cs +++ b/Assets/NanoBrain/Nucleus.cs @@ -38,7 +38,7 @@ public class Nucleus { #region Runtime state (not serialized) - public NanoBrain brain { get; protected set; } + // public NanoBrain brain { get; protected set; } public NanoBrainObj newBrain { get; protected set; } public virtual Vector3 outputValue { get; set; } @@ -80,7 +80,7 @@ public class Nucleus { } foreach (Receiver receiver in nucleus.receivers) receiver.nucleus.synapses.RemoveAll(s => s.nucleus == nucleus); - + nucleus.newBrain.nuclei.RemoveAll(n => n == nucleus); } diff --git a/Assets/NanoBrain/Perception.cs b/Assets/NanoBrain/Perception.cs index 11f917b..ccc254e 100644 --- a/Assets/NanoBrain/Perception.cs +++ b/Assets/NanoBrain/Perception.cs @@ -1,31 +1,27 @@ using System.Collections.Generic; using UnityEngine; - +[System.Serializable] public class Perception : Nucleus { public SensoryNeuroid[] sensoryNeuroids = new SensoryNeuroid[7]; + [System.Serializable] public class Receiver { public int thingType = 0; public Nucleus neuroid; } - public HashSet positionReceivers { get; protected set; } - public HashSet velocityReceivers { get; protected set; } + //public HashSet positionReceivers { get; protected set; } + public List positionReceivers; + //public HashSet velocityReceivers { get; protected set; } + public List velocityReceivers; public Perception(NanoBrainObj brain) : base(brain, "Perception") { - //this.brain = brain; this.positionReceivers = new(); this.velocityReceivers = new(); } - public Perception(NanoBrain neuroidNet) : base(null, "Perception") { - this.brain = neuroidNet; - this.positionReceivers = new(); - this.velocityReceivers = new(); - } - public void SendPositions(Nucleus receivingNeuroid, int thingType = 0, float weight = 1.0f) { Receiver receiver = new() { thingType = thingType, @@ -78,18 +74,20 @@ public class Perception : Nucleus { if (availableIx != -1) { SensoryNeuroid neuroid; if (sensoryNeuroids[availableIx] != null) { - // Debug.Log($"replace receptor for {thingId} at {availableIx}"); + Debug.Log($"replace receptor for {thingId} at {availableIx}"); neuroid = sensoryNeuroids[availableIx]; neuroid.Replace(thingId, name); } else { - // Debug.Log($"new receptor for {thingId} at {availableIx}"); - neuroid = new(brain, thingId, name); + Debug.Log($"new receptor for {thingId} at {availableIx}"); + neuroid = new(newBrain, thingId, name); sensoryNeuroids[availableIx] = neuroid; } foreach (Receiver receiver in positionReceivers) { - if (receiver.thingType == 0 || receiver.thingType == thingType) + if (receiver.thingType == 0 || receiver.thingType == thingType) { + Debug.Log("Add position receiver"); receiver.neuroid.GetInputFrom(neuroid); + } } foreach (Receiver receiver in velocityReceivers) { if (receiver.thingType == 0 || receiver.thingType == thingType) diff --git a/Assets/NanoBrain/SensoryNeuroid.cs b/Assets/NanoBrain/SensoryNeuroid.cs index 0129717..78440de 100644 --- a/Assets/NanoBrain/SensoryNeuroid.cs +++ b/Assets/NanoBrain/SensoryNeuroid.cs @@ -29,14 +29,13 @@ public class SensoryNeuroid : Neuroid { public Receptor receptor; public VelocityNeuroid velocityNeuroid; - // public SensoryNeuroid(NeuroidNetwork net, int thingId) : base(net, "sensory neuroid") { - public SensoryNeuroid(NanoBrain net, int thingId, string name = "sensor") : base(net, name) { + public SensoryNeuroid(NanoBrainObj brain, int thingId, string name = "sensor") : base(brain, name) { this.name = name + ": position"; this.receptor = new Receptor { neuroid = this, thingId = thingId }; - this.velocityNeuroid = new(net, name + ": velocity"); + this.velocityNeuroid = new(brain, name + ": velocity"); // The velocity neuroid received position data from this this.AddReceiver(velocityNeuroid); } @@ -87,7 +86,7 @@ public class VelocityNeuroid : Neuroid { private Vector3 lastPosition = Vector3.zero; private float lastValueTime = 0; - public VelocityNeuroid(NanoBrain net, string name = "velocity") : base(net, name) { + public VelocityNeuroid(NanoBrainObj net, string name = "velocity") : base(net, name) { } public void Replace(string name = "velocity") { diff --git a/Assets/NanoBrain/VisualEditor/Editor/NanoBrainInspector.cs b/Assets/NanoBrain/VisualEditor/Editor/NanoBrainInspector.cs index 2b36ad9..21b5c83 100644 --- a/Assets/NanoBrain/VisualEditor/Editor/NanoBrainInspector.cs +++ b/Assets/NanoBrain/VisualEditor/Editor/NanoBrainInspector.cs @@ -10,10 +10,6 @@ public class NanoBrainInspector : Editor { protected static VisualElement mainContainer; protected static VisualElement inspectorContainer; - //private Nucleus currentNucleus = null; - private List layers = new(); - private Dictionary neuroidPositions = new(); - protected bool breakOnWake = false; #region Start @@ -241,22 +237,20 @@ public class NanoBrainInspector : Editor { Vector2Int layerNeuroidPos = this.neuroidPositions[layerNucleus]; Vector3 parentPos = new(100 + layerNeuroidPos.x * 100, margin + layerNeuroidPos.y * spacing, 0.1f); - //int i = 0; float inputSpacing = 400f / layerNucleus.synapses.Count; float inputMargin = 10 + inputSpacing / 2; int minStale = 10000; - //foreach ((Nucleus nucleus, float weight) in layerNucleus.synapses) { + Debug.Log($"layer neuron {layerNucleus.name} has {layerNucleus.synapses.Count} synapses"); foreach (Synapse synapse in layerNucleus.synapses) { Nucleus nucleus = synapse.nucleus; if (nucleus != null) { - float weight = synapse.weight; + Debug.Log($"Synapse to {nucleus.name} is valid"); float weight = synapse.weight; if (this.neuroidPositions.ContainsKey(nucleus)) { Vector2Int inputNeuroidPos = this.neuroidPositions[nucleus]; if (inputNeuroidPos.x == layerNeuroidPos.x + 1) { Vector3 pos = new(100 + inputNeuroidPos.x * 100, inputMargin + inputNeuroidPos.y * inputSpacing, 0.0f); - //float brightness = weight / 10.0f; - Handles.color = Color.white; //new Color(brightness, brightness, brightness); + Handles.color = Color.white; Handles.DrawLine(parentPos, pos); } } @@ -265,11 +259,12 @@ public class NanoBrainInspector : Editor { } } - // if (layerNucleus.synapses.Count > 0 && minStale > 2 && layerNucleus.stale < 3) - // Debug.LogWarning($"Strange {minStale} is big duing update"); - float size = 20; + if (layerNucleus == this.currentNucleus) { + Handles.color = Color.white; + Handles.DrawSolidDisc(parentPos, Vector3.forward, size + 2); + } if (layerNucleus.isSleeping) Handles.color = Color.darkRed; else { @@ -293,7 +288,6 @@ public class NanoBrainInspector : Editor { // Process Hover HandleMouseHover(layerNucleus, neuronRect); // Process click - // Debug.Log($"{et} {e.type}"); if (e.type == EventType.MouseDown && e.button == 0) { // Consume the event so the scene doesn't also handle it e.Use(); diff --git a/Assets/NanoBrain/VisualEditor/NanoBrainObj.cs b/Assets/NanoBrain/VisualEditor/NanoBrainObj.cs index a870d49..16f386f 100644 --- a/Assets/NanoBrain/VisualEditor/NanoBrainObj.cs +++ b/Assets/NanoBrain/VisualEditor/NanoBrainObj.cs @@ -29,10 +29,10 @@ public class NanoBrainObj : ScriptableObject, ISerializationCallbackReceiver { } public void UpdateNuclei() { - foreach (Neuroid neuroid in nuclei) { - neuroid.stale++; - if (neuroid.isSleeping) - neuroid.outputValue = Vector3.zero; + foreach (Nucleus nucleus in nuclei) { + nucleus.stale++; + if (nucleus.isSleeping) + nucleus.outputValue = Vector3.zero; } } diff --git a/Assets/Scenes/Boids/Boids.unity b/Assets/Scenes/Boids/Boids.unity index 2c5cb28..5b10cbd 100644 --- a/Assets/Scenes/Boids/Boids.unity +++ b/Assets/Scenes/Boids/Boids.unity @@ -393,7 +393,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: ec888ca5333d45a438f9f417fa5ce135, type: 3} m_Name: m_EditorClassIdentifier: Assembly-CSharp::SwarmSpawn - count: 20 + count: 1 boidPrefab: {fileID: 8702527964058765413, guid: f9c706268554ce449a8773675b2864b8, type: 3} spawnAreaSize: {x: 0.5, y: 0.5, z: 0.5} minDelay: 0.05 diff --git a/Assets/Scenes/Boids/New Nano Brain Obj.asset b/Assets/Scenes/Boids/New Nano Brain Obj.asset index 1fc53fd..df2a58c 100644 --- a/Assets/Scenes/Boids/New Nano Brain Obj.asset +++ b/Assets/Scenes/Boids/New Nano Brain Obj.asset @@ -13,16 +13,48 @@ MonoBehaviour: m_Name: New Nano Brain Obj m_EditorClassIdentifier: Assembly-CSharp::NanoBrainObj title: - count: 0 + count: -26 color: {r: 1, g: 1, b: 1, a: 1} texture: {fileID: 0} nuclei: - id: 257807948 _name: Root - synapses: [] + synapses: + - nucleusId: -651011940 + weight: 1 + - nucleusId: -1689048724 + weight: 1 receivers: [] - id: -1868865374 _name: Perception synapses: [] receivers: [] + - id: -651011940 + _name: Neuron 1 + synapses: [] + receivers: + - nucleusId: 257807948 + - id: -1689048724 + _name: New neuron + synapses: [] + receivers: + - nucleusId: 257807948 + - id: -152927560 + _name: 'Boundary: position' + synapses: [] + receivers: + - nucleusId: -1462684836 + - id: -1462684836 + _name: 'Boundary: velocity' + synapses: + - nucleusId: -152927560 + weight: 1 + receivers: [] rootId: 257807948 + perception: + id: 1565766940 + _name: Perception + synapses: [] + receivers: [] + positionReceivers: [] + velocityReceivers: [] diff --git a/Assets/Scenes/Boids/Prefabs/Boid.prefab b/Assets/Scenes/Boids/Prefabs/Boid.prefab index 039cf86..1a756c3 100644 --- a/Assets/Scenes/Boids/Prefabs/Boid.prefab +++ b/Assets/Scenes/Boids/Prefabs/Boid.prefab @@ -176,4 +176,4 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 92f34a5e4027a1dc39efd8ce63cf6aba, type: 3} m_Name: m_EditorClassIdentifier: Assembly-CSharp::NanoBrainComponent - brain: {fileID: 11400000, guid: 55099766f6f09071ab4e8c89b02fa302, type: 2} + brain: {fileID: 11400000, guid: af8d90b8b4b9dcad7837130c4143d91c, type: 2} diff --git a/Assets/Scenes/Boids/RoamingBrain.asset b/Assets/Scenes/Boids/RoamingBrain.asset new file mode 100644 index 0000000..e603273 --- /dev/null +++ b/Assets/Scenes/Boids/RoamingBrain.asset @@ -0,0 +1,102 @@ +%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: 36081359186edfec998d891a1feeb17b, type: 3} + m_Name: RoamingBrain + m_EditorClassIdentifier: Assembly-CSharp::NanoBrainObj + title: + count: 0 + color: {r: 1, g: 1, b: 1, a: 1} + texture: {fileID: 0} + nuclei: + - id: -1753291412 + _name: Root + synapses: + - nucleusId: 237822944 + weight: 1 + receivers: [] + - id: 472852910 + _name: Perception + synapses: [] + receivers: [] + - id: 237822944 + _name: Avoidance + synapses: [] + receivers: + - nucleusId: -1753291412 + - id: 983561152 + _name: 'Boundary: position' + synapses: [] + receivers: + - nucleusId: -1818801134 + - id: -1818801134 + _name: 'Boundary: velocity' + synapses: + - nucleusId: 983561152 + weight: 1 + receivers: [] + - id: 1386590800 + _name: 'Boundary: position' + synapses: [] + receivers: + - nucleusId: -1415771486 + - nucleusId: 237822944 + - id: -1415771486 + _name: 'Boundary: velocity' + synapses: + - nucleusId: 1386590800 + weight: 1 + receivers: [] + - id: -213085248 + _name: 'Boundary: position' + synapses: [] + receivers: + - nucleusId: 1279519762 + - nucleusId: 237822944 + - id: 1279519762 + _name: 'Boundary: velocity' + synapses: + - nucleusId: -213085248 + weight: 1 + receivers: [] + - id: 1783940116 + _name: 'Boundary: position' + synapses: [] + receivers: + - nucleusId: -1018422170 + - nucleusId: 237822944 + - id: -1018422170 + _name: 'Boundary: velocity' + synapses: + - nucleusId: 1783940116 + weight: 1 + receivers: [] + rootId: -1753291412 + perception: + id: 2139386530 + _name: Perception + synapses: [] + receivers: [] + positionReceivers: + - thingType: 0 + neuroid: + id: 237822944 + _name: Avoidance + synapses: + - nucleusId: 1386590800 + weight: 1 + - nucleusId: -213085248 + weight: 1 + - nucleusId: 1783940116 + weight: 1 + receivers: + - nucleusId: -1753291412 + velocityReceivers: [] diff --git a/Assets/Scenes/Boids/RoamingBrain.asset.meta b/Assets/Scenes/Boids/RoamingBrain.asset.meta new file mode 100644 index 0000000..74e1c7d --- /dev/null +++ b/Assets/Scenes/Boids/RoamingBrain.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: af8d90b8b4b9dcad7837130c4143d91c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Boids/Scripts/Boid.cs b/Assets/Scenes/Boids/Scripts/Boid.cs index f13d7a9..f5a83cf 100644 --- a/Assets/Scenes/Boids/Scripts/Boid.cs +++ b/Assets/Scenes/Boids/Scripts/Boid.cs @@ -24,7 +24,7 @@ public class Boid : MonoBehaviour { public int id; void Awake() { - + nanoBrain = GetComponent(); this.id = this.GetInstanceID(); sc = FindFirstObjectByType(); diff --git a/Assets/Scenes/Boids/Scripts/RoamingNucleus.cs b/Assets/Scenes/Boids/Scripts/RoamingNucleus.cs index 2ba38b7..be2fe61 100644 --- a/Assets/Scenes/Boids/Scripts/RoamingNucleus.cs +++ b/Assets/Scenes/Boids/Scripts/RoamingNucleus.cs @@ -3,11 +3,11 @@ public class Roaming : Nucleus { public Neuroid output; - public Roaming(NanoBrain neuroidNet, Perception perception, SwarmControl sc) : base(null, "Roaming nucleus") { - avoidance = new(neuroidNet, "Avoidance") { inverse = true }; + public Roaming(NanoBrainObj brain, Perception perception, SwarmControl sc) : base(null, "Roaming nucleus") { + avoidance = new(brain, "Avoidance") { inverse = true }; perception.SendPositions(avoidance, Boid.BoundaryType); - this.output = new(neuroidNet, "Roaming"); + this.output = new(brain, "Roaming"); output.GetInputFrom(avoidance, -sc.avoidanceForce); } diff --git a/Assets/Scenes/Boids/Scripts/SwarmingNucleus.cs b/Assets/Scenes/Boids/Scripts/SwarmingNucleus.cs index e0ea77b..de25135 100644 --- a/Assets/Scenes/Boids/Scripts/SwarmingNucleus.cs +++ b/Assets/Scenes/Boids/Scripts/SwarmingNucleus.cs @@ -10,20 +10,20 @@ public class Swarming : Nucleus { public override Vector3 outputValue { get => output.outputValue; set => output.outputValue = value; } - public Swarming(NanoBrain neuroidNet, Perception perception, SwarmControl sc) : base(null, "Swarming Nucleus") { - this.cohesion = new(neuroidNet, "Cohesion") { inverse = false }; + public Swarming(NanoBrainObj brain, Perception perception, SwarmControl sc) : base(null, "Swarming Nucleus") { + this.cohesion = new(brain, "Cohesion") { inverse = false }; perception.SendPositions(this.cohesion, Boid.BoidType); - this.alignment = new(neuroidNet, "Alignment") { average = true }; + this.alignment = new(brain, "Alignment") { average = true }; perception.SendVelocities(this.alignment, Boid.BoidType); - this.avoidance = new(neuroidNet, "Avoidance") { inverse = true }; + this.avoidance = new(brain, "Avoidance") { inverse = true }; perception.SendPositions(this.avoidance); - this.boundary = new(neuroidNet, "Boundary"); + this.boundary = new(brain, "Boundary"); perception.SendPositions(this.boundary, Boid.BoundaryType); - this.output = new(neuroidNet, "Swarming"); + this.output = new(brain, "Swarming"); this.output.GetInputFrom(alignment, sc.alignmentForce); this.output.GetInputFrom(cohesion, sc.cohesionForce); this.output.GetInputFrom(avoidance, -sc.avoidanceForce);