Move more towards pure neuroids
This commit is contained in:
parent
7ce787f5db
commit
fdabad2895
@ -37,15 +37,19 @@ public class GraphEditorWindow : EditorWindow {
|
||||
int neuroidIx = 0;
|
||||
|
||||
foreach (Neuroid neuroid in neuroids) {
|
||||
// Skip neurons we already processed
|
||||
if (neuronVisited.Contains(neuroid))
|
||||
continue;
|
||||
|
||||
if (neuroid.IsStale()) {
|
||||
neuronVisited.Add(neuroid);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this neuroid is not visited while its output neuroid is visited
|
||||
// If the output neuroid is visited
|
||||
// Note: this does not yet work for multiple outputs yet (see the use of First())
|
||||
if (!neuronVisited.Contains(neuroid) && (neuroid.outputNeuroids.Count == 0 ||
|
||||
(neuronVisited.Contains(neuroid.outputNeuroids.First()) && neuroid.outputNeuroids.First().layerIx == layerIx - 1))) {
|
||||
if (neuroid.outputNeuroids.Count == 0 // make sure the root neuroids are processed directly
|
||||
|| (neuronVisited.Contains(neuroid.outputNeuroids.First()) && neuroid.outputNeuroids.First().layerIx == layerIx - 1)) {
|
||||
// Add it to the next layer
|
||||
currentLayer.neuroids.Add(neuroid);
|
||||
neuroid.layerIx = layerIx;
|
||||
@ -111,9 +115,9 @@ public class GraphEditorWindow : EditorWindow {
|
||||
Vector3 parentPos = new(100 + layerNeuroidPos.x * 100, margin + layerNeuroidPos.y * spacing, 0.1f);
|
||||
|
||||
int i = 0;
|
||||
float inputSpacing = 200f / layerNeuroid.newSynapses.Count;
|
||||
float inputSpacing = 200f / layerNeuroid.synapses.Count;
|
||||
float inputMargin = 100 + inputSpacing / 2;
|
||||
foreach (Synapse synapse in layerNeuroid.newSynapses.Values) {
|
||||
foreach (Synapse synapse in layerNeuroid.synapses.Values) {
|
||||
if (synapse.neuroid != null) {
|
||||
if (this.neuroidPositions.ContainsKey(synapse.neuroid)) {
|
||||
|
||||
@ -145,7 +149,7 @@ public class GraphEditorWindow : EditorWindow {
|
||||
// Draw the tooltip
|
||||
GUIContent tooltip = new(
|
||||
$"{neuroid.name}" +
|
||||
$"\nsynapse count {neuroid.newSynapses.Count}" +
|
||||
$"\nsynapse count {neuroid.synapses.Count}" +
|
||||
$"\nValue: {neuroid.outputValue}" +
|
||||
$"\nStale: {neuroid.stale}");
|
||||
|
||||
|
||||
@ -16,8 +16,8 @@ public class Synapse {
|
||||
public class NeuroidNetwork {
|
||||
public List<Neuroid> neuroids = new();
|
||||
|
||||
public Neuroid AddNeuron() {
|
||||
Neuroid neuroid = new(this);
|
||||
public Neuroid AddNeuron(string name) {
|
||||
Neuroid neuroid = new(this, name);
|
||||
return neuroid;
|
||||
}
|
||||
|
||||
@ -29,35 +29,33 @@ public class NeuroidNetwork {
|
||||
}
|
||||
|
||||
public class Neuroid {
|
||||
//public int id;
|
||||
public string name;
|
||||
|
||||
public int layerIx;
|
||||
public int stale = 0;
|
||||
|
||||
public readonly Dictionary<Neuroid, Synapse> newSynapses = new();
|
||||
public readonly Dictionary<Neuroid, Synapse> synapses = new();
|
||||
|
||||
public Vector3 outputValue;
|
||||
public HashSet<Neuroid> outputNeuroids = new();
|
||||
|
||||
public enum Mode {
|
||||
Sum,
|
||||
Average,
|
||||
}
|
||||
public Mode mode = Mode.Sum;
|
||||
|
||||
public bool average = false;
|
||||
//public bool quadratic = false;
|
||||
public bool inverse = false;
|
||||
public float exponent = 1.0f;
|
||||
|
||||
public NeuroidNetwork net;
|
||||
|
||||
public Neuroid(NeuroidNetwork net) {
|
||||
public Neuroid(NeuroidNetwork net, string name) {
|
||||
this.net = net;
|
||||
this.name = name;
|
||||
if (this.net != null)
|
||||
this.net.neuroids.Add(this);
|
||||
}
|
||||
|
||||
public void AddSynapse(Neuroid input) {
|
||||
input.AddReceiver(this);
|
||||
this.newSynapses[input] = new(input, Vector3.zero, 1.0f);
|
||||
this.synapses[input] = new(input, Vector3.zero, 1.0f);
|
||||
}
|
||||
|
||||
public void AddReceiver(Neuroid receiver) {
|
||||
@ -65,84 +63,77 @@ public class Neuroid {
|
||||
}
|
||||
|
||||
public void ResetWeights() {
|
||||
foreach (Synapse synapse in this.newSynapses.Values)
|
||||
foreach (Synapse synapse in this.synapses.Values)
|
||||
synapse.weight = 1.0f;
|
||||
}
|
||||
|
||||
public void SetWeight(Neuroid input, float weight) {
|
||||
if (this.newSynapses.ContainsKey(input)) {
|
||||
this.newSynapses[input].weight = weight;
|
||||
if (this.synapses.ContainsKey(input)) {
|
||||
this.synapses[input].weight = weight;
|
||||
}
|
||||
else {
|
||||
this.newSynapses[input] = new(input, Vector3.zero, weight);
|
||||
this.synapses[input] = new(input, Vector3.zero, weight);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetInputFrom(Neuroid input, float weight = 1.0f) {
|
||||
input.AddReceiver(this);
|
||||
this.newSynapses[input] = new(input, Vector3.zero, weight);
|
||||
this.synapses[input] = new(input, Vector3.zero, weight);
|
||||
}
|
||||
|
||||
public void SetInput(Neuroid input, Vector3 value) {
|
||||
if (this.newSynapses.ContainsKey(input)) {
|
||||
Synapse synapse = this.newSynapses[input];
|
||||
if (this.synapses.ContainsKey(input)) {
|
||||
Synapse synapse = this.synapses[input];
|
||||
synapse.value = value;
|
||||
}
|
||||
else
|
||||
this.newSynapses[input] = new(null, value, 1.0f);
|
||||
this.synapses[input] = new(null, value, 1.0f);
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
public void SetInput(Neuroid input, Vector3 value, float weight) {
|
||||
if (this.newSynapses.ContainsKey(input)) {
|
||||
Synapse synapse = this.newSynapses[input];
|
||||
if (this.synapses.ContainsKey(input)) {
|
||||
Synapse synapse = this.synapses[input];
|
||||
synapse.value = value;
|
||||
synapse.weight = weight;
|
||||
}
|
||||
else
|
||||
this.newSynapses[input] = new(null, value, weight);
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
public readonly Dictionary<int, Neuroid> fakeNeuroids = new();
|
||||
public void SetInput(int thingId, Vector3 value, float weight, NeuroidNetwork net) {
|
||||
if (fakeNeuroids.ContainsKey(thingId)) {
|
||||
Neuroid fakeInput = fakeNeuroids[thingId];
|
||||
Synapse synapse = this.newSynapses[fakeInput];
|
||||
synapse.value = value;
|
||||
synapse.weight = weight;
|
||||
}
|
||||
else {
|
||||
fakeNeuroids[thingId] = new(net);
|
||||
this.newSynapses[fakeNeuroids[thingId]] = new (null, value, weight);
|
||||
}
|
||||
this.synapses[input] = new(null, value, weight);
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
// public readonly Dictionary<int, Neuroid> fakeNeuroids = new();
|
||||
// public void SetInput(int thingId, Vector3 value, float weight, NeuroidNetwork net) {
|
||||
// if (fakeNeuroids.ContainsKey(thingId)) {
|
||||
// Neuroid fakeInput = fakeNeuroids[thingId];
|
||||
// Synapse synapse = this.synapses[fakeInput];
|
||||
// synapse.value = value;
|
||||
// synapse.weight = weight;
|
||||
// }
|
||||
// else {
|
||||
// fakeNeuroids[thingId] = new(net);
|
||||
// this.synapses[fakeNeuroids[thingId]] = new(null, value, weight);
|
||||
// }
|
||||
// UpdateState();
|
||||
// }
|
||||
|
||||
protected virtual void UpdateState() {
|
||||
Vector3 sum = Vector3.zero;
|
||||
foreach (Synapse synapse in this.newSynapses.Values)
|
||||
sum += synapse.value * synapse.weight;
|
||||
|
||||
this.outputValue = Activation(sum);
|
||||
foreach (Neuroid neuroid in outputNeuroids) {
|
||||
neuroid?.SetInput(this, this.outputValue);
|
||||
Vector3 result = Vector3.zero;
|
||||
foreach (Synapse synapse in this.synapses.Values) {
|
||||
Vector3 direction = synapse.value.normalized;
|
||||
float magnitude = synapse.value.magnitude;
|
||||
magnitude = synapse.weight * Mathf.Pow(magnitude, exponent);
|
||||
if (inverse)
|
||||
magnitude = 1 / magnitude;
|
||||
result += direction * magnitude;
|
||||
}
|
||||
this.stale = 0;
|
||||
}
|
||||
if (average && this.synapses.Count > 0)
|
||||
result /= this.synapses.Count;
|
||||
|
||||
Vector3 Activation(Vector3 sum) {
|
||||
if (this.newSynapses.Count == 0 && mode == Mode.Average)
|
||||
Debug.LogWarning($"{this.name} has zero synapses for average");
|
||||
if (float.IsNaN(sum.magnitude))
|
||||
Debug.LogWarning($"{this.name} sum is nan");
|
||||
return mode switch {
|
||||
Mode.Sum => sum,
|
||||
Mode.Average => sum / this.newSynapses.Count,
|
||||
_ => sum,
|
||||
};
|
||||
//return sum; //(sum.magnitude > 0.5f) ? sum : Vector3.zero;
|
||||
this.outputValue = result;
|
||||
foreach (Neuroid neuroid in outputNeuroids)
|
||||
neuroid.SetInput(this, this.outputValue);
|
||||
this.stale = 0;
|
||||
}
|
||||
|
||||
public bool IsStale() {
|
||||
|
||||
@ -3,40 +3,33 @@ using UnityEngine;
|
||||
|
||||
public class Perception {
|
||||
public SensoryNeuroid[] sensoryNeuroids = new SensoryNeuroid[7];
|
||||
//public Neuroid[] velocitySensors = new Neuroid[7];
|
||||
|
||||
public NeuroidNetwork neuroidNet { get; protected set; }
|
||||
|
||||
public HashSet<Neuroid> receivers { get; protected set; }
|
||||
public HashSet<Neuroid> positionReceivers { get; protected set; }
|
||||
public HashSet<Neuroid> velocityReceivers { get; protected set; }
|
||||
|
||||
public Perception(NeuroidNetwork neuroidNet) {
|
||||
this.neuroidNet = neuroidNet;
|
||||
this.receivers = new();
|
||||
this.positionReceivers = new();
|
||||
this.velocityReceivers = new();
|
||||
}
|
||||
|
||||
// public void SendOutputTo(Neuroid receiver) {
|
||||
// foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
|
||||
// if (neuroid != null) {
|
||||
// neuroid.AddReceiver(receiver);
|
||||
// receiver.newSynapses[neuroid] = new (neuroid, Vector3.zero, 1.0f);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public void SendPositions(Neuroid receiver) {
|
||||
receivers.Add(receiver);
|
||||
public void SendPositions(Neuroid receiver, float weight = 1.0f) {
|
||||
positionReceivers.Add(receiver);
|
||||
foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
|
||||
if (neuroid != null) {
|
||||
neuroid.AddReceiver(receiver);
|
||||
receiver.newSynapses[neuroid] = new (neuroid, Vector3.zero, 1.0f);
|
||||
receiver.synapses[neuroid] = new (neuroid, Vector3.zero, weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void SendVelocities(Neuroid receiver) {
|
||||
receivers.Add(receiver);
|
||||
velocityReceivers.Add(receiver);
|
||||
foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
|
||||
if (neuroid != null && neuroid.velocityNeuroid != null) {
|
||||
neuroid.velocityNeuroid.AddReceiver(receiver);
|
||||
receiver.newSynapses[neuroid] = new (neuroid, Vector3.zero, 1.0f);
|
||||
receiver.synapses[neuroid] = new (neuroid, Vector3.zero, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -65,8 +58,10 @@ public class Perception {
|
||||
else {
|
||||
// Debug.Log($"new receptor for {thingId}");
|
||||
SensoryNeuroid neuroid = new(neuroidNet, thingId);
|
||||
foreach (Neuroid receiver in receivers)
|
||||
foreach (Neuroid receiver in positionReceivers)
|
||||
receiver.GetInputFrom(neuroid);
|
||||
foreach (Neuroid receiver in velocityReceivers)
|
||||
receiver.GetInputFrom(neuroid.velocityNeuroid);
|
||||
|
||||
sensoryNeuroids[availableIx] = neuroid;
|
||||
neuroid.receptor.position = localPosition;
|
||||
|
||||
@ -7,8 +7,7 @@ public class SensoryNeuroid : Neuroid {
|
||||
public Receptor receptor;
|
||||
public VelocityNeuroid velocityNeuroid;
|
||||
|
||||
public SensoryNeuroid(NeuroidNetwork net, int thingId) : base(net) {
|
||||
this.name = "sensory neuroid";
|
||||
public SensoryNeuroid(NeuroidNetwork net, int thingId) : base(net, "sensory neuroid") {
|
||||
this.receptor = new Receptor {
|
||||
neuroid = this,
|
||||
thingId = thingId
|
||||
@ -31,7 +30,7 @@ public class Receptor {
|
||||
public virtual Vector3 position {
|
||||
get {
|
||||
if (neuroid != null)
|
||||
return neuroid.newSynapses[neuroid].value;
|
||||
return neuroid.synapses[neuroid].value;
|
||||
else
|
||||
return Vector3.zero;
|
||||
}
|
||||
@ -47,12 +46,12 @@ public class VelocityNeuroid : Neuroid {
|
||||
private Vector3 lastPosition = Vector3.zero;
|
||||
private float lastValueTime = 0;
|
||||
|
||||
public VelocityNeuroid(NeuroidNetwork net) : base(net) {
|
||||
public VelocityNeuroid(NeuroidNetwork net) : base(net, "Velocity") {
|
||||
}
|
||||
|
||||
protected override void UpdateState() {
|
||||
// Assuming only one synapse for now....
|
||||
Vector3 currentPosition = this.newSynapses.First().Value.value;
|
||||
Vector3 currentPosition = this.synapses.First().Value.value;
|
||||
float currentValueTime = Time.time;
|
||||
|
||||
float deltaTime = currentValueTime - lastValueTime;
|
||||
|
||||
@ -377,7 +377,6 @@ MonoBehaviour:
|
||||
cohesionForce: 5
|
||||
separationForce: 5
|
||||
separationDistance: 0.3
|
||||
bodyForce: 20
|
||||
perceptionDistance: 1
|
||||
boundaryForce: 5
|
||||
spaceSize: {x: 10, y: 10, z: 10}
|
||||
@ -394,7 +393,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: ec888ca5333d45a438f9f417fa5ce135, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::SwarmSpawn
|
||||
count: 5
|
||||
count: 10
|
||||
boidPrefab: {fileID: 8702527964058765413, guid: f9c706268554ce449a8773675b2864b8, type: 3}
|
||||
spawnAreaSize: {x: 0.5, y: 0.5, z: 0.5}
|
||||
minDelay: 0.05
|
||||
|
||||
@ -11,6 +11,8 @@ public class Boid : MonoBehaviour {
|
||||
public float separationDistance = 0.5f;
|
||||
public float bodyForce = 1;
|
||||
|
||||
public bool debug = false;
|
||||
|
||||
public SwarmControl sc;
|
||||
public Vector3 velocity = Vector3.zero;
|
||||
public Vector3 acceleration = Vector3.zero;
|
||||
@ -27,7 +29,7 @@ public class Boid : MonoBehaviour {
|
||||
public Neuroid cohesion;
|
||||
public Neuroid alignment;
|
||||
public Neuroid separation;
|
||||
public Neuroid target;
|
||||
// public Neuroid target;
|
||||
public Neuroid boundary;
|
||||
|
||||
public Neuroid totalForce;
|
||||
@ -42,34 +44,28 @@ public class Boid : MonoBehaviour {
|
||||
bounds = new(sc.transform.position, sc.spaceSize - 2 * sc.boundaryWidth);
|
||||
|
||||
perception = new Perception(neuroidNet);
|
||||
//neighbourSensor = new(neuroidNet) { name = "Neighbour", id = 879 };
|
||||
|
||||
cohesion = new(neuroidNet) { name = "Cohesion", mode = Neuroid.Mode.Sum };
|
||||
cohesion = new(neuroidNet, "Cohesion");
|
||||
perception.SendPositions(cohesion);
|
||||
//cohesion.GetInputFrom(neighbourSensor);
|
||||
alignment = new(neuroidNet) { name = "Alignment", mode = Neuroid.Mode.Average };
|
||||
//perception.SendVelocities(alignment);
|
||||
separation = new(neuroidNet) { name = "Separation", mode = Neuroid.Mode.Sum };
|
||||
target = new(neuroidNet) { name = "Target", mode = Neuroid.Mode.Sum };
|
||||
boundary = new(neuroidNet) { name = "Boundary", mode = Neuroid.Mode.Sum };
|
||||
|
||||
alignment = new(neuroidNet, "Alignment") { average = true };
|
||||
perception.SendVelocities(alignment);
|
||||
|
||||
separation = new(neuroidNet, "Separation") { inverse = true, exponent = 2 };
|
||||
perception.SendPositions(separation, sc.separationForce);
|
||||
|
||||
boundary = new(neuroidNet, "Boundary");
|
||||
|
||||
|
||||
totalForce = new(neuroidNet) { name = "Total force", mode = Neuroid.Mode.Sum };
|
||||
totalForce = new(neuroidNet, "Total");
|
||||
totalForce.GetInputFrom(alignment, sc.alignmentForce);
|
||||
totalForce.GetInputFrom(cohesion, sc.cohesionForce);
|
||||
totalForce.GetInputFrom(separation, sc.separationForce);
|
||||
totalForce.GetInputFrom(target, sc.bodyForce);
|
||||
totalForce.GetInputFrom(separation, -sc.separationForce);
|
||||
totalForce.GetInputFrom(boundary, sc.boundaryForce);
|
||||
}
|
||||
|
||||
void Update() {
|
||||
Physics.OverlapSphereNonAlloc(this.transform.position, sc.perceptionDistance, results);
|
||||
neighbourCount = 0;
|
||||
|
||||
cohesion.ResetWeights();
|
||||
alignment.ResetWeights();
|
||||
//separation.ResetWeights();
|
||||
|
||||
foreach (Collider c in results) {
|
||||
if (c == null)
|
||||
continue;
|
||||
@ -80,45 +76,40 @@ public class Boid : MonoBehaviour {
|
||||
continue;
|
||||
|
||||
Vector3 localPosition = neighbour.transform.position - this.transform.position;
|
||||
Vector3 relativeVelocity = neighbour.velocity - this.velocity;
|
||||
if (debug)
|
||||
Debug.Log($" distance {localPosition.magnitude}");
|
||||
|
||||
int thingId = neighbour.GetInstanceID();
|
||||
perception.ProcessStimulus(thingId, localPosition);
|
||||
|
||||
Vector3 separationForce = -localPosition / localPosition.sqrMagnitude;
|
||||
// which is equivalent to -(localPosition.normalized / localPosition.magnitude)
|
||||
|
||||
separation.SetInput(thingId, separationForce, sc.separationDistance, neuroidNet);
|
||||
//cohesion.SetInput(thingId, localPosition, sc.cohesionForce);
|
||||
alignment.SetInput(thingId, relativeVelocity, sc.alignmentForce, neuroidNet);
|
||||
neighbourCount++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Vector3 spaceLocalPosition = sc.transform.InverseTransformPoint(this.transform.position);
|
||||
if (!bounds.Contains(this.transform.position)) {
|
||||
Vector3 point = this.transform.position;
|
||||
// Vector3 distanceOutside = Vector3.Max(bounds.min - this.transform.position, this.transform.position - bounds.max);
|
||||
// // Ensure value is > 0 (but isn't this already)
|
||||
// Vector3 outside = distanceOutside; // Vector3.Max(Vector3.zero, distanceOutside);
|
||||
// if (!bounds.Contains(this.transform.position)) {
|
||||
// Vector3 point = this.transform.position;
|
||||
// // Vector3 distanceOutside = Vector3.Max(bounds.min - this.transform.position, this.transform.position - bounds.max);
|
||||
// // // Ensure value is > 0 (but isn't this already)
|
||||
// // Vector3 outside = distanceOutside; // Vector3.Max(Vector3.zero, distanceOutside);
|
||||
|
||||
Vector3 below = bounds.min - point; // positive where point < min
|
||||
Vector3 above = point - bounds.max; // positive where point > max
|
||||
// Vector3 below = bounds.min - point; // positive where point < min
|
||||
// Vector3 above = point - bounds.max; // positive where point > max
|
||||
|
||||
// outside distances per axis (0 if inside on that axis)
|
||||
Vector3 outside = Vector3.Max(Vector3.zero, Vector3.Max(below, above));
|
||||
float magnitude = outside.magnitude;
|
||||
Vector3 direction = (sc.transform.position - this.transform.position).normalized;
|
||||
outside = direction * magnitude;
|
||||
// // outside distances per axis (0 if inside on that axis)
|
||||
// Vector3 outside = Vector3.Max(Vector3.zero, Vector3.Max(below, above));
|
||||
// float magnitude = outside.magnitude;
|
||||
// Vector3 direction = (sc.transform.position - this.transform.position).normalized;
|
||||
// outside = direction * magnitude;
|
||||
|
||||
boundary.SetInput(id, outside, sc.boundaryForce, neuroidNet);
|
||||
// Debug.Log($"boundary {this.transform.position} {outside} force = {outside * sc.boundaryForce}");
|
||||
}
|
||||
// boundary.SetInput(id, outside, sc.boundaryForce, neuroidNet);
|
||||
// // Debug.Log($"boundary {this.transform.position} {outside} force = {outside * sc.boundaryForce}");
|
||||
// }
|
||||
|
||||
Vector3 totalForceVector = totalForce.outputValue;
|
||||
//Debug.DrawRay(this.transform.position, totalForceVector, Color.magenta);
|
||||
|
||||
if (this.debug) {
|
||||
Debug.Log($"Cohesion {cohesion.outputValue.magnitude} separation {separation.outputValue.magnitude} alignment {alignment.outputValue.magnitude}");
|
||||
}
|
||||
|
||||
this.velocity = (1 - sc.inertia) * (totalForceVector * Time.deltaTime) + sc.inertia * velocity + (sc.speed * transform.forward);
|
||||
//this.velocity = Vector3.ClampMagnitude(this.velocity, sc.speed);
|
||||
|
||||
@ -132,74 +123,7 @@ public class Boid : MonoBehaviour {
|
||||
//Debug.Log($"neighbours: {neighbourCount} synapses: {cohesion.synapses.Count}");
|
||||
neuroidNet.Update();
|
||||
}
|
||||
/*
|
||||
Receptor GetReceptor(Neuroid perceptionNeuroid, int id) {
|
||||
int availableIx = -1;
|
||||
for (int i = 0; i < neighbourSensor.Length; i++) {
|
||||
if (neighbourSensor[i] == null || neighbourSensor[i].IsStale())
|
||||
availableIx = i;
|
||||
else if (neighbourSensor[i].thingId == id)
|
||||
return neighbourSensor[i].receptor;
|
||||
}
|
||||
if (availableIx != -1) {
|
||||
if (neighbourSensor[availableIx] != null) {
|
||||
Debug.Log($"revived receptor {availableIx} for {id}");
|
||||
neighbourSensor[availableIx].thingId = id;
|
||||
return neighbourSensor[availableIx].receptor;
|
||||
}
|
||||
else {
|
||||
Debug.Log($"new receptor for {id}");
|
||||
SensoryNeuroid neuroid = new(neuroidNet, id);
|
||||
perceptionNeuroid.GetInputFrom(neuroid);
|
||||
neighbourSensor[availableIx] = neuroid;
|
||||
return neuroid.receptor;
|
||||
}
|
||||
}
|
||||
|
||||
//Debug.LogWarning($"No available receptor for {id}");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void ProcessStimulus(int thingId, Vector3 value) {
|
||||
int availableIx = -1;
|
||||
SensoryNeuroid leastInterestingNeuroid = null;
|
||||
for (int i = 0; i < neighbourSensor.Length; i++) {
|
||||
if (neighbourSensor[i] == null || neighbourSensor[i].IsStale())
|
||||
availableIx = i;
|
||||
else if (neighbourSensor[i].thingId == thingId) {
|
||||
neighbourSensor[i].receptor.SetValue(value);
|
||||
return;
|
||||
}
|
||||
if (neighbourSensor[i] != null) {
|
||||
if (leastInterestingNeuroid == null || leastInterestingNeuroid.receptor.GetValue().magnitude > neighbourSensor[i].receptor.GetValue().magnitude)
|
||||
leastInterestingNeuroid = neighbourSensor[i];
|
||||
}
|
||||
}
|
||||
if (availableIx != -1) {
|
||||
if (neighbourSensor[availableIx] != null) {
|
||||
// Debug.Log($"revived receptor {availableIx} for {thingId}");
|
||||
neighbourSensor[availableIx].thingId = thingId;
|
||||
neighbourSensor[availableIx].receptor.SetValue(value);
|
||||
}
|
||||
else {
|
||||
// Debug.Log($"new receptor for {thingId}");
|
||||
SensoryNeuroid neuroid = new(neuroidNet, thingId);
|
||||
cohesion.GetInputFrom(neuroid);
|
||||
neighbourSensor[availableIx] = neuroid;
|
||||
neuroid.receptor.SetValue(value);
|
||||
}
|
||||
}
|
||||
else if (leastInterestingNeuroid != null) {
|
||||
//Debug.Log($"replaced receptor {leastInterestingNeuroid.thingId} for {thingId}");
|
||||
leastInterestingNeuroid.thingId = thingId;
|
||||
leastInterestingNeuroid.receptor.SetValue(value);
|
||||
}
|
||||
|
||||
//Debug.LogWarning($"No available receptor for {id}");
|
||||
}
|
||||
*/
|
||||
void OnDrawGizmosSelected() {
|
||||
Gizmos.DrawWireSphere(transform.position, sc.perceptionDistance);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ public class SwarmControl : MonoBehaviour
|
||||
public float cohesionForce = 10.0f;
|
||||
public float separationForce = 5.0f;
|
||||
public float separationDistance = 0.5f;
|
||||
public float bodyForce = 20;
|
||||
// public float bodyForce = 20;
|
||||
public float perceptionDistance = 1.0f;
|
||||
|
||||
public float boundaryForce = 2.0f;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user