From 09a75aa22eea0b005ec07c8d603cc10ec3bbf6fb Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Wed, 6 May 2026 17:39:56 +0200 Subject: [PATCH] Multi smell works --- NanoBrain/Editor/ClusterEditor.cs | 52 ++-- NanoBrain/Editor/ClusterViewer.cs | 63 +++-- NanoBrain/Runtime/Scripts/Core/Cluster.cs | 308 ++++++++-------------- NanoBrain/Runtime/Scripts/Core/Neuron.cs | 21 +- NanoBrain/Runtime/Scripts/Core/Nucleus.cs | 9 - Runtime/Scripts/Ant.cs | 105 ++++---- Runtime/Scripts/Odorant.cs | 6 + Samples/Brain/Foraging.asset | 178 ++++++++++--- Samples/Brain/Foraging.asset.meta | 2 +- Samples/Brain/Pheromone.asset | 75 ++++++ Samples/Brain/Pheromone.asset.meta | 8 + Samples/Prefabs/LowPolyAnt Variant.prefab | 243 ++++++++--------- 12 files changed, 569 insertions(+), 501 deletions(-) create mode 100644 Samples/Brain/Pheromone.asset create mode 100644 Samples/Brain/Pheromone.asset.meta diff --git a/NanoBrain/Editor/ClusterEditor.cs b/NanoBrain/Editor/ClusterEditor.cs index b67650c..67764da 100644 --- a/NanoBrain/Editor/ClusterEditor.cs +++ b/NanoBrain/Editor/ClusterEditor.cs @@ -165,25 +165,10 @@ namespace NanoBrain { GUILayout.Label(nucleusType, headerStyle); // Nucleus name - //Cluster cluster = this.currentPrefabNucleus as Cluster; - Cluster cluster = this.currentNucleus as Cluster; - if (cluster != null) { - EditorGUILayout.BeginHorizontal(); - if (GUILayout.Button(this.currentNucleus.parent.name)) - OnClusterClick(cluster); - EditorGUI.BeginDisabledGroup(true); - EditorGUILayout.TextField(this.currentNucleus.name, boldTextFieldStyle); - EditorGUI.EndDisabledGroup(); - if (GUILayout.Button("Reimport")) - ReimportCluster(cluster); - EditorGUILayout.EndHorizontal(); - } - else { - string newName = EditorGUILayout.TextField(this.currentNucleus.name, boldTextFieldStyle); - if (newName != this.currentNucleus.name) { - this.currentNucleus.name = newName; - anythingChanged = true; - } + string newName = EditorGUILayout.TextField(this.currentNucleus.name, boldTextFieldStyle); + if (newName != this.currentNucleus.name) { + this.currentNucleus.name = newName; + anythingChanged = true; } // Current output value @@ -202,7 +187,7 @@ namespace NanoBrain { if (this.currentNucleus is MemoryCell memory) MemoryCellInspector(memory, ref anythingChanged); // Cluster - else if (cluster != null) + else if (this.currentNucleus is Cluster cluster) ClusterInspector(cluster, ref anythingChanged); // Other else @@ -277,8 +262,8 @@ namespace NanoBrain { if (breakOnWake && this.currentNucleus is Neuron currentNeuron) { if (currentNeuron.isSleeping == false) Debug.Break(); - trace = EditorGUILayout.Toggle("Trace", trace); - currentNeuron.trace = trace; + // trace = EditorGUILayout.Toggle("Trace", trace); + // currentNeuron.trace = trace; } } @@ -304,8 +289,6 @@ namespace NanoBrain { Nucleus[] array = null; int elementIx = -1; - //if (this.currentPrefabNucleus is Neuron prefabNeuron && prefabNeuron.synapses.Count > 0) { - // Synapse[] synapses = prefabNeuron.synapses.ToArray(); if (this.currentNucleus is Neuron currentNeuron && currentNeuron.synapses.Count > 0) { Synapse[] synapses = currentNeuron.synapses.ToArray(); foreach (Synapse synapse in synapses) { @@ -345,19 +328,19 @@ namespace NanoBrain { else { EditorGUILayout.BeginHorizontal(); - if (synapse.neuron.parent.prefab != this.currentNucleus.parent.prefab) { + if (synapse.neuron.parent != this.currentNucleus.parent) { // If it is a different cluster GUIStyle labelStyle = new(GUI.skin.label); float labelWidth = 200; - if (synapse.neuron.parent.prefab != null) { - labelWidth = labelStyle.CalcSize(new GUIContent($"{synapse.neuron.parent.prefab.name}.")).x; - GUILayout.Label($"{synapse.neuron.parent.prefab.name}", GUILayout.Width(labelWidth)); + if (synapse.neuron.parent != null) { + labelWidth = labelStyle.CalcSize(new GUIContent($"{synapse.neuron.parent.name}.")).x; + GUILayout.Label($"{synapse.neuron.parent.name}", GUILayout.Width(labelWidth)); } - string[] options = synapse.neuron.parent.prefab.cluster.nuclei.Select(n => n.name).ToArray(); + string[] options = synapse.neuron.parent.nuclei.Select(n => n.name).ToArray(); int selectedIndex = System.Array.IndexOf(options, synapse.neuron.name); int newIndex = EditorGUILayout.Popup(selectedIndex, options); if (newIndex != selectedIndex) { - Neuron newNeuron = synapse.neuron.parent.prefab.cluster.nuclei[newIndex] as Neuron; + Neuron newNeuron = synapse.neuron.parent.nuclei[newIndex] as Neuron; ChangeSynapse(synapse, newNeuron); } } @@ -437,7 +420,7 @@ namespace NanoBrain { } protected virtual void AddNeuronInput(Nucleus nucleus) { - Neuron newNeuron = new (this.currentCluster, "New Neuron"); + Neuron newNeuron = new(this.currentCluster, "New Neuron"); //Neuron newNeuroid = new(this.prefab.cluster, "New neuron"); newNeuron.AddReceiver(nucleus); this.currentNucleus = newNeuron; @@ -453,7 +436,7 @@ namespace NanoBrain { ClusterPickerWindow.ShowPicker(brain => OnClusterPicked(nucleus, brain), "Select Cluster"); } private void OnClusterPicked(Nucleus nucleus, ClusterPrefab selectedPrefab) { - Cluster subclusterInstance = new(selectedPrefab, this.prefab); + Cluster subclusterInstance = new(selectedPrefab, this.currentCluster); subclusterInstance.defaultOutput.AddReceiver(nucleus); } @@ -557,11 +540,6 @@ namespace NanoBrain { AddInput(selectedType, this.currentNucleus); } return connecting; - // if (selectedType == Nucleus.Type.None) - // return false; - - // AddInput(selectedType, this.currentNucleus); - // return true; } protected virtual void ChangeSynapse(Synapse synapse, Neuron newNucleus) { diff --git a/NanoBrain/Editor/ClusterViewer.cs b/NanoBrain/Editor/ClusterViewer.cs index 86ae2a4..1127e5c 100644 --- a/NanoBrain/Editor/ClusterViewer.cs +++ b/NanoBrain/Editor/ClusterViewer.cs @@ -108,7 +108,7 @@ namespace NanoBrain { this.gameObject = gameObject; if (this.currentCluster == null) return; - + if (Application.isPlaying == false) this.serializedBrain = new SerializedObject(this.currentCluster.prefab); this.selectedOutput = this.currentCluster.outputs[0]; @@ -488,14 +488,15 @@ namespace NanoBrain { maxValue = 1; float brightness = siblingNeuron.outputMagnitude / maxValue; color = new Color(brightness, brightness, brightness, 1f); - } DrawNucleus(siblingNeuron, position, size, color); + } + DrawNucleus(siblingNeuron, position, size, color); GUIStyle style = new(EditorStyles.label) { alignment = TextAnchor.UpperCenter, normal = { textColor = Color.white }, fontStyle = FontStyle.Bold, }; Vector3 labelPos = position - Vector3.down * (size + 5); // below neuron - string name = $"{sibling.baseName}.{nucleus.name}"; + string name = $"{sibling.baseName}\n{nucleus.name}"; Handles.Label(labelPos, name, style); row++; } @@ -505,7 +506,7 @@ namespace NanoBrain { protected void DrawOutputs(Vector2 parentPos, float size) { if (this.currentCluster == null) return; - + // Determine the maximum value in this layer // This is used to 'scale' the output value colors of the nuclei float maxValue = 0; @@ -612,18 +613,12 @@ namespace NanoBrain { if (nucleus.parent != null && currentNucleus != null && nucleus.parent != currentNucleus.parent && nucleus.parent is Cluster parentCluster1) { // This neuron is part of another cluster parentCluster1.name ??= ""; - string baseName = ""; int colonPos = parentCluster1.name.IndexOf(":"); + string baseName; if (colonPos > 0 && colonPos < parentCluster1.name.Length - 2) - baseName = parentCluster1.name[..colonPos] + "."; + baseName = parentCluster1.name[..colonPos] + "\n"; else - baseName = parentCluster1.name + "."; - // if (colonPos > 0 && colonPos < parentCluster1.name.Length - 2) { - // // if it is an array, we should not show the :0 of the first element - // //baseName = baseName[..colonPos]; - // Handles.Label(labelPos, baseName + nucleus.name, style); - // } - // else + baseName = parentCluster1.name + "\n"; Handles.Label(labelPos, baseName + nucleus.name, style); } else { @@ -858,22 +853,34 @@ namespace NanoBrain { void OnSceneGUI(SceneView sceneView) { if (this.gameObject != null) { - // if (this.currentNucleus is IReceptor receptor) { - // foreach (Nucleus nucleus in receptor.nucleiArray) { - // if (nucleus is Neuron neuron) { - // Vector3 worldVector = this.gameObject.transform.TransformVector(neuron.outputValue); - // Handles.color = Color.yellow; - // Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector); - // } - // } - // } - // else { - if (this.currentNucleus is Neuron currentNeuron) { - Vector3 worldVector = this.gameObject.transform.TransformVector(currentNeuron.outputValue); - Handles.color = Color.yellow; - Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector); + + Handles.color = Color.yellow; + if (this.selectedSynapseNeuron != null) { + foreach (Cluster sibling in this.selectedSynapseNeuron.parent.siblingClusters) { + Neuron siblingNeuron = sibling.GetNucleus(this.selectedSynapseNeuron.name) as Neuron; + Vector3 worldVector = this.gameObject.transform.TransformVector(siblingNeuron.outputValue); + Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector); + } + // if (this.currentNucleus is Cluster cluster) { + // foreach (Cluster sibling in cluster.siblingClusters) { + + // } + // } + // // if (this.currentNucleus is IReceptor receptor) { + // // foreach (Nucleus nucleus in receptor.nucleiArray) { + // // if (nucleus is Neuron neuron) { + // // Vector3 worldVector = this.gameObject.transform.TransformVector(neuron.outputValue); + // // Handles.color = Color.yellow; + // // Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector); + // // } + // // } + } + else { + if (this.currentNucleus is Neuron currentNeuron) { + Vector3 worldVector = this.gameObject.transform.TransformVector(currentNeuron.outputValue); + Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector); + } } - // } } } diff --git a/NanoBrain/Runtime/Scripts/Core/Cluster.cs b/NanoBrain/Runtime/Scripts/Core/Cluster.cs index 973c692..329fd3a 100644 --- a/NanoBrain/Runtime/Scripts/Core/Cluster.cs +++ b/NanoBrain/Runtime/Scripts/Core/Cluster.cs @@ -111,13 +111,13 @@ namespace NanoBrain { Neuron synapseNeuron = prefabSynapse.neuron; if (synapseNeuron.parent.prefab != null && synapseNeuron.parent.prefab != this.prefab) { // Neuron is in another cluster, find the cloned cluster first - ClusterPrefab prefabCluster = synapseNeuron.parent.prefab; + Cluster prefabCluster = synapseNeuron.parent; Cluster clonedCluster = this.nuclei.Find(n => n.name == prefabCluster.name) as Cluster; if (clonedCluster == null) continue; // Now find the neuron in that cloned cluster - int neuronIx = GetNucleusIndex(prefabCluster.cluster.nuclei, prefabSynapse.neuron.name); + int neuronIx = GetNucleusIndex(prefabCluster.nuclei, prefabSynapse.neuron.name); if (neuronIx < 0) // Could not find the neuron in the prefab cluster continue; @@ -140,28 +140,6 @@ namespace NanoBrain { // Debug.Log($"Add synapse {clonedSender.name} -> {clonedNeuron.name}"); } } - - // // Copy the receivers, which will also create the synapses - // foreach (Nucleus receiver in prefabNeuron.receivers.ToArray()) { - // int ix = GetNucleusIndex(prefabNuclei, receiver); - // if (ix < 0) - // continue; - - // if (clonedNuclei[ix] is not Nucleus clonedReceiver) - // continue; - - // // Find the synapse for the weight - // float weight = 1; - // foreach (Synapse synapse in receiver.synapses) { - // // Find the weight for this synapse - // if (synapse.neuron == prefabNucleus) { - // weight = synapse.weight; - // break; - // } - // } - - // clonedNeuron.AddReceiver(clonedReceiver, weight); - // } } if (Application.isPlaying) { @@ -191,135 +169,43 @@ namespace NanoBrain { // Ensure that all neurons are computed to initialize bias foreach (Nucleus clonedNucleus in clonedNuclei) { - clonedNucleus.UpdateStateIsolated(); + if (clonedNucleus is not Cluster) + clonedNucleus.UpdateStateIsolated(); } } - /* - for (int nucleusIx = 0; nucleusIx < clonedNuclei.Length; nucleusIx++) { - Nucleus prefabNucleus = prefabNuclei[nucleusIx]; - if (prefabNucleus is not Cluster prefabCluster) - continue; - - if (prefabCluster.instanceCount <= 1) - continue; - - Cluster clonedNucleus = clonedNuclei[nucleusIx] as Cluster; - if (prefabCluster == prefabCluster.siblingClusters[0]) { - // We clone the array only for the first entry - //NucleusArray clonedArray = new(prefabReceptor.nucleiArray.Length); - Cluster[] clonedArray = new Cluster[prefabCluster.siblingClusters.Length]; - int arrayIx = 0; - foreach (Cluster prefabArrayNucleus in prefabCluster.siblingClusters) { - int arrayNucleusIx = GetNucleusIndex(prefabNuclei, prefabArrayNucleus); - if (arrayNucleusIx >= 0) { - Cluster clonedArrayNucleus = clonedNuclei[arrayNucleusIx] as Cluster; - clonedArray[arrayIx] = clonedArrayNucleus; - } - else { - Debug.LogError($" Could not find prefab nucleus {prefabNucleus.name} in the clones"); - } - arrayIx++; - } - clonedNucleus.siblingClusters = clonedArray; - } - else { - // The others will refer to the array created for the first nucleus in the array - int firstNucleusIx = GetNucleusIndex(prefabNuclei, prefabCluster.siblingClusters[0]); - Cluster clonedFirstNucleus = clonedNuclei[firstNucleusIx] as Cluster; - clonedNucleus.siblingClusters = clonedFirstNucleus.siblingClusters; - } - } } - /* - // Collect the subclusters - List subClusters = new(); - foreach (Nucleus nucleus in prefabNuclei) { - foreach (Synapse synapse in nucleus.synapses) { - Nucleus synapseNucleus = synapse.neuron; - Cluster subCluster = synapseNucleus.parent; - if (subCluster is null || - synapseNucleus.clusterPrefab == this.clusterPrefab) { + // private void CloneSynapses(Neuron prefabNeuron, Neuron clonedNeuron) { + // foreach (Synapse prefabSynapse in prefabNeuron.synapses) { + // Neuron synapseNeuron = prefabSynapse.neuron; + // if (synapseNeuron.parent.prefab != null && synapseNeuron.parent.prefab != this.prefab) { + // // Neuron is in another cluster, find the cloned cluster first + // ClusterPrefab prefabCluster = synapseNeuron.parent.prefab; + // Cluster clonedCluster = this.nuclei.Find(n => n.name == prefabCluster.name) as Cluster; + // if (clonedCluster == null) + // continue; - continue; - } - // if (synapseNucleus is not Cluster subCluster) - // continue; - if (subClusters.Contains(subCluster)) - continue; - subClusters.Add(subCluster); - } - } - // Create the subcluster instances - foreach (Cluster subCluster in subClusters) { - for (int ix = 0; ix < subCluster.instanceCount; ix++) { - // create the new instance - Cluster clusterInstance = new(subCluster.prefab); - // connect it - foreach ((Neuron sender, Nucleus receiver) in subCluster.CollectConnections()) { - int receiverIx = GetNucleusIndex(prefabNuclei, receiver); - if (receiverIx < 0) - continue; + // // Now find the neuron in that cloned cluster + // int neuronIx = GetNucleusIndex(prefabCluster.cluster.nuclei, prefabSynapse.neuron.name); + // if (neuronIx < 0) + // // Could not find the neuron in the prefab cluster + // continue; + // if (clonedCluster.nuclei[neuronIx] is not Neuron clonedSender) + // // Could not find the neuron in the cloned cluster + // continue; - if (clonedNuclei[receiverIx] is not Nucleus clonedReceiver) - continue; + // clonedSender.AddReceiver(clonedNeuron, prefabSynapse.weight); + // //Debug.Log($"Add synapse {clonedCluster.name}.{clonedSender.name} -> {clonedNeuron.name} [{clonedSender.receivers.Count}]"); + // } + // else { + // Neuron clonedSender = this.nuclei.Find(n => n.name == prefabSynapse.neuron.name) as Neuron; + // // Copy the receivers which will also create the synapse + // clonedSender.AddReceiver(clonedNeuron, prefabSynapse.weight); + // // Debug.Log($"Add synapse {clonedSender.name} -> {clonedNeuron.name}"); + // } + // } - // Find the synapse for the weight - float weight = 1; - foreach (Synapse synapse in receiver.synapses) { - // Find the weight for this synapse - if (synapse.neuron == sender) { - weight = synapse.weight; - break; - } - } - - if (clusterInstance.GetNucleus(sender.name) is not Neuron clonedSender) - continue; - - clonedSender.AddReceiver(clonedReceiver, weight); - } - } - } - */ - - // foreach (Nucleus nucleus in this.clusterNuclei) { - // if (nucleus is Cluster clonedSubCluster) - // RestoreAllExternalReceivers(clonedSubCluster, this.prefab, this); - // } - } - - private void CloneSynapses(Neuron prefabNeuron, Neuron clonedNeuron) { - foreach (Synapse prefabSynapse in prefabNeuron.synapses) { - Neuron synapseNeuron = prefabSynapse.neuron; - if (synapseNeuron.parent.prefab != null && synapseNeuron.parent.prefab != this.prefab) { - // Neuron is in another cluster, find the cloned cluster first - ClusterPrefab prefabCluster = synapseNeuron.parent.prefab; - Cluster clonedCluster = this.nuclei.Find(n => n.name == prefabCluster.name) as Cluster; - if (clonedCluster == null) - continue; - - // Now find the neuron in that cloned cluster - int neuronIx = GetNucleusIndex(prefabCluster.cluster.nuclei, prefabSynapse.neuron.name); - if (neuronIx < 0) - // Could not find the neuron in the prefab cluster - continue; - if (clonedCluster.nuclei[neuronIx] is not Neuron clonedSender) - // Could not find the neuron in the cloned cluster - continue; - - clonedSender.AddReceiver(clonedNeuron, prefabSynapse.weight); - //Debug.Log($"Add synapse {clonedCluster.name}.{clonedSender.name} -> {clonedNeuron.name} [{clonedSender.receivers.Count}]"); - } - else { - Neuron clonedSender = this.nuclei.Find(n => n.name == prefabSynapse.neuron.name) as Neuron; - // Copy the receivers which will also create the synapse - clonedSender.AddReceiver(clonedNeuron, prefabSynapse.weight); - // Debug.Log($"Add synapse {clonedSender.name} -> {clonedNeuron.name}"); - } - } - - } + // } /// /// Sort the nuclei in a correct evaluation order @@ -537,43 +423,43 @@ namespace NanoBrain { } } - public virtual Cluster GetThingCluster() { - Cluster selectedCluster = SelectCluster(); - return selectedCluster; - } - public virtual Cluster GetThingCluster(int thingId, string thingName = null) { - if (thingClusters.TryGetValue(thingId, out Cluster cluster)) - return cluster; + // public virtual Cluster GetThingCluster() { + // Cluster selectedCluster = SelectCluster(); + // return selectedCluster; + // } + // public virtual Cluster GetThingCluster(int thingId, string thingName = null) { + // if (thingClusters.TryGetValue(thingId, out Cluster cluster)) + // return cluster; - Cluster selectedCluster = SelectCluster(); - selectedCluster.name = baseName + ": " + thingName; - thingClusters[thingId] = selectedCluster; - return selectedCluster; - } + // Cluster selectedCluster = SelectCluster(); + // selectedCluster.name = baseName + ": " + thingName; + // thingClusters[thingId] = selectedCluster; + // return selectedCluster; + // } - private Cluster SelectCluster() { - if (this.siblingClusters == null) - return this; + // private Cluster SelectCluster() { + // if (this.siblingClusters == null) + // return this; - // Find a sleeping cluster - // foreach (Cluster cluster in this.siblingClusters) { - // if (cluster.defaultOutput.isSleeping) { - // RemoveThingCluster(cluster); - // return cluster; - // } - // } + // // Find a sleeping cluster + // // foreach (Cluster cluster in this.siblingClusters) { + // // if (cluster.defaultOutput.isSleeping) { + // // RemoveThingCluster(cluster); + // // return cluster; + // // } + // // } - // Find longest unused cluster - // Note this uses the default output... - Cluster unusedCluster = this.siblingClusters[0]; - for (int ix = 1; ix < this.siblingClusters.Length; ix++) { - if (this.siblingClusters[ix].defaultOutput.lastUpdate < unusedCluster.defaultOutput.lastUpdate) - unusedCluster = this.siblingClusters[ix]; - } + // // Find longest unused cluster + // // Note this uses the default output... + // Cluster unusedCluster = this.siblingClusters[0]; + // for (int ix = 1; ix < this.siblingClusters.Length; ix++) { + // if (this.siblingClusters[ix].defaultOutput.lastUpdate < unusedCluster.defaultOutput.lastUpdate) + // unusedCluster = this.siblingClusters[ix]; + // } - RemoveThingCluster(unusedCluster); - return unusedCluster; - } + // RemoveThingCluster(unusedCluster); + // return unusedCluster; + // } private void RemoveThingCluster(Cluster cluster) { List keysToRemove = new(); @@ -756,8 +642,8 @@ namespace NanoBrain { else { string nucleusName0 = nucleusName + ": 0"; foreach (Nucleus nucleus in this.nuclei) { - if (nucleus is Cluster) { //IReceptor receptor) { - if (nucleus.name == nucleusName | nucleus.name == nucleusName0) + if (nucleus is Cluster) { + if (nucleus.name == nucleusName || nucleus.name == nucleusName0) return nucleus; } else if (nucleus.name == nucleusName) @@ -775,6 +661,51 @@ namespace NanoBrain { return null; } + public Neuron GetNeuron(int thingId, string neuronName, string thingName = null) { + if (this.siblingClusters == null || this.siblingClusters.Length <= 1) + return this.GetNeuron(neuronName); + + // See if we are already using a cluster for thingId + if (thingClusters.TryGetValue(thingId, out Cluster cluster)) + return cluster.GetNeuron(neuronName); + + // Find the cluster with the lowest value neuron + Neuron lowestNeuron = null; + foreach (Cluster sibling in this.siblingClusters) { + Neuron neuron = sibling.GetNeuron(neuronName); + if (lowestNeuron == null || neuron.outputMagnitude < lowestNeuron.outputMagnitude) + lowestNeuron = neuron; + } + Cluster selectedCluster = lowestNeuron.parent; + RemoveThingCluster(selectedCluster); + selectedCluster.name = baseName + ": " + thingName; + thingClusters[thingId] = selectedCluster; + return lowestNeuron; + /* + // Find a sleeping cluster + // foreach (Cluster cluster in this.siblingClusters) { + // if (cluster.defaultOutput.isSleeping) { + // RemoveThingCluster(cluster); + // return cluster; + // } + // } + + // Find longest unused cluster + // Note this uses the default output... + Cluster unusedCluster = this.siblingClusters[0]; + for (int ix = 1; ix < this.siblingClusters.Length; ix++) { + if (this.siblingClusters[ix].defaultOutput.lastUpdate < unusedCluster.defaultOutput.lastUpdate) + unusedCluster = this.siblingClusters[ix]; + } + + RemoveThingCluster(unusedCluster); + //return unusedCluster; + + Cluster cluster = GetThingCluster(thingId, thingName); + Neuron neuron = cluster?.GetNeuron(neuronName); + return neuron; + */ + } public bool DeleteNucleus(Nucleus nucleus) { if (this.nuclei.Contains(nucleus) == false) { // Try to find the nucleus by name @@ -883,27 +814,19 @@ namespace NanoBrain { } List computeOrder = this.computeOrders[startNucleus]; - //if (startNucleus.trace) - // Debug.Log($"Update from {startNucleus.name}"); foreach (Nucleus nucleus in computeOrder) { if (nucleus is not Cluster) { nucleus.UpdateStateIsolated(); - //if (startNucleus.trace && nucleus is Neuron neuron) - // Debug.Log($" {nucleus.name}"); if (nucleus is Neuron neuron) { foreach (Nucleus receiver in neuron.receivers) { if (receiver.parent != this) { - Debug.Log($" External: {receiver.parent.name}.{receiver.name}"); + //Debug.Log($" External: {receiver.parent.name}.{receiver.name}"); receiver.parent.UpdateFromNucleus(receiver); } } } } } - - // continue in parent - //this.parent?.UpdateFromNucleus(this); - UpdateNuclei(); } @@ -911,6 +834,7 @@ namespace NanoBrain { throw new Exception("Cluster should not be updated!"); } + // Don't think this does anything anymore... public override void UpdateNuclei() { foreach (Nucleus nucleus in this.nuclei) nucleus.UpdateNuclei(); @@ -921,9 +845,9 @@ namespace NanoBrain { public void Refresh() { // This should not be needed, but somehow somewhere the parent is changed... foreach (Nucleus nucleus in this.nuclei) { - if (nucleus is not Neuron neuron) - continue; - neuron.parent = this; + // if (nucleus is not Neuron neuron) + // continue; + nucleus.parent = this; } RefreshOutputs(); RefreshComputeOrders(); diff --git a/NanoBrain/Runtime/Scripts/Core/Neuron.cs b/NanoBrain/Runtime/Scripts/Core/Neuron.cs index 43b6507..4869615 100644 --- a/NanoBrain/Runtime/Scripts/Core/Neuron.cs +++ b/NanoBrain/Runtime/Scripts/Core/Neuron.cs @@ -276,16 +276,11 @@ namespace NanoBrain { public float outputSqrMagnitude => _outputValue.sqrMagnitude; #endif - public bool isFiring { - get { - //SleepCheck(); - return this.outputMagnitude > 0.5f; - } - } + public bool isFiring => this.outputMagnitude > 0.5f; public Action WhenFiring; public bool persistOutput = false; - public virtual bool isSleeping => persistOutput ? false : (Time.time - this.lastUpdate > this.timeToSleep); + public virtual bool isSleeping => !persistOutput && (Time.time - this.lastUpdate > this.timeToSleep); public void SleepCheck() { if (this.isSleeping) { #if UNITY_MATHEMATICS @@ -299,9 +294,9 @@ namespace NanoBrain { /// /// Toggle for printing debugging trace data /// - public bool trace = false; + //public bool trace = false; - [NonSerialized] + //[NonSerialized] public float lastUpdate = 0; public readonly float timeToSleep = 1f; @@ -624,7 +619,13 @@ namespace NanoBrain { #endregion Receivers - public override void ProcessStimulus(Vector3 inputValue) { + /// + /// Process an external stimulus + /// + /// The value of the stimulus + /// The id of the thing causing the stimulus + /// The name of the thing causing the stimulus + public virtual void ProcessStimulus(Vector3 inputValue) { this.lastUpdate = Time.time; this.bias = inputValue; this.parent?.UpdateFromNucleus(this); diff --git a/NanoBrain/Runtime/Scripts/Core/Nucleus.cs b/NanoBrain/Runtime/Scripts/Core/Nucleus.cs index 5c91a4a..594fd57 100644 --- a/NanoBrain/Runtime/Scripts/Core/Nucleus.cs +++ b/NanoBrain/Runtime/Scripts/Core/Nucleus.cs @@ -142,15 +142,6 @@ public abstract class Nucleus { // this.parent.UpdateFromNucleus(this); // } - /// - /// Process an external stimulus - /// - /// The value of the stimulus - /// The id of the thing causing the stimulus - /// The name of the thing causing the stimulus - public virtual void ProcessStimulus(Vector3 inputValue) { //, int thingId = 0, string thingName = "") { - } - #endregion Update } diff --git a/Runtime/Scripts/Ant.cs b/Runtime/Scripts/Ant.cs index ec2eb22..c4c1265 100644 --- a/Runtime/Scripts/Ant.cs +++ b/Runtime/Scripts/Ant.cs @@ -42,10 +42,10 @@ namespace CreatureControl { /// like placing pheromones public Neuron beat; - public Neuron pheromoneSteering; public Neuron foodReceptor; public Neuron homeReceptor; - public Neuron foodSmell; + public Cluster foodReceptors; + public Cluster homeReceptors; // brain output public Neuron targetDirection; @@ -71,10 +71,11 @@ namespace CreatureControl { touchRight.receptor = brain.GetNucleus("Hit Right") as Neuron; this.foodReceptor = brain.GetNucleus("Food Receptor") as Neuron; this.homeReceptor = brain.GetNucleus("Home Receptor") as Neuron; - this.pheromoneSteering = brain.GetNucleus("Pheromone Steering") as Neuron; + this.foodReceptors = brain.GetNucleus("Food Receptors") as Cluster; + this.homeReceptors = brain.GetNucleus("Home Receptors") as Cluster; //--- brain outputs - this.targetDirection = brain.GetNucleus("Output") as Neuron; + this.targetDirection = brain.GetNucleus("Movement") as Neuron; this.hasFood = brain.GetNucleus("Having Food") as Neuron; } } @@ -106,18 +107,23 @@ namespace CreatureControl { #region Update + private int foodPheromoneIx = 0; void PlaceFoodPheromone() { if (foodPheromonePrefab == null) return; GameObject pheromoneObj = Instantiate(foodPheromonePrefab); + pheromoneObj.name = $"To Food {foodPheromoneIx++}"; pheromoneObj.transform.position = this.model.position; } + + private int homePheromoneIx = 0; void PlaceHomePheromone() { if (homePheromonePrefab == null) return; GameObject pheromoneObj = Instantiate(homePheromonePrefab); + pheromoneObj.name = $"To Home {homePheromoneIx++}"; pheromoneObj.transform.position = this.model.position; } @@ -163,9 +169,13 @@ namespace CreatureControl { // Set random direction to simulate noisy smells perception // which will result in a bit of random walking when no clear // smells are received - float randomAngle = Random.Range(-smellAngle/4, smellAngle/4); - Vector3 randomDirection = Quaternion.AngleAxis(randomAngle, Vector3.up) * Vector3.forward; + float randomAngle = Random.Range(-smellAngle, smellAngle); + Vector3 randomDirection = Quaternion.AngleAxis(randomAngle, Vector3.up) * Vector3.forward * 0.01f; foodReceptor?.SetBias(randomDirection); + randomAngle = Random.Range(-smellAngle, smellAngle); + randomDirection = Quaternion.AngleAxis(randomAngle, Vector3.up) * Vector3.forward * 0.01f; + homeReceptor?.SetBias(randomDirection); + yield return _waitForSeconds3; } } @@ -174,61 +184,50 @@ namespace CreatureControl { Collider[] colliders = Physics.OverlapSphere(this.transform.position, smellRadius); foreach (Collider collider in colliders) { SmellPheromones(collider); - SmellFood(collider); - SmellHome(collider); } } void SmellPheromones(Collider thing) { - Pheromone pheromone = thing.GetComponentInParent(); - if (pheromone == null) - return; - - Vector3 smellDirection = this.transform.InverseTransformPoint(pheromone.transform.position); + Vector3 smellDirection = this.transform.InverseTransformPoint(thing.transform.position); float distance = smellDirection.magnitude; float angle = Vector3.Angle(Vector3.forward, smellDirection); + if (angle < smellAngle && smellDirection.magnitude > 0.01) { - float intensity = pheromone.StrengthAt(distance); - Vector3 smell = smellDirection.normalized * intensity; - switch (pheromone.type) { - case Pheromone.Type.Food: - foodReceptor?.ProcessStimulus(smell); - break; - case Pheromone.Type.Home: - homeReceptor?.ProcessStimulus(smell); - break; + // float intensity = pheromone.StrengthAt(distance); + // Vector3 smell = smellDirection.normalized * intensity; + Vector3 smell = Vector3.zero; + + int id = thing.GetInstanceID(); + Neuron receptor = null; + + Pheromone pheromone = thing.GetComponentInParent(); + if (pheromone != null) { + // multiply by distance to compensate for strong and weak smells + smell = pheromone.StrengthAt(smellDirection) * distance / 10; + switch (pheromone.type) { + case Pheromone.Type.Food: + receptor = foodReceptors?.GetNeuron(id, "Output", pheromone.name); + //Debug.DrawRay(this.transform.position, this.transform.rotation * smell, Color.magenta); + break; + case Pheromone.Type.Home: + receptor = homeReceptors?.GetNeuron(id, "Output", pheromone.name); + //Debug.DrawRay(this.transform.position, this.transform.rotation * smell, Color.cyan); + break; + } } - // Debug.DrawLine(this.transform.position, pheromone.transform.position, Color.magenta); - } - } - - void SmellFood(Collider thing) { - Food food = thing.GetComponentInParent(); - if (food == null) - return; - - Vector3 smellDirection = this.transform.InverseTransformPoint(food.transform.position); - float distance = smellDirection.magnitude; - float angle = Vector3.Angle(Vector3.forward, smellDirection); - if (angle < smellAngle && distance > 0.01) { - float intensity = food.StrengthAt(distance); - foodReceptor?.ProcessStimulus(smellDirection.normalized * intensity); - //Debug.DrawLine(this.transform.position, food.transform.position, Color.red); - } - } - - void SmellHome(Collider thing) { - AntsNest nest = thing.GetComponentInParent(); - if (nest == null) - return; - - Vector3 smellDirection = this.transform.InverseTransformPoint(nest.transform.position); - float distance = smellDirection.magnitude; - float angle = Vector3.Angle(Vector3.forward, smellDirection); - if (angle < smellAngle && distance > 0.01) { - float intensity = nest.StrengthAt(distance); - homeReceptor?.ProcessStimulus(smellDirection.normalized * intensity); - //Debug.DrawLine(this.transform.position, nest.transform.position, Color.red); + Food food = thing.GetComponentInParent(); + if (food != null) { + receptor = foodReceptors?.GetNeuron(id, "Output", food.name); + smell = food.StrengthAt(smellDirection) * distance / 10; + //Debug.DrawRay(this.transform.position, this.transform.rotation * smell, Color.magenta); + } + AntsNest home = thing.GetComponentInParent(); + if (home != null) { + receptor = homeReceptors?.GetNeuron(id, "Output", home.name); + smell = home.StrengthAt(smellDirection) * distance / 10; + //Debug.DrawRay(this.transform.position, this.transform.rotation * smell, Color.cyan); + } + receptor?.ProcessStimulus(smell); } } diff --git a/Runtime/Scripts/Odorant.cs b/Runtime/Scripts/Odorant.cs index 0046e4f..97573b9 100644 --- a/Runtime/Scripts/Odorant.cs +++ b/Runtime/Scripts/Odorant.cs @@ -12,6 +12,12 @@ namespace CreatureControl { float intensity = this.strength / (4.0f * Mathf.PI * distance * distance); return intensity; } + public Vector3 StrengthAt(Vector3 localPosition) { + float magnitude = localPosition.magnitude; + float intensity = StrengthAt(magnitude); + Vector3 intensity3 = localPosition.normalized * intensity; + return intensity3; + } } } \ No newline at end of file diff --git a/Samples/Brain/Foraging.asset b/Samples/Brain/Foraging.asset index eb473f0..519d1b3 100644 --- a/Samples/Brain/Foraging.asset +++ b/Samples/Brain/Foraging.asset @@ -33,6 +33,8 @@ MonoBehaviour: - rid: 4201949834634854857 - rid: 4201949834634854858 - rid: 4201949854258954578 + - rid: 4201949854258954866 + - rid: 4201949854258955200 references: version: 2 RefIds: @@ -41,20 +43,20 @@ MonoBehaviour: - rid: 4201949831649034325 type: {class: Neuron, ns: NanoBrain, asm: Assembly-CSharp} data: - name: Output + name: Movement parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 0, y: 0, z: 1} _synapses: - neuron: rid: 4201949831649034327 - weight: 1 + weight: 4 - neuron: rid: 4201949834634854855 - weight: 1 + weight: 0.8 - neuron: rid: 4201949834634854857 - weight: 1 + weight: 0.8 combinator: 0 _curvePreset: 0 curve: @@ -83,14 +85,14 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: [] - rid: 4201949831649034327 type: {class: Neuron, ns: NanoBrain, asm: Assembly-CSharp} data: name: Collision parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 0, y: 0, z: 0} _synapses: - neuron: @@ -127,7 +129,7 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: - rid: 4201949831649034325 - rid: 4201949834634854801 @@ -136,7 +138,7 @@ MonoBehaviour: data: name: Hit Left parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 0, y: 0, z: 0} _synapses: [] combinator: 0 @@ -167,7 +169,7 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: - rid: 4201949831649034327 - rid: 4201949831649034329 @@ -175,7 +177,7 @@ MonoBehaviour: data: name: Hit Right parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 0, y: 0, z: 0} _synapses: [] combinator: 0 @@ -206,7 +208,7 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: - rid: 4201949831649034327 - rid: 4201949834634854702 @@ -214,7 +216,7 @@ MonoBehaviour: data: name: Beat parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 0, y: 0, z: 0} _synapses: [] combinator: 0 @@ -245,7 +247,7 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: - rid: 4201949834634854704 - rid: 4201949854258954578 @@ -254,7 +256,7 @@ MonoBehaviour: data: name: Home Pheromones parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 1, y: 1, z: 1} _synapses: - neuron: @@ -291,16 +293,19 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: [] - rid: 4201949834634854727 type: {class: Neuron, ns: NanoBrain, asm: Assembly-CSharp} data: name: Food Receptor parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 0, y: 0, z: 0} - _synapses: [] + _synapses: + - neuron: + rid: 4201949854258954867 + weight: 1 combinator: 0 _curvePreset: 0 curve: @@ -329,7 +334,7 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: - rid: 4201949834634854857 - rid: 4201949834634854801 @@ -337,7 +342,7 @@ MonoBehaviour: data: name: Mouth parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 0, y: 0, z: 0} _synapses: - neuron: @@ -371,14 +376,14 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: [] - rid: 4201949834634854833 type: {class: Neuron, ns: NanoBrain, asm: Assembly-CSharp} data: name: Having Food parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 0, y: 0, z: 0} _synapses: [] combinator: 0 @@ -409,7 +414,7 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 1 - trace: 0 + lastUpdate: 0 _receivers: - rid: 4201949834634854855 - rid: 4201949834634854858 @@ -419,7 +424,7 @@ MonoBehaviour: data: name: Home Smell parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 1, y: 1, z: 1} _synapses: - neuron: @@ -456,7 +461,7 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: - rid: 4201949831649034325 - rid: 4201949834634854856 @@ -464,9 +469,12 @@ MonoBehaviour: data: name: Home Receptor parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 0, y: 0, z: 0} - _synapses: [] + _synapses: + - neuron: + rid: 4201949854258955201 + weight: 1 combinator: 0 _curvePreset: 0 curve: @@ -495,7 +503,7 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: - rid: 4201949834634854855 - rid: 4201949834634854857 @@ -503,7 +511,7 @@ MonoBehaviour: data: name: Food Smell parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 1, y: 1, z: 1} _synapses: - neuron: @@ -540,7 +548,7 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: - rid: 4201949831649034325 - rid: 4201949834634854858 @@ -548,7 +556,7 @@ MonoBehaviour: data: name: Not having Food parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 1, y: 1, z: 1} _synapses: - neuron: @@ -582,7 +590,7 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 1 - trace: 0 + lastUpdate: 0 _receivers: - rid: 4201949834634854857 - rid: 4201949834634854704 @@ -591,7 +599,7 @@ MonoBehaviour: data: name: Food Pheromones parent: - rid: 4201949854258954746 + rid: 4201949861964939451 bias: {x: 1, y: 1, z: 1} _synapses: - neuron: @@ -628,9 +636,107 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 persistOutput: 0 - trace: 0 + lastUpdate: 0 _receivers: [] - - rid: 4201949854258954746 + - rid: 4201949854258954866 + type: {class: Cluster, ns: NanoBrain, asm: Assembly-CSharp} + data: + name: Food Receptors + parent: + rid: 4201949861964939451 + prefab: {fileID: 11400000, guid: 13516cb1b506d662db7775f7cd16dbca, type: 2} + instanceCount: 6 + nuclei: + - rid: 4201949854258954867 + - rid: 4201949854258954867 + type: {class: Neuron, ns: NanoBrain, asm: Assembly-CSharp} + data: + name: Output + parent: + rid: 4201949854258954866 + bias: {x: 0, y: 0, z: 0} + _synapses: [] + combinator: 0 + _curvePreset: 0 + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + - serializedVersion: 3 + time: 1000 + value: 1000 + inSlope: 1 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + curveMax: 1 + persistOutput: 0 + lastUpdate: 0 + _receivers: + - rid: 4201949834634854727 + - rid: 4201949854258955200 + type: {class: Cluster, ns: NanoBrain, asm: Assembly-CSharp} + data: + name: Home Receptors + parent: + rid: 4201949861964939451 + prefab: {fileID: 11400000, guid: 13516cb1b506d662db7775f7cd16dbca, type: 2} + instanceCount: 6 + nuclei: + - rid: 4201949854258955201 + - rid: 4201949854258955201 + type: {class: Neuron, ns: NanoBrain, asm: Assembly-CSharp} + data: + name: Output + parent: + rid: 4201949854258955200 + bias: {x: 0, y: 0, z: 0} + _synapses: [] + combinator: 0 + _curvePreset: 0 + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + - serializedVersion: 3 + time: 1000 + value: 1000 + inSlope: 1 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + curveMax: 1 + persistOutput: 0 + lastUpdate: 0 + _receivers: + - rid: 4201949834634854856 + - rid: 4201949861964939451 type: {class: Cluster, ns: NanoBrain, asm: Assembly-CSharp} data: name: Foraging @@ -653,3 +759,5 @@ MonoBehaviour: - rid: 4201949834634854857 - rid: 4201949834634854858 - rid: 4201949854258954578 + - rid: 4201949854258954866 + - rid: 4201949854258955200 diff --git a/Samples/Brain/Foraging.asset.meta b/Samples/Brain/Foraging.asset.meta index 551433b..ebe1a03 100644 --- a/Samples/Brain/Foraging.asset.meta +++ b/Samples/Brain/Foraging.asset.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c8e4b0990eb7dbbc4bee34addd9cd2b8 +guid: 17e54c217d4c2a8daa851222f0591dd2 NativeFormatImporter: externalObjects: {} mainObjectFileID: 11400000 diff --git a/Samples/Brain/Pheromone.asset b/Samples/Brain/Pheromone.asset new file mode 100644 index 0000000..753afdc --- /dev/null +++ b/Samples/Brain/Pheromone.asset @@ -0,0 +1,75 @@ +%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: 60a957541c24c57e78018c202ebb1d9b, type: 3} + m_Name: Pheromone + m_EditorClassIdentifier: + cluster: + name: + parent: + rid: -2 + prefab: {fileID: 11400000} + instanceCount: 1 + nuclei: + - rid: 4201949854258954854 + references: + version: 2 + RefIds: + - rid: -2 + type: {class: , ns: , asm: } + - rid: 4201949854258954854 + type: {class: Neuron, ns: NanoBrain, asm: Assembly-CSharp} + data: + name: Output + parent: + rid: 4201949854258954855 + bias: {x: 0, y: 0, z: 0} + _synapses: [] + combinator: 0 + _curvePreset: 0 + curve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + - serializedVersion: 3 + time: 1000 + value: 1000 + inSlope: 1 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + curveMax: 1 + persistOutput: 0 + trace: 0 + _receivers: [] + - rid: 4201949854258954855 + type: {class: Cluster, ns: NanoBrain, asm: Assembly-CSharp} + data: + name: + parent: + rid: -2 + prefab: {fileID: 11400000} + instanceCount: 1 + nuclei: + - rid: 4201949854258954854 diff --git a/Samples/Brain/Pheromone.asset.meta b/Samples/Brain/Pheromone.asset.meta new file mode 100644 index 0000000..a5ec799 --- /dev/null +++ b/Samples/Brain/Pheromone.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 13516cb1b506d662db7775f7cd16dbca +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples/Prefabs/LowPolyAnt Variant.prefab b/Samples/Prefabs/LowPolyAnt Variant.prefab index 56af8da..ad17fb4 100644 --- a/Samples/Prefabs/LowPolyAnt Variant.prefab +++ b/Samples/Prefabs/LowPolyAnt Variant.prefab @@ -25,7 +25,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 143286242955637876} serializedVersion: 2 - m_LocalRotation: {x: -0.22205506, y: -0.7431153, z: -0.29594883, w: 0.55757105} + m_LocalRotation: {x: -0.22205536, y: -0.74311525, z: -0.2959492, w: 0.55757093} m_LocalPosition: {x: -0.00024003958, y: 0.0020915146, z: -0.0014802816} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 @@ -52,14 +52,14 @@ MonoBehaviour: _tarsus: {fileID: 8196205064751031824} _phalanges: {fileID: 0} _end: {fileID: 0} - _femurLength: 0.0024082733 - _tibiaLength: 0.0041295574 + _femurLength: 0.0024082724 + _tibiaLength: 0.0041295583 _tarsusLength: 0 _phalangesLength: 0 side: 0 target: {fileID: 6415599125966866927} - targetToBoneFemur: {x: 0.0759626, y: -0.70301473, z: -0.70301485, w: 0.075962685} - targetToBoneTibia: {x: -0.5739337, y: -0.41303778, z: -0.41303787, w: -0.5739338} + targetToBoneFemur: {x: 0.075962596, y: -0.70301473, z: -0.7030147, w: 0.07596261} + targetToBoneTibia: {x: -0.5739338, y: -0.41303772, z: -0.41303757, w: -0.57393384} --- !u!1 &705568938082032721 GameObject: m_ObjectHideFlags: 0 @@ -86,8 +86,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 705568938082032721} serializedVersion: 2 - m_LocalRotation: {x: -0.03981568, y: 0.9599673, z: -0.18536556, w: -0.20619665} - m_LocalPosition: {x: -0.0025763502, y: 0, z: -0.007210666} + m_LocalRotation: {x: -0.039815743, y: 0.95996726, z: -0.18536565, w: -0.20619684} + m_LocalPosition: {x: -0.0025763516, y: 0, z: -0.007210664} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -160,8 +160,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 771417713020922740} serializedVersion: 2 - m_LocalRotation: {x: 0.50033474, y: -0.000000014901159, z: -0.0000000037252899, w: 0.86583203} - m_LocalPosition: {x: 0, y: 1.4551915e-11, z: 0.0019033401} + m_LocalRotation: {x: 0.500335, y: -0, z: -0.000000012107192, w: 0.86583185} + m_LocalPosition: {x: 0, y: 0, z: 0.0019033398} m_LocalScale: {x: 0.99999994, y: 1, z: 0.99999994} m_ConstrainProportionsScale: 0 m_Children: @@ -194,8 +194,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 854478626558788248} serializedVersion: 2 - m_LocalRotation: {x: 0.13480826, y: 0.7633578, z: -0.16905655, w: 0.60871303} - m_LocalPosition: {x: 0.0052212873, y: 0, z: -0.0023041023} + m_LocalRotation: {x: 0.1348082, y: 0.7633578, z: -0.1690565, w: 0.6087131} + m_LocalPosition: {x: 0.005221286, y: 0, z: -0.002304102} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -302,8 +302,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1083078033105624184} serializedVersion: 2 - m_LocalRotation: {x: 0.7023513, y: 0.000000029802322, z: -0.000000052154064, w: 0.7118305} - m_LocalPosition: {x: 1.1641532e-10, y: -2.910383e-11, z: 0.0019033394} + m_LocalRotation: {x: 0.7023515, y: -0.00000014901161, z: 0.000000048428774, w: 0.7118304} + m_LocalPosition: {x: 2.910383e-10, y: -8.731149e-11, z: 0.0019033398} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -506,8 +506,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2032809585173054758} serializedVersion: 2 - m_LocalRotation: {x: 0.6516017, y: -0.000000059604645, z: 0.000000022351742, w: 0.7585614} - m_LocalPosition: {x: -1.1641532e-10, y: -5.820766e-11, z: 0.0030040154} + m_LocalRotation: {x: 0.6516016, y: 0.00000008940697, z: -0.000000052154064, w: 0.7585614} + m_LocalPosition: {x: -2.3283064e-10, y: -1.1641532e-10, z: 0.003004015} m_LocalScale: {x: 1, y: 1.0000001, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -538,8 +538,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2174179322558643890} serializedVersion: 2 - m_LocalRotation: {x: 0.5662592, y: 0.000000014901161, z: -0.0000000037252903, w: 0.8242272} - m_LocalPosition: {x: 0, y: -1.7462298e-10, z: 0.0030040164} + m_LocalRotation: {x: 0.56625944, y: 0.000000029802322, z: 0.000000007450581, w: 0.82422715} + m_LocalPosition: {x: -1.1641532e-10, y: -3.4924597e-10, z: 0.0030040166} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -639,8 +639,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2247055388988280205} serializedVersion: 2 - m_LocalRotation: {x: -0.25057173, y: -0.00000005535319, z: 0.000000071577944, w: 0.96809804} - m_LocalPosition: {x: -2.9282865e-10, y: 0, z: 0.004176515} + m_LocalRotation: {x: -0.25057185, y: -0.0000000567234, z: 0.000000032103785, w: 0.96809804} + m_LocalPosition: {x: -4.916112e-11, y: 0, z: 0.0041765124} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] @@ -672,8 +672,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2344423464168616931} serializedVersion: 2 - m_LocalRotation: {x: 0.28778726, y: -0.46212685, z: 0.16157518, w: 0.82311046} - m_LocalPosition: {x: -0.0029576193, y: 0, z: 0.00044939894} + m_LocalRotation: {x: 0.28778717, y: -0.4621268, z: 0.16157508, w: 0.82311046} + m_LocalPosition: {x: -0.0029576183, y: 0, z: 0.00044939917} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -746,8 +746,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2503148901578430105} serializedVersion: 2 - m_LocalRotation: {x: 0.8119707, y: -0.00000011920929, z: 0.000000014901161, w: 0.5836983} - m_LocalPosition: {x: 2.910383e-11, y: -2.3283064e-10, z: 0.002408273} + m_LocalRotation: {x: 0.811971, y: 0.00000008940697, z: -0.00000008940697, w: 0.5836978} + m_LocalPosition: {x: -1.7462298e-10, y: -2.3283064e-10, z: 0.0024082724} m_LocalScale: {x: 0.9999998, y: 1, z: 1.0000001} m_ConstrainProportionsScale: 0 m_Children: @@ -778,8 +778,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2882239523612217299} serializedVersion: 2 - m_LocalRotation: {x: -0.19549885, y: 0.000000002172962, z: 0.0000000057906107, w: 0.9807039} - m_LocalPosition: {x: -2.7544242e-10, y: 6.9849193e-10, z: 0.0030214665} + m_LocalRotation: {x: -0.1954989, y: -0.000000038309114, z: 0.000000027783733, w: 0.98070395} + m_LocalPosition: {x: 1.91438e-11, y: 0, z: 0.0030214656} m_LocalScale: {x: 1.0000001, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] @@ -809,8 +809,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3374865219866590095} serializedVersion: 2 - m_LocalRotation: {x: -0.24540225, y: -0.000000010576111, z: 0.000000011730633, w: 0.9694213} - m_LocalPosition: {x: 1.1680018e-10, y: 6.9849193e-10, z: 0.0041061183} + m_LocalRotation: {x: -0.24540237, y: -0.000000019989661, z: 0.000000018695667, w: 0.9694214} + m_LocalPosition: {x: 1.9036872e-10, y: 0, z: 0.0041061183} m_LocalScale: {x: 0.9999999, y: 0.9999999, z: 0.9999999} m_ConstrainProportionsScale: 0 m_Children: [] @@ -842,8 +842,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3392280556579772079} serializedVersion: 2 - m_LocalRotation: {x: 0.16025314, y: -0.7708367, z: 0.21358094, w: 0.5783709} - m_LocalPosition: {x: -0.0035855495, y: 0, z: -0.0024545891} + m_LocalRotation: {x: 0.16025315, y: -0.7708368, z: 0.21358101, w: 0.5783708} + m_LocalPosition: {x: -0.0035855481, y: 0, z: -0.0024545894} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -917,7 +917,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3800556883426211010} serializedVersion: 2 - m_LocalRotation: {x: -0.055727538, y: 0.1424893, z: 0.00803545, w: 0.9881937} + m_LocalRotation: {x: -0.05572754, y: 0.14248934, z: 0.008035455, w: 0.98819363} m_LocalPosition: {x: 0.0011845141, y: 0.0022176225, z: -0.0008242579} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 @@ -944,14 +944,14 @@ MonoBehaviour: _tarsus: {fileID: 615395507866503330} _phalanges: {fileID: 0} _end: {fileID: 0} - _femurLength: 0.0019033402 - _tibiaLength: 0.0030214665 + _femurLength: 0.0019033398 + _tibiaLength: 0.0030214654 _tarsusLength: 0 _phalangesLength: 0 side: 0 target: {fileID: 5961476926804711974} - targetToBoneFemur: {x: 0.3940539, y: -0.58712995, z: -0.58713037, w: 0.39405394} - targetToBoneTibia: {x: -0.1659759, y: -0.6873515, z: -0.68735147, w: -0.1659759} + targetToBoneFemur: {x: 0.3940539, y: -0.58713, z: -0.58713037, w: 0.39405394} + targetToBoneTibia: {x: -0.16597603, y: -0.6873516, z: -0.6873514, w: -0.1659759} --- !u!1 &3918606941992177650 GameObject: m_ObjectHideFlags: 0 @@ -977,7 +977,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3918606941992177650} serializedVersion: 2 - m_LocalRotation: {x: -0.13913122, y: -0.48328668, z: -0.07811372, w: 0.86079895} + m_LocalRotation: {x: -0.1391313, y: -0.48328656, z: -0.078113794, w: 0.860799} m_LocalPosition: {x: -0.00058102724, y: 0.0022176215, z: -0.0009999603} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 @@ -1004,14 +1004,14 @@ MonoBehaviour: _tarsus: {fileID: 8056997594033936271} _phalanges: {fileID: 0} _end: {fileID: 0} - _femurLength: 0.0019033395 - _tibiaLength: 0.0029819135 + _femurLength: 0.0019033398 + _tibiaLength: 0.0029819137 _tarsusLength: 0 _phalangesLength: 0 side: 0 target: {fileID: 5535986122466163059} - targetToBoneFemur: {x: 0.54446495, y: -0.4511739, z: -0.4511739, w: 0.54446507} - targetToBoneTibia: {x: 0.42917126, y: 0.5619716, z: 0.56197155, w: 0.4291714} + targetToBoneFemur: {x: 0.54446507, y: -0.45117387, z: -0.45117393, w: 0.544465} + targetToBoneTibia: {x: 0.42917144, y: 0.56197166, z: 0.5619715, w: 0.42917144} --- !u!1 &4040189390208258658 GameObject: m_ObjectHideFlags: 0 @@ -1038,8 +1038,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 4040189390208258658} serializedVersion: 2 - m_LocalRotation: {x: 0.0773633, y: 0.9162942, z: -0.21589425, w: 0.32834378} - m_LocalPosition: {x: 0.004090543, y: 0, z: -0.006165691} + m_LocalRotation: {x: 0.07736324, y: 0.9162942, z: -0.21589403, w: 0.3283439} + m_LocalPosition: {x: 0.0040905434, y: 0, z: -0.0061656903} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -1324,8 +1324,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 4789320418346547653} serializedVersion: 2 - m_LocalRotation: {x: 0.26484576, y: 0.13751145, z: -0.038188547, w: 0.95367134} - m_LocalPosition: {x: 0.002225488, y: 0, z: 0.00271038} + m_LocalRotation: {x: 0.264846, y: 0.13751146, z: -0.0381886, w: 0.9536713} + m_LocalPosition: {x: 0.0022254875, y: 0, z: 0.002710377} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -1503,8 +1503,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5872439506191515607} serializedVersion: 2 - m_LocalRotation: {x: 0.6839642, y: 0.00000011920929, z: -0.000000014901161, w: 0.7295157} - m_LocalPosition: {x: -2.0372681e-10, y: 2.910383e-11, z: 0.0024082721} + m_LocalRotation: {x: 0.6839639, y: -0, z: -0.000000014901161, w: 0.7295159} + m_LocalPosition: {x: 5.820766e-11, y: 8.731149e-11, z: 0.0024082721} m_LocalScale: {x: 1, y: 1.0000001, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -1536,7 +1536,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5934342576853380286} serializedVersion: 2 - m_LocalRotation: {x: 0.034137037, y: 0.9646966, z: 0.15892807, w: -0.20721248} + m_LocalRotation: {x: 0.034137055, y: 0.9646966, z: 0.15892811, w: -0.20721269} m_LocalPosition: {x: -0.00033019992, y: 0.002194208, z: -0.0022233187} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 @@ -1563,14 +1563,14 @@ MonoBehaviour: _tarsus: {fileID: 8105911159671643989} _phalanges: {fileID: 0} _end: {fileID: 0} - _femurLength: 0.0030040168 - _tibiaLength: 0.004106119 + _femurLength: 0.003004017 + _tibiaLength: 0.0041061183 _tarsusLength: 0 _phalangesLength: 0 side: 0 target: {fileID: 8439091168374640007} - targetToBoneFemur: {x: -0.4297835, y: 0.56150347, z: 0.5615035, w: -0.42978358} - targetToBoneTibia: {x: -0.6955418, y: 0.12736529, z: 0.12736529, w: -0.6955415} + targetToBoneFemur: {x: -0.42978352, y: 0.5615036, z: 0.5615035, w: -0.42978352} + targetToBoneTibia: {x: -0.6955417, y: 0.1273652, z: 0.1273651, w: -0.6955417} --- !u!1 &6065556596967559351 GameObject: m_ObjectHideFlags: 0 @@ -1595,8 +1595,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6065556596967559351} serializedVersion: 2 - m_LocalRotation: {x: -0.2783754, y: -0.000000037985085, z: 0.000000022928376, w: 0.96047235} - m_LocalPosition: {x: 1.2023199e-10, y: 0, z: 0.0029819133} + m_LocalRotation: {x: -0.27837572, y: 0.000000033831125, z: -0.00000006138512, w: 0.96047235} + m_LocalPosition: {x: 1.734421e-11, y: 4.656613e-10, z: 0.0029819135} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] @@ -1627,7 +1627,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6293298600777026745} serializedVersion: 2 - m_LocalRotation: {x: -0.065785386, y: 0.92331046, z: 0.18358438, w: 0.33085796} + m_LocalRotation: {x: -0.065785415, y: 0.92331034, z: 0.18358444, w: 0.33085802} m_LocalPosition: {x: 0.0009336879, y: 0.0024799206, z: -0.0023264561} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 @@ -1660,8 +1660,8 @@ MonoBehaviour: _phalangesLength: 0 side: 0 target: {fileID: 7871660662594056517} - targetToBoneFemur: {x: 0.68627703, y: -0.17036355, z: -0.1703638, w: 0.6862772} - targetToBoneTibia: {x: 0.6842575, y: -0.17830335, z: -0.17830299, w: 0.6842574} + targetToBoneFemur: {x: 0.68627715, y: -0.1703635, z: -0.17036393, w: 0.6862773} + targetToBoneTibia: {x: 0.68425757, y: -0.17830308, z: -0.17830327, w: 0.68425703} --- !u!1 &7202005123023226514 GameObject: m_ObjectHideFlags: 0 @@ -1873,7 +1873,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7731414149959408473} serializedVersion: 2 - m_LocalRotation: {x: -0.17347457, y: 0.75097865, z: 0.2175461, w: 0.5988417} + m_LocalRotation: {x: -0.17347425, y: 0.75097877, z: 0.21754575, w: 0.5988418} m_LocalPosition: {x: 0.0008435269, y: 0.0020915149, z: -0.0013045785} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 @@ -1900,14 +1900,14 @@ MonoBehaviour: _tarsus: {fileID: 7805495626236998544} _phalanges: {fileID: 0} _end: {fileID: 0} - _femurLength: 0.0024082721 - _tibiaLength: 0.004176515 + _femurLength: 0.0024082724 + _tibiaLength: 0.004176512 _tarsusLength: 0 _phalangesLength: 0 side: 0 target: {fileID: 5250359002763488712} - targetToBoneFemur: {x: 0.66122675, y: -0.25055832, z: -0.25055823, w: 0.66122663} - targetToBoneTibia: {x: 0.5807946, y: -0.40333316, z: -0.40333334, w: 0.58079493} + targetToBoneFemur: {x: 0.6612268, y: -0.25055817, z: -0.2505583, w: 0.6612265} + targetToBoneTibia: {x: 0.5807945, y: -0.40333316, z: -0.40333313, w: 0.58079475} --- !u!1 &7870208251778510133 GameObject: m_ObjectHideFlags: 0 @@ -2037,8 +2037,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 8102965106138119688} serializedVersion: 2 - m_LocalRotation: {x: -0.2783009, y: 0.000000037683723, z: -0.000000053537306, w: 0.960494} - m_LocalPosition: {x: 9.294565e-12, y: 0, z: 0.0042412234} + m_LocalRotation: {x: -0.278301, y: -0.0000000993223, z: 0.000000084176655, w: 0.960494} + m_LocalPosition: {x: -2.2376767e-10, y: 0.0000000018626449, z: 0.0042412234} m_LocalScale: {x: 1, y: 0.9999999, z: 0.9999999} m_ConstrainProportionsScale: 0 m_Children: [] @@ -2068,8 +2068,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 8620845555170327592} serializedVersion: 2 - m_LocalRotation: {x: -0.29382303, y: 0.000000115436556, z: -0.0000000994468, w: 0.9558599} - m_LocalPosition: {x: 3.151205e-10, y: 0, z: 0.0041295574} + m_LocalRotation: {x: -0.29382306, y: -0.000000100343954, z: 0.00000013887743, w: 0.95585984} + m_LocalPosition: {x: 1.65906e-10, y: 9.313226e-10, z: 0.0041295574} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] @@ -2089,15 +2089,15 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 878733956556189420, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x - value: -0.4692818 + value: -0.46928197 objectReference: {fileID: 0} - target: {fileID: 878733956556189420, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y - value: -0.63777685 + value: -0.6377769 objectReference: {fileID: 0} - target: {fileID: 878733956556189420, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z - value: -0.17352022 + value: -0.17352007 objectReference: {fileID: 0} - target: {fileID: 921079959415626025, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w @@ -2105,31 +2105,31 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 921079959415626025, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x - value: -0.43574923 + value: -0.43574932 objectReference: {fileID: 0} - target: {fileID: 921079959415626025, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y - value: 0.14708138 + value: 0.1470814 objectReference: {fileID: 0} - target: {fileID: 921079959415626025, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z - value: -0.34798685 + value: -0.34798694 objectReference: {fileID: 0} - target: {fileID: 1185156659557624868, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w - value: 0.28808329 + value: 0.28808293 objectReference: {fileID: 0} - target: {fileID: 1185156659557624868, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x - value: -0.5423464 + value: -0.5423462 objectReference: {fileID: 0} - target: {fileID: 1185156659557624868, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y - value: -0.5076532 + value: -0.5076529 objectReference: {fileID: 0} - target: {fileID: 1185156659557624868, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z - value: 0.604282 + value: 0.6042826 objectReference: {fileID: 0} - target: {fileID: 3207777328726177782, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalPosition.x @@ -2173,31 +2173,31 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 4217164170368883032, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w - value: 0.8540212 + value: 0.85402143 objectReference: {fileID: 0} - target: {fileID: 4217164170368883032, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x - value: -0.3250143 + value: -0.32501405 objectReference: {fileID: 0} - target: {fileID: 4217164170368883032, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y - value: 0.22636859 + value: 0.22636862 objectReference: {fileID: 0} - target: {fileID: 4217164170368883032, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z - value: 0.3372994 + value: 0.33729875 objectReference: {fileID: 0} - target: {fileID: 4280044992070512807, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w - value: 0.03278106 + value: 0.032781146 objectReference: {fileID: 0} - target: {fileID: 4280044992070512807, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x - value: -0.044934656 + value: -0.04493456 objectReference: {fileID: 0} - target: {fileID: 4280044992070512807, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y - value: 0.8327048 + value: 0.83270484 objectReference: {fileID: 0} - target: {fileID: 4280044992070512807, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z @@ -2205,7 +2205,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 4355293283798979008, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w - value: -0.5112789 + value: -0.5112788 objectReference: {fileID: 0} - target: {fileID: 4355293283798979008, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x @@ -2213,11 +2213,11 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 4355293283798979008, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y - value: 0.2597021 + value: 0.25970212 objectReference: {fileID: 0} - target: {fileID: 4355293283798979008, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z - value: -0.1114271 + value: -0.11142698 objectReference: {fileID: 0} - target: {fileID: 5152346580398522335, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w @@ -2233,23 +2233,23 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 5152346580398522335, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z - value: -0.087881684 + value: -0.08788167 objectReference: {fileID: 0} - target: {fileID: 5426871202115288240, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w - value: 0.75851035 + value: 0.7585102 objectReference: {fileID: 0} - target: {fileID: 5426871202115288240, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x - value: 0.57238495 + value: 0.5723851 objectReference: {fileID: 0} - target: {fileID: 5426871202115288240, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y - value: -0.008788292 + value: -0.008788249 objectReference: {fileID: 0} - target: {fileID: 5426871202115288240, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z - value: -0.3113845 + value: -0.31138477 objectReference: {fileID: 0} - target: {fileID: 5498987105763849279, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_Name @@ -2257,23 +2257,23 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 6797057378463114089, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w - value: 0.4702007 + value: 0.47020072 objectReference: {fileID: 0} - target: {fileID: 6797057378463114089, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x - value: 0.13349886 + value: 0.1334991 objectReference: {fileID: 0} - target: {fileID: 6797057378463114089, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y - value: 0.79217046 + value: 0.7921703 objectReference: {fileID: 0} - target: {fileID: 6797057378463114089, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z - value: -0.3654522 + value: -0.3654527 objectReference: {fileID: 0} - target: {fileID: 7468650878180815412, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w - value: -0.028299622 + value: -0.028299695 objectReference: {fileID: 0} - target: {fileID: 7468650878180815412, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x @@ -2281,19 +2281,19 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 7468650878180815412, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y - value: 0.71126777 + value: 0.7112677 objectReference: {fileID: 0} - target: {fileID: 7468650878180815412, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z - value: 0.15780832 + value: 0.15780841 objectReference: {fileID: 0} - target: {fileID: 8564223698435002511, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w - value: 0.6106671 + value: 0.61066705 objectReference: {fileID: 0} - target: {fileID: 8564223698435002511, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x - value: 0.2575532 + value: 0.25755325 objectReference: {fileID: 0} - target: {fileID: 8564223698435002511, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y @@ -2305,19 +2305,19 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 8675830525085349096, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.w - value: 0.70776933 + value: 0.70776963 objectReference: {fileID: 0} - target: {fileID: 8675830525085349096, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.x - value: 0.38709378 + value: 0.38709393 objectReference: {fileID: 0} - target: {fileID: 8675830525085349096, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.y - value: -0.17679322 + value: -0.17679343 objectReference: {fileID: 0} - target: {fileID: 8675830525085349096, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3} propertyPath: m_LocalRotation.z - value: -0.563884 + value: -0.56388354 objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] @@ -2574,24 +2574,6 @@ MonoBehaviour: persistOutput: 0 trace: 0 _receivers: [] - pheromoneSteering: - name: - parent: - rid: -2 - bias: {x: 0, y: 0, z: 0} - _synapses: [] - combinator: 0 - _curvePreset: 0 - curve: - serializedVersion: 2 - m_Curve: [] - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - curveMax: 0 - persistOutput: 0 - trace: 0 - _receivers: [] foodReceptor: name: parent: @@ -2628,24 +2610,13 @@ MonoBehaviour: persistOutput: 0 trace: 0 _receivers: [] - foodSmell: + pheromoneReceptors: name: parent: rid: -2 - bias: {x: 0, y: 0, z: 0} - _synapses: [] - combinator: 0 - _curvePreset: 0 - curve: - serializedVersion: 2 - m_Curve: [] - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - curveMax: 0 - persistOutput: 0 - trace: 0 - _receivers: [] + prefab: {fileID: 0} + instanceCount: 0 + nuclei: [] targetDirection: name: parent: @@ -2701,7 +2672,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 92f34a5e4027a1dc39efd8ce63cf6aba, type: 3} m_Name: m_EditorClassIdentifier: - brainPrefab: {fileID: 11400000, guid: c8e4b0990eb7dbbc4bee34addd9cd2b8, type: 2} + brainPrefab: {fileID: 11400000, guid: 17e54c217d4c2a8daa851222f0591dd2, type: 2} --- !u!4 &5208545581280796884 stripped Transform: m_CorrespondingSourceObject: {fileID: 4280044992070512807, guid: 4dff5bed1fdfdda6cb1a398623e62f76, type: 3}