More nucleus like neurons
This commit is contained in:
parent
88bf20b9c2
commit
9a6ae0e071
@ -5,13 +5,13 @@ using System.Collections.Generic;
|
||||
|
||||
public class NeuroidLayer {
|
||||
public int ix = 0;
|
||||
public List<Neuroid> neuroids = new();
|
||||
public List<Nucleus> neuroids = new();
|
||||
}
|
||||
|
||||
public class GraphEditorWindow : EditorWindow {
|
||||
private Neuroid currentNeuroid;
|
||||
private Nucleus currentNucleus;
|
||||
private List<Neuroid> allNeuroids;
|
||||
private Dictionary<Neuroid, Vector2Int> neuroidPositions = new();
|
||||
private Dictionary<Nucleus, Vector2Int> neuroidPositions = new();
|
||||
|
||||
private List<NeuroidLayer> layers = new();
|
||||
|
||||
@ -21,7 +21,58 @@ public class GraphEditorWindow : EditorWindow {
|
||||
SelectNeuron();
|
||||
}
|
||||
|
||||
private void BuildLayers(List<Neuroid> neuroids) {
|
||||
private void AddToLayer(NeuroidLayer layer, Nucleus nucleus) {
|
||||
layer.neuroids.Add(nucleus);
|
||||
nucleus.layerIx = layer.ix;
|
||||
// Store its position
|
||||
Vector2Int neuroidPosition = new(layer.ix, layer.neuroids.Count - 1);
|
||||
neuroidPositions[nucleus] = neuroidPosition;
|
||||
|
||||
}
|
||||
|
||||
private void BuildLayers() {
|
||||
// A temporary list to track what's been added to layers
|
||||
this.layers = new();
|
||||
int layerIx = 0;
|
||||
|
||||
Nucleus selectedNucleus = this.currentNucleus;
|
||||
NeuroidLayer currentLayer = new() { ix = layerIx };
|
||||
|
||||
foreach (Neuroid outputNeuroid in selectedNucleus.outputNeuroids) {
|
||||
if (outputNeuroid != null) {
|
||||
AddToLayer(currentLayer, outputNeuroid);
|
||||
Debug.Log($"layer {layerIx} nucleus {outputNeuroid.name}");
|
||||
}
|
||||
}
|
||||
if (currentLayer.neuroids.Count > 0) {
|
||||
this.layers.Add(currentLayer);
|
||||
layerIx++;
|
||||
currentLayer = new() { ix = layerIx };
|
||||
}
|
||||
|
||||
AddToLayer(currentLayer, selectedNucleus);
|
||||
this.layers.Add(currentLayer);
|
||||
Debug.Log($"layer {layerIx} nucleus {selectedNucleus.name}");
|
||||
|
||||
layerIx++;
|
||||
currentLayer = new() { ix = layerIx };
|
||||
|
||||
int six = 0;
|
||||
foreach (Synapse synapse in selectedNucleus.synapses.Values) {
|
||||
Debug.Log($"Synapse {six}");
|
||||
Nucleus input = synapse.neuroid;
|
||||
if (input != null) {
|
||||
AddToLayer(currentLayer, input);
|
||||
Debug.Log($"layer {layerIx} nucleus {input.name}");
|
||||
}
|
||||
six++;
|
||||
}
|
||||
if (currentLayer.neuroids.Count > 0) {
|
||||
this.layers.Add(currentLayer);
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildLayers_old(List<Neuroid> neuroids) {
|
||||
if (neuroids == null)
|
||||
return;
|
||||
|
||||
@ -41,10 +92,11 @@ public class GraphEditorWindow : EditorWindow {
|
||||
if (neuronVisited.Contains(neuroid))
|
||||
continue;
|
||||
|
||||
if (neuroid.IsStale()) {
|
||||
neuronVisited.Add(neuroid);
|
||||
continue;
|
||||
}
|
||||
// if (neuroid.IsStale()) {
|
||||
// Debug.Log($"neuron {neuroid.name} is stale {neuroid.stale}");
|
||||
// neuronVisited.Add(neuroid);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// If the output neuroid is visited
|
||||
// Note: this does not yet work for multiple outputs yet (see the use of First())
|
||||
@ -92,7 +144,7 @@ public class GraphEditorWindow : EditorWindow {
|
||||
}
|
||||
|
||||
private void DrawGraph() {
|
||||
if (currentNeuroid == null)
|
||||
if (currentNucleus == null)
|
||||
return;
|
||||
|
||||
foreach (NeuroidLayer layer in layers)
|
||||
@ -103,25 +155,29 @@ public class GraphEditorWindow : EditorWindow {
|
||||
int column = layer.ix * 100;
|
||||
int nodeCount = layer.neuroids.Count;
|
||||
float maxValue = 0;
|
||||
foreach (Neuroid neuroid in layer.neuroids) {
|
||||
foreach (Nucleus nucleus in layer.neuroids) {
|
||||
if (nucleus is Neuroid neuroid) {
|
||||
float value = neuroid.outputValue.magnitude;
|
||||
if (value > maxValue)
|
||||
maxValue = value;
|
||||
}
|
||||
float spacing = 200f / nodeCount;
|
||||
}
|
||||
float spacing = 400f / nodeCount;
|
||||
float margin = 100 + spacing / 2;
|
||||
foreach (Neuroid layerNeuroid in layer.neuroids) {
|
||||
foreach (Nucleus layerNucleus in layer.neuroids) {
|
||||
if (layerNucleus is Neuroid layerNeuroid) {
|
||||
Vector2Int layerNeuroidPos = this.neuroidPositions[layerNeuroid];
|
||||
Vector3 parentPos = new(100 + layerNeuroidPos.x * 100, margin + layerNeuroidPos.y * spacing, 0.1f);
|
||||
|
||||
int i = 0;
|
||||
float inputSpacing = 200f / layerNeuroid.synapses.Count;
|
||||
float inputSpacing = 400f / layerNeuroid.synapses.Count;
|
||||
float inputMargin = 100 + inputSpacing / 2;
|
||||
foreach (Synapse synapse in layerNeuroid.synapses.Values) {
|
||||
if (synapse.neuroid != null) {
|
||||
if (this.neuroidPositions.ContainsKey(synapse.neuroid)) {
|
||||
|
||||
Vector2Int inputNeuroidPos = this.neuroidPositions[synapse.neuroid];
|
||||
if (inputNeuroidPos.x == layerNeuroidPos.x + 1) {
|
||||
Vector3 pos = new(100 + inputNeuroidPos.x * 100, inputMargin + inputNeuroidPos.y * inputSpacing, 0.0f);
|
||||
|
||||
float brightness = synapse.weight / 10.0f;
|
||||
@ -130,28 +186,56 @@ public class GraphEditorWindow : EditorWindow {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float size = layerNeuroid.outputValue.magnitude / maxValue * 20;
|
||||
float size = 20;
|
||||
if (layerNeuroid.IsStale())
|
||||
Handles.color = Color.yellow;
|
||||
else
|
||||
Handles.color = Color.white;
|
||||
Handles.color = Color.black;
|
||||
else {
|
||||
float brightness = layerNeuroid.outputValue.magnitude / maxValue;
|
||||
Handles.color = new Color(brightness, brightness, brightness);
|
||||
}
|
||||
Handles.DrawSolidDisc(parentPos, Vector3.forward, size);
|
||||
Rect neuronRect = new(parentPos.x - size, parentPos.y - size, size * 2, size * 2);
|
||||
if (neuronRect.Contains(Event.current.mousePosition))
|
||||
HandleMouseHover(layerNeuroid, neuronRect);
|
||||
i++;
|
||||
Vector3 labelPos = parentPos - Vector3.down * (size + 0.2f); // below disc along up axis
|
||||
GUIStyle style = new GUIStyle(EditorStyles.label) {
|
||||
alignment = TextAnchor.UpperCenter,
|
||||
normal = { textColor = Color.white },
|
||||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
Handles.Label(labelPos, layerNeuroid.name, style);
|
||||
|
||||
Rect neuronRect = new(parentPos.x - size, parentPos.y - size, size * 2, size * 2);
|
||||
Event e = Event.current;
|
||||
if (e != null && neuronRect.Contains(e.mousePosition)) {
|
||||
HandleMouseHover(layerNeuroid, neuronRect);
|
||||
// Process click
|
||||
if (e.type == EventType.MouseDown && e.button == 0) {
|
||||
// Consume the event so the scene doesn't also handle it
|
||||
e.Use();
|
||||
HandleDiscClicked(layerNeuroid);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMouseHover(Neuroid neuroid, Rect rect) {
|
||||
// Draw the tooltip
|
||||
GUIContent tooltip = new(
|
||||
GUIContent tooltip;
|
||||
if (neuroid is SensoryNeuroid sensoryNeuroid) {
|
||||
tooltip = new(
|
||||
$"{sensoryNeuroid.name}" +
|
||||
$"\nThing {sensoryNeuroid.receptor.thingId}" +
|
||||
$"\nValue: {neuroid.outputValue}" +
|
||||
$"\nStale: {neuroid.stale}");
|
||||
}
|
||||
else {
|
||||
tooltip = new(
|
||||
$"{neuroid.name}" +
|
||||
$"\nsynapse count {neuroid.synapses.Count}" +
|
||||
$"\nValue: {neuroid.outputValue}" +
|
||||
$"\nStale: {neuroid.stale}");
|
||||
}
|
||||
|
||||
Vector2 mousePosition = Event.current.mousePosition;
|
||||
|
||||
@ -162,6 +246,10 @@ public class GraphEditorWindow : EditorWindow {
|
||||
GUI.Box(tooltipRect, tooltip);
|
||||
}
|
||||
|
||||
private void HandleDiscClicked(Nucleus nucleus) {
|
||||
this.currentNucleus = nucleus;
|
||||
BuildLayers();
|
||||
}
|
||||
|
||||
// Update node colors based on selected GameObjects
|
||||
private void SelectNeuron() {
|
||||
@ -175,15 +263,15 @@ public class GraphEditorWindow : EditorWindow {
|
||||
return;
|
||||
|
||||
Neuroid neuroid = boid.totalForce;
|
||||
this.currentNeuroid = neuroid;
|
||||
this.currentNucleus = neuroid;
|
||||
if (neuroid == null)
|
||||
this.allNeuroids = new();
|
||||
else
|
||||
this.allNeuroids = neuroid.net.neuroids;
|
||||
|
||||
|
||||
//Debug.Log($"Neuroncount = {this.allNeuroids.Count}");
|
||||
BuildLayers(this.allNeuroids);
|
||||
Debug.Log($"Neuroncount = {this.allNeuroids.Count}");
|
||||
BuildLayers();
|
||||
Debug.Log($"Layercount = {this.layers.Count}");
|
||||
|
||||
}
|
||||
|
||||
@ -3,12 +3,12 @@ using UnityEngine;
|
||||
using System.Linq;
|
||||
|
||||
public class Synapse {
|
||||
public Synapse(Neuroid neuroid, Vector3 value, float weight) {
|
||||
public Synapse(Nucleus neuroid, Vector3 value, float weight) {
|
||||
this.neuroid = neuroid;
|
||||
this.value = value;
|
||||
this.weight = weight;
|
||||
}
|
||||
public Neuroid neuroid;
|
||||
public Nucleus neuroid;
|
||||
public Vector3 value;
|
||||
public float weight;
|
||||
}
|
||||
@ -24,19 +24,16 @@ public class NeuroidNetwork {
|
||||
public void Update() {
|
||||
foreach (Neuroid neuroid in neuroids) {
|
||||
neuroid.stale++;
|
||||
if (neuroid.IsStale())
|
||||
neuroid.outputValue = Vector3.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Neuroid : Nucleus {
|
||||
public string name;
|
||||
|
||||
public int stale = 0;
|
||||
|
||||
// public readonly Dictionary<Neuroid, Synapse> synapses = new();
|
||||
|
||||
public Vector3 outputValue;
|
||||
// public HashSet<Neuroid> outputNeuroids = new();
|
||||
//public Vector3 outputValue;
|
||||
|
||||
public bool average = false;
|
||||
//public bool quadratic = false;
|
||||
@ -45,11 +42,12 @@ public class Neuroid : Nucleus {
|
||||
|
||||
public NeuroidNetwork net;
|
||||
|
||||
public Neuroid(NeuroidNetwork net, string name) : base(net) {
|
||||
public Neuroid(NeuroidNetwork net, string name) : base(name) {
|
||||
this.net = net;
|
||||
this.name = name;
|
||||
if (this.net != null)
|
||||
this.net.neuroids.Add(this);
|
||||
else
|
||||
Debug.LogError("No neuroid network");
|
||||
}
|
||||
|
||||
public void AddSynapse(Neuroid input) {
|
||||
@ -129,8 +127,14 @@ public class Neuroid : Nucleus {
|
||||
protected virtual void UpdateState() {
|
||||
Vector3 result = Vector3.zero;
|
||||
foreach (Synapse synapse in this.synapses.Values) {
|
||||
// if (synapse.neuroid == null)
|
||||
// continue;
|
||||
Vector3 direction = synapse.value.normalized;
|
||||
float magnitude = synapse.value.magnitude;
|
||||
|
||||
// Vector3 direction = synapse.neuroid.outputValue.normalized;
|
||||
// float magnitude = synapse.neuroid.outputValue.magnitude;
|
||||
|
||||
magnitude = synapse.weight * Mathf.Pow(magnitude, exponent);
|
||||
if (inverse)
|
||||
magnitude = 1 / magnitude;
|
||||
|
||||
@ -1,26 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class Nucleus {
|
||||
//public Neuroid output;
|
||||
public readonly Dictionary<Neuroid, Synapse> synapses = new();
|
||||
public string name;
|
||||
|
||||
public readonly Dictionary<Nucleus, Synapse> synapses = new();
|
||||
public HashSet<Neuroid> outputNeuroids = new();
|
||||
public virtual Vector3 outputValue {get; set; }
|
||||
|
||||
public int layerIx;
|
||||
|
||||
|
||||
public Nucleus(NeuroidNetwork neuroidNet) {
|
||||
//this.output = new(neuroidNet, "Nucleus output");
|
||||
public Nucleus(string name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public virtual void AddReceiver(Neuroid receiver) {
|
||||
//this.output.AddReceiver(receiver);
|
||||
this.outputNeuroids.Add(receiver);
|
||||
receiver.synapses[this] = new(this, Vector3.zero, 1.0f);
|
||||
}
|
||||
|
||||
// public void GetInputFrom(Neuroid input, float weight = 1.0f) {
|
||||
// input.AddReceiver(this);
|
||||
// this.synapses[input] = new(input, Vector3.zero, weight);
|
||||
// }
|
||||
|
||||
}
|
||||
@ -15,7 +15,7 @@ public class Perception : Nucleus {
|
||||
public HashSet<Receiver> positionReceivers { get; protected set; }
|
||||
public HashSet<Receiver> velocityReceivers { get; protected set; }
|
||||
|
||||
public Perception(NeuroidNetwork neuroidNet) : base(neuroidNet) {
|
||||
public Perception(NeuroidNetwork neuroidNet) : base("Perception") {
|
||||
this.neuroidNet = neuroidNet;
|
||||
this.positionReceivers = new();
|
||||
this.velocityReceivers = new();
|
||||
@ -48,9 +48,9 @@ public class Perception : Nucleus {
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessStimulus(int thingId, int thingType, Vector3 localPosition) {
|
||||
public void ProcessStimulus(int thingId, int thingType, Vector3 localPosition, string name = "Sensing") {
|
||||
int availableIx = -1;
|
||||
SensoryNeuroid leastInterestingNeuroid = null;
|
||||
int leastInterestingIx = -1;
|
||||
for (int i = 0; i < sensoryNeuroids.Length; i++) {
|
||||
if (sensoryNeuroids[i] == null || sensoryNeuroids[i].IsStale())
|
||||
availableIx = i;
|
||||
@ -59,19 +59,16 @@ public class Perception : Nucleus {
|
||||
return;
|
||||
}
|
||||
if (sensoryNeuroids[i] != null) {
|
||||
if (leastInterestingNeuroid == null || leastInterestingNeuroid.receptor.position.magnitude > sensoryNeuroids[i].receptor.position.magnitude)
|
||||
leastInterestingNeuroid = sensoryNeuroids[i];
|
||||
if (leastInterestingIx == -1 || sensoryNeuroids[leastInterestingIx].receptor.position.magnitude > sensoryNeuroids[i].receptor.position.magnitude)
|
||||
leastInterestingIx = i;
|
||||
}
|
||||
}
|
||||
if (availableIx == -1)
|
||||
availableIx = leastInterestingIx;
|
||||
|
||||
if (availableIx != -1) {
|
||||
if (sensoryNeuroids[availableIx] != null) {
|
||||
// Debug.Log($"revived receptor {availableIx} for {thingId}");
|
||||
sensoryNeuroids[availableIx].receptor.thingId = thingId;
|
||||
sensoryNeuroids[availableIx].receptor.position = localPosition;
|
||||
}
|
||||
else {
|
||||
// Debug.Log($"new receptor for {thingId}");
|
||||
SensoryNeuroid neuroid = new(neuroidNet, thingId);
|
||||
SensoryNeuroid neuroid = new(neuroidNet, thingId) { name = name };
|
||||
foreach (Receiver receiver in positionReceivers) {
|
||||
if (receiver.thingType == 0 || receiver.thingType == thingType)
|
||||
receiver.neuroid.GetInputFrom(neuroid);
|
||||
@ -85,14 +82,6 @@ public class Perception : Nucleus {
|
||||
neuroid.receptor.position = localPosition;
|
||||
}
|
||||
}
|
||||
else if (leastInterestingNeuroid != null) {
|
||||
//Debug.Log($"replaced receptor {leastInterestingNeuroid.thingId} for {thingId}");
|
||||
leastInterestingNeuroid.receptor.thingId = thingId;
|
||||
leastInterestingNeuroid.receptor.position = localPosition;
|
||||
}
|
||||
|
||||
//Debug.LogWarning($"No available receptor for {id}");
|
||||
}
|
||||
|
||||
public void RemoveStimulus(int thingId) {
|
||||
for (int i = 0; i < sensoryNeuroids.Length; i++) {
|
||||
|
||||
@ -393,7 +393,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: ec888ca5333d45a438f9f417fa5ce135, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::SwarmSpawn
|
||||
count: 1
|
||||
count: 2
|
||||
boidPrefab: {fileID: 8702527964058765413, guid: f9c706268554ce449a8773675b2864b8, type: 3}
|
||||
spawnAreaSize: {x: 0.5, y: 0.5, z: 0.5}
|
||||
minDelay: 0.05
|
||||
|
||||
@ -21,15 +21,10 @@ public class Boid : MonoBehaviour {
|
||||
private Bounds innerBounds;
|
||||
private Bounds outerBounds;
|
||||
|
||||
readonly Collider[] results = new Collider[10];
|
||||
|
||||
public NeuroidNetwork neuroidNet = new();
|
||||
public Perception perception;
|
||||
public Neuroid cohesion;
|
||||
public Neuroid alignment;
|
||||
public Neuroid avoidance;
|
||||
// public Neuroid boundary;
|
||||
public Roaming roaming;
|
||||
|
||||
public Nucleus behaviour;
|
||||
|
||||
public Neuroid totalForce;
|
||||
|
||||
@ -45,53 +40,34 @@ public class Boid : MonoBehaviour {
|
||||
|
||||
perception = new Perception(neuroidNet);
|
||||
|
||||
// cohesion = new(neuroidNet, "Cohesion");
|
||||
// perception.SendPositions(cohesion, 1.0f, BoidType);
|
||||
|
||||
// alignment = new(neuroidNet, "Alignment") { average = true };
|
||||
// perception.SendVelocities(alignment);
|
||||
|
||||
// avoidance = new(neuroidNet, "Separation") { inverse = true };
|
||||
// perception.SendPositions(avoidance, sc.avoidanceForce);
|
||||
|
||||
//boundary = new(neuroidNet, "Boundary");
|
||||
|
||||
roaming = new(neuroidNet, perception, sc);
|
||||
//behaviour = new Roaming(neuroidNet, perception, sc);
|
||||
behaviour = new Swarming(neuroidNet, perception, sc);
|
||||
|
||||
totalForce = new(neuroidNet, "Total");
|
||||
//totalForce.GetInputFrom(alignment, sc.alignmentForce);
|
||||
//totalForce.GetInputFrom(cohesion, sc.cohesionForce);
|
||||
// totalForce.GetInputFrom(avoidance, -sc.avoidanceForce);
|
||||
//totalForce.GetInputFrom(boundary, sc.boundaryForce);
|
||||
roaming.AddReceiver(totalForce);
|
||||
behaviour.AddReceiver(totalForce);
|
||||
}
|
||||
|
||||
void Update() {
|
||||
// Physics.OverlapSphereNonAlloc(this.transform.position, sc.perceptionDistance, results);
|
||||
// foreach (Collider c in results) {
|
||||
// if (c == null)
|
||||
// continue;
|
||||
Collider[] results = Physics.OverlapSphere(this.transform.position, sc.perceptionDistance);
|
||||
foreach (Collider c in results) {
|
||||
if (c as CapsuleCollider != null) {
|
||||
Boid neighbour = c.GetComponentInParent<Boid>();
|
||||
if (neighbour == null || neighbour == this)
|
||||
continue;
|
||||
|
||||
// if (c as CapsuleCollider != null) {
|
||||
// Boid neighbour = c.GetComponentInParent<Boid>();
|
||||
// if (neighbour == null || neighbour == this)
|
||||
// continue;
|
||||
Vector3 localPosition = neighbour.transform.position - this.transform.position;
|
||||
|
||||
// Vector3 localPosition = neighbour.transform.position - this.transform.position;
|
||||
// if (debug)
|
||||
// Debug.Log($" distance {localPosition.magnitude}");
|
||||
|
||||
// int thingId = neighbour.GetInstanceID();
|
||||
// perception.ProcessStimulus(thingId, localPosition);
|
||||
// }
|
||||
// }
|
||||
int thingId = neighbour.GetInstanceID();
|
||||
perception.ProcessStimulus(thingId, BoidType, localPosition); //, neighbour.gameObject.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!innerBounds.Contains(this.transform.position)) {
|
||||
Vector3 point = this.transform.position;
|
||||
Vector3 pointOnBounds = innerBounds.ClosestPoint(point);
|
||||
Vector3 desiredWorldSpace = (pointOnBounds - point).normalized * sc.speed;
|
||||
Vector3 desiredLocalSpace = -this.transform.InverseTransformPoint(desiredWorldSpace);
|
||||
perception.ProcessStimulus(777, BoundaryType, desiredLocalSpace);
|
||||
perception.ProcessStimulus(777, BoundaryType, desiredLocalSpace, "Boundary");
|
||||
}
|
||||
else {
|
||||
perception.RemoveStimulus(777);
|
||||
|
||||
@ -1,18 +1,11 @@
|
||||
public class Roaming : Nucleus {
|
||||
public float avoidanceForce;
|
||||
public Neuroid avoidance;
|
||||
|
||||
public Neuroid output;
|
||||
|
||||
|
||||
public const int BoundaryType = 1;
|
||||
public const int BoidType = 2;
|
||||
|
||||
public Roaming(NeuroidNetwork neuroidNet, Perception perception, SwarmControl sc) : base(neuroidNet) {
|
||||
this.avoidanceForce = sc.avoidanceForce;
|
||||
|
||||
public Roaming(NeuroidNetwork neuroidNet, Perception perception, SwarmControl sc) : base("Roaming nucleus") {
|
||||
avoidance = new(neuroidNet, "Avoidance") { inverse = true };
|
||||
perception.SendPositions(avoidance);
|
||||
perception.SendPositions(avoidance, 1.0f, 1);
|
||||
|
||||
this.output = new(neuroidNet, "Roaming");
|
||||
output.GetInputFrom(avoidance, -sc.avoidanceForce);
|
||||
|
||||
@ -1,31 +1,34 @@
|
||||
public class Swarming : Nucleus {
|
||||
//public Perception perception;
|
||||
using UnityEngine;
|
||||
|
||||
public class Swarming : Nucleus {
|
||||
public Neuroid cohesion;
|
||||
public Neuroid alignment;
|
||||
public Neuroid avoidance;
|
||||
public Neuroid boundary;
|
||||
|
||||
public Neuroid output;
|
||||
|
||||
public override Vector3 outputValue { get => output.outputValue; set => output.outputValue = value; }
|
||||
|
||||
public const int BoundaryType = 1;
|
||||
public const int BoidType = 2;
|
||||
|
||||
public Swarming(NeuroidNetwork neuroidNet, Perception perception, SwarmControl sc) : base(neuroidNet) {
|
||||
cohesion = new(neuroidNet, "Cohesion");
|
||||
perception.SendPositions(cohesion, 1.0f, BoidType);
|
||||
public Swarming(NeuroidNetwork neuroidNet, Perception perception, SwarmControl sc) : base("Swarming Nucleus") {
|
||||
this.cohesion = new(neuroidNet, "Cohesion");
|
||||
perception.SendPositions(this.cohesion, 1.0f, BoidType);
|
||||
|
||||
alignment = new(neuroidNet, "Alignment") { average = true };
|
||||
perception.SendVelocities(alignment);
|
||||
this.alignment = new(neuroidNet, "Alignment") { average = true };
|
||||
perception.SendVelocities(this.alignment, 1.0f, BoidType);
|
||||
|
||||
avoidance = new(neuroidNet, "Separation") { inverse = true };
|
||||
perception.SendPositions(avoidance, sc.avoidanceForce);
|
||||
|
||||
boundary = new(neuroidNet, "Boundary");
|
||||
this.avoidance = new(neuroidNet, "Avoidance") { inverse = true };
|
||||
perception.SendPositions(this.avoidance);
|
||||
|
||||
this.output = new(neuroidNet, "Swarming");
|
||||
output.GetInputFrom(alignment, sc.alignmentForce);
|
||||
output.GetInputFrom(cohesion, sc.cohesionForce);
|
||||
output.GetInputFrom(avoidance, -sc.avoidanceForce);
|
||||
output.GetInputFrom(boundary, sc.boundaryForce);
|
||||
}}
|
||||
//this.output.GetInputFrom(alignment, sc.alignmentForce);
|
||||
this.output.GetInputFrom(cohesion, sc.cohesionForce);
|
||||
this.output.GetInputFrom(avoidance, -sc.avoidanceForce);
|
||||
}
|
||||
|
||||
public override void AddReceiver(Neuroid receiver) {
|
||||
this.output.AddReceiver(receiver);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user