diff --git a/Assets/NanoBrain/Editor/NanoBrain_Editor.cs b/Assets/NanoBrain/Editor/NanoBrain_Editor.cs index 008646d..74bd49a 100644 --- a/Assets/NanoBrain/Editor/NanoBrain_Editor.cs +++ b/Assets/NanoBrain/Editor/NanoBrain_Editor.cs @@ -26,7 +26,6 @@ public class NanoBrain_Editor : Editor { Debug.Log($"Layercount = {this.layers.Count}"); } - #endregion Start #region Update @@ -205,10 +204,18 @@ public class NanoBrain_Editor : Editor { if (brain == null) return; + Vector3 position = brain.transform.position; + float radius = 1; + + + Handles.DrawWireDisc(position, Vector3.up, radius); // horizontal circle + Handles.DrawWireDisc(position, Vector3.right, radius); // X-plane + Handles.DrawWireDisc(position, Vector3.forward, radius); // Z-plane + + // Debug.DrawRay(brain.transform.position, Vector3.forward, Color.magenta); // Handles.color = Color.green; // Handles.DrawLine(brain.transform.position, brain.transform.position + Vector3.up); - Vector3 position = brain.transform.position; Handles.color = Color.yellow; Vector3 worldForce = brain.transform.TransformDirection(this.currentNucleus.outputValue); Debug.DrawRay(position, worldForce * 10, Color.yellow); diff --git a/Assets/NanoBrain/Neuroid.cs b/Assets/NanoBrain/Neuroid.cs index 6f2e6dc..852f8b5 100644 --- a/Assets/NanoBrain/Neuroid.cs +++ b/Assets/NanoBrain/Neuroid.cs @@ -3,13 +3,10 @@ using UnityEngine; public class Neuroid : Nucleus { public int stale = 0; - public bool average = false; public bool inverse = false; public float exponent = 1.0f; - public NanoBrain brain; - public Neuroid(NanoBrain brain, string name) : base(name) { this.brain = brain; if (this.brain != null) @@ -18,10 +15,10 @@ public class Neuroid : Nucleus { Debug.LogError("No neuroid network"); } - public void AddSynapse(Neuroid input) { - input.AddReceiver(this); - this.synapses[input] = 1.0f; - } + // public void AddSynapse(Neuroid input) { + // input.AddReceiver(this); + // this.synapses[input] = 1.0f; + // } public void SetWeight(Neuroid input, float weight) { this.synapses[input] = weight; @@ -43,21 +40,7 @@ public class Neuroid : Nucleus { UpdateState(); } - public void RemoveInputFrom(Neuroid input) { - if (this.synapses.Count == 0) - return; - - this.synapses.Remove(input); - if (this.synapses.Count == 0) { - // In case this was the last synapse, we reset the output because in this case no updates from synapses will follow. - this.outputValue = Vector3.zero; - foreach (Neuroid neuroid in this.receivers) - neuroid.SetInput(this); - } - } - public virtual void UpdateState() { - // int minStale = 10000; Vector3 result = Vector3.zero; foreach ((Nucleus nucleus, float weight) in this.synapses) { if (nucleus is Neuroid neuroid && neuroid.IsStale()) @@ -71,16 +54,11 @@ public class Neuroid : Nucleus { magnitude = 1 / magnitude; result += direction * magnitude; - // if (nucleus is Neuroid neuroid && neuroid.stale < minStale) - // minStale = neuroid.stale; } if (average && this.synapses.Count > 0) result /= this.synapses.Count; this.outputValue = result; - - // if (minStale > 2) - // Debug.LogWarning($"Strange {minStale} is big duing update"); this.stale = 0; foreach (Neuroid receiver in this.receivers) diff --git a/Assets/NanoBrain/Nucleus.cs b/Assets/NanoBrain/Nucleus.cs index 0683d79..c34b8ed 100644 --- a/Assets/NanoBrain/Nucleus.cs +++ b/Assets/NanoBrain/Nucleus.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using UnityEngine; public class Nucleus { + public NanoBrain brain { get; protected set; } + public string name; public readonly Dictionary synapses = new(); diff --git a/Assets/NanoBrain/Perception.cs b/Assets/NanoBrain/Perception.cs index efc7970..fd5dfeb 100644 --- a/Assets/NanoBrain/Perception.cs +++ b/Assets/NanoBrain/Perception.cs @@ -5,9 +5,6 @@ using UnityEngine; public class Perception : Nucleus { public SensoryNeuroid[] sensoryNeuroids = new SensoryNeuroid[7]; - // public NeuroidNetwork neuroidNet { get; protected set; } - public NanoBrain neuroidNet { get; protected set; } - public class Receiver { public int thingType = 0; public Neuroid neuroid; @@ -16,9 +13,8 @@ public class Perception : Nucleus { public HashSet positionReceivers { get; protected set; } public HashSet velocityReceivers { get; protected set; } - // public Perception(NeuroidNetwork neuroidNet) : base("Perception") { public Perception(NanoBrain neuroidNet) : base("Perception") { - this.neuroidNet = neuroidNet; + this.brain = neuroidNet; this.positionReceivers = new(); this.velocityReceivers = new(); } @@ -32,7 +28,7 @@ public class Perception : Nucleus { foreach (SensoryNeuroid neuroid in sensoryNeuroids) { if (neuroid != null) { neuroid.AddReceiver(receivingNeuroid); - receivingNeuroid.synapses[neuroid] = weight; // new(neuroid, weight); + receivingNeuroid.synapses[neuroid] = weight; } } } @@ -45,7 +41,7 @@ public class Perception : Nucleus { foreach (SensoryNeuroid neuroid in sensoryNeuroids) { if (neuroid != null && neuroid.velocityNeuroid != null) { neuroid.velocityNeuroid.AddReceiver(receivingNeuroid); - receivingNeuroid.synapses[neuroid] = 1.0f; //new(neuroid); + receivingNeuroid.synapses[neuroid] = weight; } } } @@ -73,49 +69,28 @@ public class Perception : Nucleus { availableIx = leastInterestingIx; if (availableIx != -1) { + SensoryNeuroid neuroid; if (sensoryNeuroids[availableIx] != null) { - Debug.Log($"replace receptor for {thingId} at {availableIx}"); - SensoryNeuroid neuroid = sensoryNeuroids[availableIx]; - neuroid.Replace(thingId); - neuroid.name = name; - foreach (Receiver receiver in positionReceivers) { - if (receiver.thingType == 0 || receiver.thingType == thingType) - receiver.neuroid.GetInputFrom(neuroid); - } - foreach (Receiver receiver in velocityReceivers) { - if (receiver.thingType == 0 || receiver.thingType == thingType) - receiver.neuroid.GetInputFrom(neuroid.velocityNeuroid); - } - neuroid.receptor.position = localPosition; - + // Debug.Log($"replace receptor for {thingId} at {availableIx}"); + neuroid = sensoryNeuroids[availableIx]; + neuroid.Replace(thingId, name); } else { - Debug.Log($"new receptor for {thingId} at {availableIx}"); - SensoryNeuroid neuroid = new(neuroidNet, thingId) { name = name }; - foreach (Receiver receiver in positionReceivers) { - if (receiver.thingType == 0 || receiver.thingType == thingType) - receiver.neuroid.GetInputFrom(neuroid); - } - foreach (Receiver receiver in velocityReceivers) { - if (receiver.thingType == 0 || receiver.thingType == thingType) - receiver.neuroid.GetInputFrom(neuroid.velocityNeuroid); - } - + // Debug.Log($"new receptor for {thingId} at {availableIx}"); + neuroid = new(brain, thingId) { name = name }; sensoryNeuroids[availableIx] = neuroid; - neuroid.receptor.position = localPosition; } + foreach (Receiver receiver in positionReceivers) { + if (receiver.thingType == 0 || receiver.thingType == thingType) + receiver.neuroid.GetInputFrom(neuroid); + } + foreach (Receiver receiver in velocityReceivers) { + if (receiver.thingType == 0 || receiver.thingType == thingType) + receiver.neuroid.GetInputFrom(neuroid.velocityNeuroid); + } + + neuroid.receptor.position = localPosition; } } - public void RemoveStimulus(int thingId) { - for (int i = 0; i < sensoryNeuroids.Length; i++) { - if (sensoryNeuroids[i] != null && sensoryNeuroids[i].receptor.thingId == thingId) { - foreach (Neuroid receiver in sensoryNeuroids[i].receivers) - receiver.RemoveInputFrom(sensoryNeuroids[i]); - sensoryNeuroids[i] = null; - return; - } - } - - } } \ No newline at end of file diff --git a/Assets/NanoBrain/SensoryNeuroid.cs b/Assets/NanoBrain/SensoryNeuroid.cs index c6c0bc7..72985e5 100644 --- a/Assets/NanoBrain/SensoryNeuroid.cs +++ b/Assets/NanoBrain/SensoryNeuroid.cs @@ -7,17 +7,17 @@ public class Receptor { public SensoryNeuroid neuroid; public int thingId; - public Vector3 value; + public Vector3 localPosition; /// /// Local position of the thing /// public virtual Vector3 position { get { - return this.value; + return this.localPosition; } set { - this.value = value; + this.localPosition = value; neuroid.UpdateState(); } } @@ -40,17 +40,18 @@ public class SensoryNeuroid : Neuroid { this.AddReceiver(velocityNeuroid); } - public void Replace(int thingId) { - this.name = "sensory neuroid"; + public void Replace(int thingId, string name = "sensory neuroid") { + this.name = name; this.receptor.thingId = thingId; - this.receptor.value = Vector3.zero; + this.receptor.localPosition = Vector3.zero; this.outputValue = Vector3.zero; this.receivers = new(); this.AddReceiver(velocityNeuroid); + this.velocityNeuroid.receivers = new(); } public override void UpdateState() { - Vector3 result = receptor.value; + Vector3 result = receptor.localPosition; //foreach ((Nucleus nucleus, Synapse synapse) in this.synapses) { foreach ((Nucleus nucleus, float weight) in this.synapses) { Vector3 direction = nucleus.outputValue.normalized; diff --git a/Assets/Scenes/Boids/Boids.unity b/Assets/Scenes/Boids/Boids.unity index 9827fcf..1c9b8ef 100644 --- a/Assets/Scenes/Boids/Boids.unity +++ b/Assets/Scenes/Boids/Boids.unity @@ -373,8 +373,8 @@ MonoBehaviour: m_EditorClassIdentifier: Assembly-CSharp::SwarmControl speed: 2 inertia: 0.1 - alignmentForce: 5 - cohesionForce: 5 + alignmentForce: 3 + cohesionForce: 3 avoidanceForce: 5 separationDistance: 0.3 perceptionDistance: 1 @@ -393,7 +393,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: ec888ca5333d45a438f9f417fa5ce135, type: 3} m_Name: m_EditorClassIdentifier: Assembly-CSharp::SwarmSpawn - count: 2 + count: 5 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/Scripts/Boid.cs b/Assets/Scenes/Boids/Scripts/Boid.cs index 0fdebd6..0ac0c98 100644 --- a/Assets/Scenes/Boids/Scripts/Boid.cs +++ b/Assets/Scenes/Boids/Scripts/Boid.cs @@ -63,9 +63,6 @@ public class Boid : MonoBehaviour { Vector3 desiredLocalSpace = -this.transform.InverseTransformPoint(desiredWorldSpace); perception.ProcessStimulus(777, BoundaryType, desiredLocalSpace, "Boundary"); } - // else { - // perception.RemoveStimulus(777); - // } Vector3 worldForce = this.transform.TransformDirection(totalForce.outputValue); @@ -95,19 +92,4 @@ public class Boid : MonoBehaviour { float m = Mathf.Min(sx, Mathf.Min(sy, sz)); return b.center + d * m; } - - // void OnDrawGizmosSelected() { - // if (sc == null) - // return; - // Gizmos.DrawWireSphere(this.transform.position, sc.perceptionDistance); - // Gizmos.color = Color.yellow; - // Vector3 worldForce = this.transform.TransformDirection(totalForce.outputValue); - // Gizmos.DrawRay(transform.position, worldForce * 10); - // // Gizmos.color = Color.magenta; - // // Gizmos.DrawRay(transform.position, this.transform.TransformDirection(avoidance.outputValue) * 10); - // // Debug.Log($"Avoidance {roaming.avoidance.outputValue} Roaming {roaming.output.outputValue} Total {totalForce.outputValue}"); - // // Debug.Log($"WorldForce {worldForce} velocity {velocity} inertia {sc.inertia}"); - // Gizmos.color = Color.blue; - // Gizmos.DrawRay(transform.position, this.velocity * 10); - // } } diff --git a/Assets/Scenes/Boids/Scripts/RoamingNucleus.cs b/Assets/Scenes/Boids/Scripts/RoamingNucleus.cs index ac510bf..2499b5d 100644 --- a/Assets/Scenes/Boids/Scripts/RoamingNucleus.cs +++ b/Assets/Scenes/Boids/Scripts/RoamingNucleus.cs @@ -3,7 +3,6 @@ public class Roaming : Nucleus { public Neuroid output; - // public Roaming(NeuroidNetwork neuroidNet, Perception perception, SwarmControl sc) : base("Roaming nucleus") { public Roaming(NanoBrain neuroidNet, Perception perception, SwarmControl sc) : base("Roaming nucleus") { avoidance = new(neuroidNet, "Avoidance") { inverse = true }; perception.SendPositions(avoidance, 1.0f, 1); diff --git a/Assets/Scenes/Boids/Scripts/SwarmSpawner.cs b/Assets/Scenes/Boids/Scripts/SwarmSpawner.cs index 241969a..48a08d4 100644 --- a/Assets/Scenes/Boids/Scripts/SwarmSpawner.cs +++ b/Assets/Scenes/Boids/Scripts/SwarmSpawner.cs @@ -26,7 +26,8 @@ public class SwarmSpawn : MonoBehaviour { ); // Instantiate the prefab at the random position relative to the spawner - Instantiate(boidPrefab, transform.position + randomPosition, Random.rotation); + GameObject boid = Instantiate(boidPrefab, transform.position + randomPosition, Random.rotation); + boid.name = "Boid " + i; } } } diff --git a/Assets/Scenes/Boids/Scripts/SwarmingNucleus.cs b/Assets/Scenes/Boids/Scripts/SwarmingNucleus.cs index 23831bf..f8c7bef 100644 --- a/Assets/Scenes/Boids/Scripts/SwarmingNucleus.cs +++ b/Assets/Scenes/Boids/Scripts/SwarmingNucleus.cs @@ -12,7 +12,6 @@ public class Swarming : Nucleus { public const int BoundaryType = 1; public const int BoidType = 2; - // public Swarming(NeuroidNetwork neuroidNet, Perception perception, SwarmControl sc) : base("Swarming Nucleus") { public Swarming(NanoBrain neuroidNet, Perception perception, SwarmControl sc) : base("Swarming Nucleus") { this.cohesion = new(neuroidNet, "Cohesion"); perception.SendPositions(this.cohesion, 1.0f, BoidType);