removed synapse type

This commit is contained in:
Pascal Serrarens 2025-12-03 15:15:42 +01:00
parent 145e033d4c
commit a3d49e330f
8 changed files with 161 additions and 166 deletions

View File

@ -26,6 +26,7 @@ public class NanoBrain_Editor : Editor {
Debug.Log($"Layercount = {this.layers.Count}");
}
#endregion Start
#region Update
@ -46,10 +47,10 @@ public class NanoBrain_Editor : Editor {
return;
NeuroidLayer currentLayer = new() { ix = layerIx };
foreach (Neuroid outputNeuroid in selectedNucleus.outputNeuroids) {
foreach (Neuroid outputNeuroid in selectedNucleus.receivers) {
if (outputNeuroid != null) {
AddToLayer(currentLayer, outputNeuroid);
Debug.Log($"layer {layerIx} nucleus {outputNeuroid.name}");
// Debug.Log($"layer {layerIx} nucleus {outputNeuroid.name}");
}
}
if (currentLayer.neuroids.Count > 0) {
@ -60,14 +61,14 @@ public class NanoBrain_Editor : Editor {
AddToLayer(currentLayer, selectedNucleus);
this.layers.Add(currentLayer);
Debug.Log($"layer {layerIx} nucleus {selectedNucleus.name}");
// Debug.Log($"layer {layerIx} nucleus {selectedNucleus.name}");
layerIx++;
currentLayer = new() { ix = layerIx };
foreach (Nucleus input in selectedNucleus.synapses.Keys) {
AddToLayer(currentLayer, input);
Debug.Log($"layer {layerIx} nucleus {input.name}");
// Debug.Log($"layer {layerIx} nucleus {input.name}");
}
if (currentLayer.neuroids.Count > 0) {
this.layers.Add(currentLayer);
@ -110,32 +111,32 @@ public class NanoBrain_Editor : Editor {
Vector2Int layerNeuroidPos = this.neuroidPositions[layerNeuroid];
Vector3 parentPos = new(100 + layerNeuroidPos.x * 100, margin + layerNeuroidPos.y * spacing, 0.1f);
int i = 0;
//int i = 0;
float inputSpacing = 400f / layerNeuroid.synapses.Count;
float inputMargin = 10 + inputSpacing / 2;
// foreach (Synapse synapse in layerNeuroid.synapses.Values) {
// if (synapse.neuroid != null) {
// if (this.neuroidPositions.ContainsKey(synapse.neuroid)) {
int minStale = 10000;
foreach ((Nucleus nucleus, float weight) in layerNeuroid.synapses) {
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);
// Vector2Int inputNeuroidPos = this.neuroidPositions[synapse.neuroid];
foreach ((Nucleus neuroid, Synapse synapse) in layerNeuroid.synapses) {
if (neuroid != null) {
if (this.neuroidPositions.ContainsKey(neuroid)) {
Vector2Int inputNeuroidPos = this.neuroidPositions[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;
Handles.color = new Color(brightness, brightness, brightness);
Handles.DrawLine(parentPos, pos);
}
float brightness = weight / 10.0f;
Handles.color = new Color(brightness, brightness, brightness);
Handles.DrawLine(parentPos, pos);
}
}
if (nucleus is Neuroid neuroid && neuroid.stale < minStale)
minStale = neuroid.stale;
}
if (layerNeuroid.synapses.Count > 0 && minStale > 2 && layerNeuroid.stale < 3)
Debug.LogWarning($"Strange {minStale} is big duing update");
float size = 20;
if (layerNeuroid.IsStale())
Handles.color = Color.black;
Handles.color = Color.darkCyan;
else {
float brightness = layerNeuroid.outputValue.magnitude / maxValue;
Handles.color = new Color(brightness, brightness, brightness);
@ -154,16 +155,16 @@ public class NanoBrain_Editor : Editor {
Event e = Event.current;
EventType et = e.GetTypeForControl(id);
if (e != null && neuronRect.Contains(e.mousePosition)) {
// Process Hover
HandleMouseHover(layerNeuroid, neuronRect);
// Process click
Debug.Log($"{et}");
if (et == EventType.MouseDown && e.button == 0) {
// Consume the event so the scene doesn't also handle it
e.Use();
HandleDiscClicked(layerNeuroid);
}
}
i++;
//i++;
}
}
}
@ -199,5 +200,19 @@ public class NanoBrain_Editor : Editor {
BuildLayers();
}
protected virtual void OnSceneGUI() {
NanoBrain brain = target as NanoBrain;
if (brain == null)
return;
// 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);
}
#endregion Update
}

View File

@ -40,7 +40,7 @@ public class GraphEditorWindow : EditorWindow {
return;
NeuroidLayer currentLayer = new() { ix = layerIx };
foreach (Neuroid outputNeuroid in selectedNucleus.outputNeuroids) {
foreach (Neuroid outputNeuroid in selectedNucleus.receivers) {
if (outputNeuroid != null) {
AddToLayer(currentLayer, outputNeuroid);
Debug.Log($"layer {layerIx} nucleus {outputNeuroid.name}");
@ -63,7 +63,8 @@ public class GraphEditorWindow : EditorWindow {
// foreach (Synapse synapse in selectedNucleus.synapses.Values) {
// Debug.Log($"Synapse {six}");
// Nucleus input = synapse.neuroid;
foreach ((Nucleus input, Synapse synapse) in selectedNucleus.synapses) {
//foreach ((Nucleus input, Synapse synapse) in selectedNucleus.synapses) {
foreach ((Nucleus input, float weight) in selectedNucleus.synapses) {
if (input != null) {
AddToLayer(currentLayer, input);
Debug.Log($"layer {layerIx} nucleus {input.name}");
@ -103,8 +104,8 @@ public class GraphEditorWindow : EditorWindow {
// If the output neuroid is visited
// Note: this does not yet work for multiple outputs yet (see the use of First())
if (neuroid.outputNeuroids.Count == 0 // make sure the root neuroids are processed directly
|| (neuronVisited.Contains(neuroid.outputNeuroids.First()) && neuroid.outputNeuroids.First().layerIx == layerIx - 1)) {
if (neuroid.receivers.Count == 0 // make sure the root neuroids are processed directly
|| (neuronVisited.Contains(neuroid.receivers.First()) && neuroid.receivers.First().layerIx == layerIx - 1)) {
// Add it to the next layer
currentLayer.neuroids.Add(neuroid);
neuroid.layerIx = layerIx;
@ -180,14 +181,16 @@ public class GraphEditorWindow : EditorWindow {
// if (this.neuroidPositions.ContainsKey(synapse.neuroid)) {
// Vector2Int inputNeuroidPos = this.neuroidPositions[synapse.neuroid];
foreach ((Nucleus neuroid, Synapse synapse) in layerNeuroid.synapses) {
//foreach ((Nucleus neuroid, Synapse synapse) in layerNeuroid.synapses) {
foreach ((Nucleus neuroid, float weight) in layerNeuroid.synapses) {
if (neuroid != null) {
if (this.neuroidPositions.ContainsKey(neuroid)) {
Vector2Int inputNeuroidPos = this.neuroidPositions[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;
//float brightness = synapse.weight / 10.0f;
float brightness = weight / 10.0f;
Handles.color = new Color(brightness, brightness, brightness);
Handles.DrawLine(parentPos, pos);
}
@ -274,7 +277,7 @@ public class GraphEditorWindow : EditorWindow {
if (neuroid == null)
this.allNeuroids = new();
else
this.allNeuroids = neuroid.net.neuroids;
this.allNeuroids = neuroid.brain.neuroids;
Debug.Log($"Neuroncount = {this.allNeuroids.Count}");

View File

@ -9,7 +9,7 @@ public class NanoBrain : MonoBehaviour {
return neuroid;
}
public void Update() {
public void UpdateNeurons() {
foreach (Neuroid neuroid in neuroids) {
neuroid.stale++;
if (neuroid.IsStale())

View File

@ -1,137 +1,90 @@
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class Synapse {
public Synapse(Nucleus neuroid, float weight = 1.0f) {
//this.neuroid = neuroid;
this.weight = weight;
}
//public Nucleus neuroid;
public float weight;
}
// public class NeuroidNetwork {
// public List<Neuroid> neuroids = new();
// public Neuroid AddNeuron(string name) {
// Neuroid neuroid = new(this, name);
// return neuroid;
// }
// public void Update() {
// foreach (Neuroid neuroid in neuroids) {
// neuroid.stale++;
// if (neuroid.IsStale())
// neuroid.outputValue = Vector3.zero;
// }
// }
// }
public class Neuroid : Nucleus {
public int stale = 0;
//public Vector3 outputValue;
public bool average = false;
//public bool quadratic = false;
public bool inverse = false;
public float exponent = 1.0f;
//public NeuroidNetwork net;
public NanoBrain net;
public NanoBrain brain;
// public Neuroid(NeuroidNetwork net, string name) : base(name) {
public Neuroid(NanoBrain net, string name) : base(name) {
this.net = net;
if (this.net != null)
this.net.neuroids.Add(this);
public Neuroid(NanoBrain brain, string name) : base(name) {
this.brain = brain;
if (this.brain != null)
this.brain.neuroids.Add(this);
else
Debug.LogError("No neuroid network");
}
public void AddSynapse(Neuroid input) {
input.AddReceiver(this);
this.synapses[input] = new(input);
}
// public void AddReceiver(Neuroid receiver) {
// this.outputNeuroids.Add(receiver);
// }
public void ResetWeights() {
foreach (Synapse synapse in this.synapses.Values)
synapse.weight = 1.0f;
this.synapses[input] = 1.0f;
}
public void SetWeight(Neuroid input, float weight) {
if (this.synapses.ContainsKey(input)) {
this.synapses[input].weight = weight;
}
else {
this.synapses[input] = new(input, weight);
}
this.synapses[input] = weight;
}
public void GetInputFrom(Neuroid input, float weight = 1.0f) {
input.AddReceiver(this);
this.synapses[input] = new(input, weight);
this.synapses[input] = weight;
}
public void SetInput(Neuroid input) {
if (this.synapses.ContainsKey(input) == false)
this.synapses[input] = new(input);
this.synapses[input] = 1.0f;
UpdateState();
}
public void SetInput(Neuroid input, float weight) {
if (this.synapses.ContainsKey(input)) {
Synapse synapse = this.synapses[input];
synapse.weight = weight;
}
else
this.synapses[input] = new(input, weight);
this.synapses[input] = weight;
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.outputNeuroids)
foreach (Neuroid neuroid in this.receivers)
neuroid.SetInput(this);
}
}
public virtual void UpdateState() {
// int minStale = 10000;
Vector3 result = Vector3.zero;
foreach ((Nucleus nucleus, Synapse synapse) in this.synapses) {
// foreach (Synapse synapse in this.synapses.Values) {
// if (synapse.neuroid == null)
// Debug.LogWarning(" disconnected synapse");
// if (synapse.value != synapse.neuroid.outputValue)
// Debug.LogWarning("synapse value error");
// Vector3 direction = synapse.value.normalized;
// float magnitude = synapse.value.magnitude;
// Vector3 direction = synapse.neuroid.outputValue.normalized;
// float magnitude = synapse.neuroid.outputValue.magnitude;
foreach ((Nucleus nucleus, float weight) in this.synapses) {
if (nucleus is Neuroid neuroid && neuroid.IsStale())
continue;
Vector3 direction = nucleus.outputValue.normalized;
float magnitude = nucleus.outputValue.magnitude;
magnitude = synapse.weight * Mathf.Pow(magnitude, exponent);
magnitude = weight * Mathf.Pow(magnitude, exponent);
if (inverse && magnitude > 0)
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;
foreach (Neuroid neuroid in this.outputNeuroids)
neuroid.SetInput(this);
// if (minStale > 2)
// Debug.LogWarning($"Strange {minStale} is big duing update");
this.stale = 0;
foreach (Neuroid receiver in this.receivers)
receiver.SetInput(this);
}
public bool IsStale() {

View File

@ -4,9 +4,9 @@ using UnityEngine;
public class Nucleus {
public string name;
public readonly Dictionary<Nucleus, Synapse> synapses = new();
public HashSet<Neuroid> outputNeuroids = new();
public virtual Vector3 outputValue {get; set; }
public readonly Dictionary<Nucleus, float> synapses = new();
public HashSet<Neuroid> receivers = new();
public virtual Vector3 outputValue { get; set; }
public int layerIx;
@ -15,7 +15,9 @@ public class Nucleus {
}
public virtual void AddReceiver(Neuroid receiver) {
this.outputNeuroids.Add(receiver);
receiver.synapses[this] = new(this);
//Debug.Log($"add receiver to {this} for {receiver} {receiver.GetHashCode()} {this.receivers.Count} {receiver.synapses.Count}");
this.receivers.Add(receiver);
receiver.synapses[this] = 1.0f; // new(this);
//Debug.Log($"receiver # {this.receivers.Count} synapse count {receiver.synapses.Count}");
}
}

View File

@ -32,7 +32,7 @@ public class Perception : Nucleus {
foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
if (neuroid != null) {
neuroid.AddReceiver(receivingNeuroid);
receivingNeuroid.synapses[neuroid] = new(neuroid, weight);
receivingNeuroid.synapses[neuroid] = weight; // new(neuroid, weight);
}
}
}
@ -45,7 +45,7 @@ public class Perception : Nucleus {
foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
if (neuroid != null && neuroid.velocityNeuroid != null) {
neuroid.velocityNeuroid.AddReceiver(receivingNeuroid);
receivingNeuroid.synapses[neuroid] = new(neuroid);
receivingNeuroid.synapses[neuroid] = 1.0f; //new(neuroid);
}
}
}
@ -54,42 +54,64 @@ public class Perception : Nucleus {
int availableIx = -1;
int leastInterestingIx = -1;
for (int i = 0; i < sensoryNeuroids.Length; i++) {
if (sensoryNeuroids[i] == null || sensoryNeuroids[i].IsStale())
if (sensoryNeuroids[i] == null)
availableIx = i;
else if (sensoryNeuroids[i].receptor.thingId == thingId) {
sensoryNeuroids[i].receptor.position = localPosition;
return;
}
if (sensoryNeuroids[i] != null) {
if (leastInterestingIx == -1 || sensoryNeuroids[leastInterestingIx].receptor.position.magnitude > sensoryNeuroids[i].receptor.position.magnitude)
if (availableIx == -1) {
if (sensoryNeuroids[i].IsStale())
leastInterestingIx = i;
else if (sensoryNeuroids[i] != null) {
if (leastInterestingIx == -1 || sensoryNeuroids[leastInterestingIx].receptor.position.magnitude > sensoryNeuroids[i].receptor.position.magnitude)
leastInterestingIx = i;
}
}
}
if (availableIx == -1)
availableIx = leastInterestingIx;
if (availableIx != -1) {
// Debug.Log($"new receptor for {thingId}");
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);
}
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;
sensoryNeuroids[availableIx] = neuroid;
neuroid.receptor.position = localPosition;
}
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);
}
sensoryNeuroids[availableIx] = neuroid;
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 outputNeuroid in sensoryNeuroids[i].outputNeuroids)
outputNeuroid.RemoveInputFrom(sensoryNeuroids[i]);
foreach (Neuroid receiver in sensoryNeuroids[i].receivers)
receiver.RemoveInputFrom(sensoryNeuroids[i]);
sensoryNeuroids[i] = null;
return;
}

View File

@ -40,23 +40,23 @@ public class SensoryNeuroid : Neuroid {
this.AddReceiver(velocityNeuroid);
}
public void Replace(int thingId) {
this.name = "sensory neuroid";
this.receptor.thingId = thingId;
this.receptor.value = Vector3.zero;
this.outputValue = Vector3.zero;
this.receivers = new();
this.AddReceiver(velocityNeuroid);
}
public override void UpdateState() {
Vector3 result = receptor.value;
// SensoryNeuroid normally do not have synapses...
// foreach (Synapse synapse in this.synapses.Values) {
// if (synapse.neuroid == null)
// Debug.LogWarning(" disconnected synapse");
// // if (synapse.value != synapse.neuroid.outputValue)
// // Debug.LogWarning("synapse value error");
// // Vector3 direction = synapse.value.normalized;
// // float magnitude = synapse.value.magnitude;
// Vector3 direction = synapse.neuroid.outputValue.normalized;
// float magnitude = synapse.neuroid.outputValue.magnitude;
foreach ((Nucleus nucleus, Synapse synapse) in this.synapses) {
//foreach ((Nucleus nucleus, Synapse synapse) in this.synapses) {
foreach ((Nucleus nucleus, float weight) in this.synapses) {
Vector3 direction = nucleus.outputValue.normalized;
float magnitude = nucleus.outputValue.magnitude;
magnitude = synapse.weight * Mathf.Pow(magnitude, exponent);
//magnitude = synapse.weight * Mathf.Pow(magnitude, exponent);
magnitude = weight * Mathf.Pow(magnitude, exponent);
if (inverse)
magnitude = 1 / magnitude;
result += direction * magnitude;
@ -65,7 +65,7 @@ public class SensoryNeuroid : Neuroid {
result /= this.synapses.Count + 1;
this.outputValue = result;
foreach (Neuroid neuroid in this.outputNeuroids)
foreach (Neuroid neuroid in this.receivers)
neuroid.SetInput(this);
this.stale = 0;
}
@ -82,7 +82,6 @@ public class VelocityNeuroid : Neuroid {
public override void UpdateState() {
// Assuming only one synapse for now....
//Vector3 currentPosition = this.synapses.First().Value.neuroid.outputValue;
Vector3 currentPosition = this.synapses.First().Key.outputValue;
float currentValueTime = Time.time;
@ -92,10 +91,11 @@ public class VelocityNeuroid : Neuroid {
// No activation function...
this.outputValue = velocity;
foreach (Neuroid receiver in outputNeuroids)
foreach (Neuroid receiver in receivers)
receiver?.SetInput(this);
this.stale = 0;
this.lastValueTime = Time.time;
this.lastPosition = currentPosition;
}
}

View File

@ -52,7 +52,7 @@ public class Boid : MonoBehaviour {
Vector3 localPosition = neighbour.transform.position - this.transform.position;
int thingId = neighbour.GetInstanceID();
perception.ProcessStimulus(thingId, BoidType, localPosition); //, neighbour.gameObject.name);
perception.ProcessStimulus(thingId, BoidType, localPosition, neighbour.gameObject.name);
}
}
@ -63,9 +63,9 @@ public class Boid : MonoBehaviour {
Vector3 desiredLocalSpace = -this.transform.InverseTransformPoint(desiredWorldSpace);
perception.ProcessStimulus(777, BoundaryType, desiredLocalSpace, "Boundary");
}
else {
perception.RemoveStimulus(777);
}
// else {
// perception.RemoveStimulus(777);
// }
Vector3 worldForce = this.transform.TransformDirection(totalForce.outputValue);
@ -82,7 +82,7 @@ public class Boid : MonoBehaviour {
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2f); // Adjust the speed of rotation
}
neuroidNet.Update();
neuroidNet.UpdateNeurons();
}
Vector3 ClosestPointOnBoundsSurface(Bounds b, Vector3 p) {
@ -96,18 +96,18 @@ public class Boid : MonoBehaviour {
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);
}
// 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);
// }
}