From d9ba98da47c69918ca23526b8a668692626a77e2 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Mon, 9 Mar 2026 11:10:17 +0100 Subject: [PATCH] WIP: Initial scripts --- .gitignore | 5 + Editor.meta | 8 + LICENSE.meta | 7 + README.md.meta | 7 + Runtime.meta | 8 + Runtime/Scripts.meta | 8 + Runtime/Scripts/AnimatedAnt.cs | 245 +++++++++++++++++++++++++++ Runtime/Scripts/AnimatedAnt.cs.meta | 11 ++ Runtime/Scripts/AntennaTouch.cs | 17 ++ Runtime/Scripts/AntennaTouch.cs.meta | 11 ++ Runtime/Scripts/AntsNest.cs | 32 ++++ Runtime/Scripts/AntsNest.cs.meta | 11 ++ Runtime/Scripts/Food.cs | 5 + Runtime/Scripts/Food.cs.meta | 11 ++ Runtime/Scripts/Mouth.cs | 64 +++++++ Runtime/Scripts/Mouth.cs.meta | 11 ++ Runtime/Scripts/Odorant.cs | 10 ++ Runtime/Scripts/Odorant.cs.meta | 11 ++ Runtime/Scripts/Pheromone.cs | 22 +++ Runtime/Scripts/Pheromone.cs.meta | 11 ++ Tests.meta | 8 + package.json | 27 +++ package.json.meta | 7 + 23 files changed, 557 insertions(+) create mode 100644 Editor.meta create mode 100644 LICENSE.meta create mode 100644 README.md.meta create mode 100644 Runtime.meta create mode 100644 Runtime/Scripts.meta create mode 100644 Runtime/Scripts/AnimatedAnt.cs create mode 100644 Runtime/Scripts/AnimatedAnt.cs.meta create mode 100644 Runtime/Scripts/AntennaTouch.cs create mode 100644 Runtime/Scripts/AntennaTouch.cs.meta create mode 100644 Runtime/Scripts/AntsNest.cs create mode 100644 Runtime/Scripts/AntsNest.cs.meta create mode 100644 Runtime/Scripts/Food.cs create mode 100644 Runtime/Scripts/Food.cs.meta create mode 100644 Runtime/Scripts/Mouth.cs create mode 100644 Runtime/Scripts/Mouth.cs.meta create mode 100644 Runtime/Scripts/Odorant.cs create mode 100644 Runtime/Scripts/Odorant.cs.meta create mode 100644 Runtime/Scripts/Pheromone.cs create mode 100644 Runtime/Scripts/Pheromone.cs.meta create mode 100644 Tests.meta create mode 100644 package.json create mode 100644 package.json.meta diff --git a/.gitignore b/.gitignore index 22e7db6..ec3ad73 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ # Visual Studio cache directory .vs/ +.vscode/ # Gradle cache directory .gradle/ @@ -73,3 +74,7 @@ crashlytics-build.properties /[Aa]ssets/[Ss]treamingAssets/aa.meta /[Aa]ssets/[Ss]treamingAssets/aa/* +# Passer +/Samples +/Samples.meta +/Samples~.meta diff --git a/Editor.meta b/Editor.meta new file mode 100644 index 0000000..d9c13b1 --- /dev/null +++ b/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9d715489a5eda538a959b6e4cb89d1bc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/LICENSE.meta b/LICENSE.meta new file mode 100644 index 0000000..9d955b4 --- /dev/null +++ b/LICENSE.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5099850b415a5749b9205723281be597 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md.meta b/README.md.meta new file mode 100644 index 0000000..de0e52f --- /dev/null +++ b/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d1f9abd0bb6ced431ad732ea64b1d722 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime.meta b/Runtime.meta new file mode 100644 index 0000000..d63eb51 --- /dev/null +++ b/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c85913106343e6988b160abd2d543f3f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts.meta b/Runtime/Scripts.meta new file mode 100644 index 0000000..a98755b --- /dev/null +++ b/Runtime/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 94025bfe58d21d7aba189dab371f3e97 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/AnimatedAnt.cs b/Runtime/Scripts/AnimatedAnt.cs new file mode 100644 index 0000000..e6e6778 --- /dev/null +++ b/Runtime/Scripts/AnimatedAnt.cs @@ -0,0 +1,245 @@ +using System.Collections.Generic; +using UnityEngine; + +[RequireComponent(typeof(NanoBrain))] +public class AnimatedAnt : MonoBehaviour { + private readonly float inertia = 0.2f; + private readonly float smellRadius = 1.0f; + private readonly float smellAngle = 80.0f; + + public GameObject homePheromonePrefab; + public GameObject foodPheromonePrefab; + + public AntennaTouch touchLeft; + public AntennaTouch touchRight; + + public NanoBrain nanoBrain; + // brain output + public Neuron hasFood; + // brain input + public Nucleus pheromoneSteering; + public Nucleus hitLeft; + public Nucleus hitRight; + public Nucleus beat; + public Receptor foodReceptor; + public Receptor homeReceptor; + + public new Rigidbody rigidbody; + public Animator animator; + public float forwardSpeed = 1; + public float rotationSpeed = 1; + public Vector3 linearVelocity; + public Vector3 angularVelocity; + + protected virtual void Awake() { + this.animator = GetComponentInChildren(); + if (this.animator == null && this.transform.parent != null) + this.animator = this.transform.parent.GetComponentInChildren(); + this.nanoBrain = GetComponentInChildren(); + + this.rigidbody = GetComponentInParent(); + this.rigidbody.isKinematic = false; + } + + + void Start() { + Cluster brain = this.nanoBrain.brain; + if (brain != null) { + // brain outputs + this.pheromoneSteering = brain.GetNucleus("Pheromone Steering"); + + + if (brain.GetNucleus("Home Pheromones") is Neuron homePheromones) + homePheromones.WhenFiring += PlaceHomePheromone; + if (brain.GetNucleus("Food Pheromones") is Neuron foodPheromones) + foodPheromones.WhenFiring += PlaceFoodPheromone; + + this.hasFood = brain.GetNucleus("Having Food") as Neuron; + // brain inputs + this.beat = brain.GetNucleus("Beat"); + this.hitLeft = brain.GetNucleus("Hit Left"); + this.hitRight = brain.GetNucleus("Hit Right"); + this.foodReceptor = brain.GetNucleus("Food Receptor") as Receptor; + this.homeReceptor = brain.GetNucleus("Home Receptor") as Receptor; + } + + this.linearVelocity = Vector3.forward; + + if (touchLeft != null) + touchLeft.touched += OnAntennaTouchLeft; + if (touchRight != null) + touchRight.touched += OnAntennaTouchRight; + + } + + void PlaceFoodPheromone() { + GameObject pheromoneObj = Instantiate(foodPheromonePrefab); + pheromoneObj.transform.position = this.transform.position; + } + void PlaceHomePheromone() { + GameObject pheromoneObj = Instantiate(homePheromonePrefab); + pheromoneObj.transform.position = this.transform.position; + } + + // Update is called once per frame + void Update() { + UpdateBeat(); + UpdateSmell(); + + if (this.nanoBrain == null || this.nanoBrain.brain == null || this.animator == null) + return; + + Vector3 localForce = nanoBrain.brain.defaultOutput.outputValue; + this.linearVelocity = (1 - inertia) * (Time.deltaTime * localForce.normalized) + inertia * this.linearVelocity; + this.linearVelocity = this.linearVelocity.normalized * 0.2f; + + // Vector3 linearVelocityWorld = this.transform.TransformVector(this.linearVelocity); + // this.rigidbody.linearVelocity = linearVelocityWorld; + this.animator.SetFloat("forward speed", this.linearVelocity.z * this.forwardSpeed); + + // Rotate towards the movement direction + if (this.linearVelocity != Vector3.zero) { + Quaternion targetRotation = Quaternion.LookRotation(this.linearVelocity); + Quaternion worldRotation = transform.rotation * targetRotation; + Quaternion deltaRotation = worldRotation * Quaternion.Inverse(transform.rotation); + + Vector3 eulerAngleChange = deltaRotation.eulerAngles; + // Normalize the Euler angles to avoid unexpected jumps due to 360-degree rotations + eulerAngleChange = new Vector3( + LinearAlgebra.Angles.Normalize(eulerAngleChange.x), + LinearAlgebra.Angles.Normalize(eulerAngleChange.y), + LinearAlgebra.Angles.Normalize(eulerAngleChange.z) + ); + + Vector3 angularVelocity = 5f * Mathf.Deg2Rad * eulerAngleChange; + //rigidbody.angularVelocity = angularVelocity; + this.animator.SetFloat("rotate speed", eulerAngleChange.y / 45 * this.rotationSpeed); + } + } + + public float beatInterval = 3; + float lastBeatTime = 0; + void UpdateBeat() { + if (lastBeatTime == 0) { + ulong delay = (ulong)(UnityEngine.Random.value * beatInterval); + lastBeatTime = Time.time - delay; + } + if (Time.time - lastBeatTime >= beatInterval) { + lastBeatTime = Time.time; + beat?.SetBias(Vector3.one); //, 0); + } + } + + void UpdateSmell() { + // To generate random basic movement, we add a small with a random direction with low intensity + float randomAngle = Random.Range(-smellAngle, smellAngle); + Vector3 randomDirection = Quaternion.AngleAxis(randomAngle, Vector3.up) * Vector3.forward * 0.01f; + pheromoneSteering?.SetBias(randomDirection); //, 0, "random"); + + Collider[] colliders = Physics.OverlapSphere(this.transform.position, smellRadius); + foreach (Collider collider in colliders) { + SmellPheromones(collider); + SmellFood(collider); + SmellHome(collider); + } + if (nanoBrain != null && nanoBrain.brain != null) + nanoBrain.brain.UpdateNuclei(); + } + + void SmellPheromones(Collider thing) { + Pheromone pheromone = thing.GetComponentInParent(); + if (pheromone == null) + return; + // if (hasFood == null) + // return; + + // if ((hasFood.outputValue.x > 0 && pheromone.type == Pheromone.Type.Home) || + // (hasFood.outputValue.x < 0 && pheromone.type == Pheromone.Type.Food)) { + + // Vector3 smellDirection = this.transform.InverseTransformPoint(pheromone.transform.position); + // float distance = smellDirection.magnitude; + // float angle = Vector3.Angle(Vector3.forward, smellDirection); + // if (angle < smellAngle && smellDirection.magnitude > 0.05) { + // float intensity = pheromone.StrengthAt(distance);//strength * (1 / distance); + // pheromoneSteering?.ProcessStimulus(pheromone.GetInstanceID(), smellDirection.normalized * intensity, + // pheromone.type.ToString() + " pheromone"); + // //Debug.DrawLine(this.transform.position, pheromone.transform.position, Color.magenta); + // } + // } + + Vector3 smellDirection = this.transform.InverseTransformPoint(pheromone.transform.position); + float distance = smellDirection.magnitude; + float angle = Vector3.Angle(Vector3.forward, smellDirection); + if (angle < smellAngle && smellDirection.magnitude > 0.05) { + float intensity = pheromone.StrengthAt(distance); + Vector3 smell = smellDirection.normalized * intensity; + switch (pheromone.type) { + case Pheromone.Type.Food: + //foodSmell?.ProcessStimulus(pheromone.GetInstanceID(), smell, "food pheromone"); + foodReceptor?.ProcessStimulus(smellDirection.normalized * intensity, pheromone.GetInstanceID(), "food pheromone"); + break; + case Pheromone.Type.Home: + //pheromoneSteering?.ProcessStimulus(pheromone.GetInstanceID(), smell, "home pheromone"); + //homeSmell?.ProcessStimulus(pheromone.GetInstanceID(), smell, "home pheromone"); + homeReceptor?.ProcessStimulus(smellDirection.normalized * intensity, pheromone.GetInstanceID(), "home pheromone"); + break; + } + //Debug.DrawLine(this.transform.position, pheromone.transform.position, Color.magenta); + } + + } + + void SmellFood(Collider thing) { + if (hasFood != null && hasFood.outputValue.x > 0) + // if it has food... + return; + + 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.05) { + float intensity = food.StrengthAt(distance); //strength * (1 / distance); + //foodSmell?.ProcessStimulus(food.GetInstanceID(), smellDirection.normalized * intensity, "food"); + foodReceptor?.ProcessStimulus(smellDirection.normalized * intensity, food.GetInstanceID(), "food"); + Debug.DrawLine(this.transform.position, food.transform.position, Color.red); + } + } + + void SmellHome(Collider thing) { + if (hasFood != null && hasFood.outputValue.x < 0) + // if it does not have food.... + return; + + 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.05) { + float intensity = nest.StrengthAt(distance); //strength * (1 / distance); + //homeSmell?.ProcessStimulus(nest.GetInstanceID(), smellDirection.normalized * intensity, "nest"); + Vector3 value = smellDirection.normalized * intensity; + homeReceptor?.ProcessStimulus(value, nest.GetInstanceID(), "nest"); + Debug.DrawLine(this.transform.position, nest.transform.position, Color.red); + } + } + + void OnAntennaTouchLeft(Collider other, bool isTouching) { + Vector3 touchDirection = Vector3.zero; + if (isTouching) + touchDirection = this.transform.InverseTransformVector(touchLeft.transform.forward); + hitLeft?.SetBias(touchDirection); //, other.GetInstanceID(), "Touch Left"); + } + void OnAntennaTouchRight(Collider other, bool isTouching) { + Vector3 touchDirection = Vector3.zero; + if (isTouching) + touchDirection = this.transform.InverseTransformVector(touchRight.transform.forward); + hitRight?.SetBias(touchDirection); //, other.GetInstanceID(), "Touch Right"); + } +} diff --git a/Runtime/Scripts/AnimatedAnt.cs.meta b/Runtime/Scripts/AnimatedAnt.cs.meta new file mode 100644 index 0000000..396041b --- /dev/null +++ b/Runtime/Scripts/AnimatedAnt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 456c8036e1196d245a3894315f92807d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/AntennaTouch.cs b/Runtime/Scripts/AntennaTouch.cs new file mode 100644 index 0000000..d9e99aa --- /dev/null +++ b/Runtime/Scripts/AntennaTouch.cs @@ -0,0 +1,17 @@ +using System; +using UnityEngine; + +public class AntennaTouch : MonoBehaviour +{ + public Action touched; + + // void OnTriggerEnter(Collider other) { + // touched?.Invoke(other, true); + // } + void OnTriggerStay(Collider other) { + touched?.Invoke(other, true); + } + void OnTriggerExit(Collider other) { + touched?.Invoke(other, false); + } +} diff --git a/Runtime/Scripts/AntennaTouch.cs.meta b/Runtime/Scripts/AntennaTouch.cs.meta new file mode 100644 index 0000000..efc0d51 --- /dev/null +++ b/Runtime/Scripts/AntennaTouch.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62f6712fb1e4fb40285b0bb5008716dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/AntsNest.cs b/Runtime/Scripts/AntsNest.cs new file mode 100644 index 0000000..64a3d0c --- /dev/null +++ b/Runtime/Scripts/AntsNest.cs @@ -0,0 +1,32 @@ +using System.Collections; +using UnityEngine; + +public class AntsNest : Odorant { + + public Ant antPrefab; + public uint numberOfAnts = 1; + public bool spawnAnt = false; + + private uint antCount = 0; + protected virtual void Start() { + StartCoroutine(SpawnAnts()); + } + IEnumerator SpawnAnts() { + while (numberOfAnts > 0) { + Ant ant = Instantiate(antPrefab); + ant.transform.eulerAngles = 360 * Random.value * Vector3.up; + ant.transform.position = this.transform.position + ant.transform.forward * 0.1F; + ant.name = "Ant " + (++antCount); + numberOfAnts--; + yield return new WaitForSeconds(0.2f); + } + } + + protected virtual void Update() { + if (spawnAnt) { + Ant ant = Instantiate(antPrefab); + ant.name = "Ant " + (++antCount); + spawnAnt = false; + } + } +} diff --git a/Runtime/Scripts/AntsNest.cs.meta b/Runtime/Scripts/AntsNest.cs.meta new file mode 100644 index 0000000..818609b --- /dev/null +++ b/Runtime/Scripts/AntsNest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d0564480d9177a79bba1b4a7d666d26 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/Food.cs b/Runtime/Scripts/Food.cs new file mode 100644 index 0000000..d9672b5 --- /dev/null +++ b/Runtime/Scripts/Food.cs @@ -0,0 +1,5 @@ +using UnityEngine; + +public class Food : Odorant +{ +} diff --git a/Runtime/Scripts/Food.cs.meta b/Runtime/Scripts/Food.cs.meta new file mode 100644 index 0000000..a31ab32 --- /dev/null +++ b/Runtime/Scripts/Food.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0a250a4dd786bd61cb1ea1f3618db2ee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/Mouth.cs b/Runtime/Scripts/Mouth.cs new file mode 100644 index 0000000..a05de44 --- /dev/null +++ b/Runtime/Scripts/Mouth.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using UnityEngine; + +public class Mouth : MonoBehaviour { + public GameObject foodPrefab; + public NanoBrain nanoBrain; + + public Neuron havingFood; + public Nucleus enableFoodPheromones; + + void Awake() { + this.nanoBrain = GetComponentInParent(); + if (this.nanoBrain == null || this.nanoBrain.brain == null) + return; + + if (nanoBrain.brain.GetNucleus("Mouth") is Neuron mouthNeuron) + mouthNeuron.WhenFiring += CheckGrab; + this.havingFood = nanoBrain.brain.GetNucleus("Having Food") as Neuron; + } + + void Start() { + havingFood?.SetBias(-Vector3.one); + } + + protected void CheckGrab() { + if (havingFood == null) + return; + Collider[] colliders = Physics.OverlapSphere(this.transform.position, 0.04f); + foreach (Collider c in colliders) { + if (havingFood.outputValue.x > 0) { + AntsNest nest = c.GetComponentInParent(); + if (nest != null) + LetGo(); + } + else { + Food food = c.GetComponentInParent(); + if (food != null) + Grab(); + } + } + } + + public bool Grab() { + //Debug.Log($"{this.transform.parent.name} Grab food"); + havingFood?.SetBias(Vector3.one); + GameObject food = Instantiate(foodPrefab); + + food.transform.SetParent(this.transform, false); + food.transform.localPosition = Vector3.zero; + return true; + } + + public void LetGo() { + //Debug.Log($"{this.transform.parent.name} Release food"); + + List toDelete = new(); + for (int i = 0; i < transform.childCount; i++) + toDelete.Add(transform.GetChild(i).gameObject); + foreach (GameObject go in toDelete) + Destroy(go); + + havingFood?.SetBias(-Vector3.one); + } +} diff --git a/Runtime/Scripts/Mouth.cs.meta b/Runtime/Scripts/Mouth.cs.meta new file mode 100644 index 0000000..62a5d08 --- /dev/null +++ b/Runtime/Scripts/Mouth.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 122a8c835cdbd95fb87b06d19573b3da +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/Odorant.cs b/Runtime/Scripts/Odorant.cs new file mode 100644 index 0000000..14cda79 --- /dev/null +++ b/Runtime/Scripts/Odorant.cs @@ -0,0 +1,10 @@ +using UnityEngine; + +public class Odorant : MonoBehaviour { + public float strength = 1; + + public float StrengthAt(float distance) { + float intensity = this.strength * (1 / distance); + return intensity; + } +} \ No newline at end of file diff --git a/Runtime/Scripts/Odorant.cs.meta b/Runtime/Scripts/Odorant.cs.meta new file mode 100644 index 0000000..de73b94 --- /dev/null +++ b/Runtime/Scripts/Odorant.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5715f90d63da4f8cc878030dce3e5c4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/Pheromone.cs b/Runtime/Scripts/Pheromone.cs new file mode 100644 index 0000000..2e5b488 --- /dev/null +++ b/Runtime/Scripts/Pheromone.cs @@ -0,0 +1,22 @@ +using UnityEngine; + +public class Pheromone : Odorant { + //public float strength = 30; // seconds + public float duration = 30; + + public enum Type { + Unknown = 0, + Food = 82, + Home = 83 + }; + public Type type = 0; + + // Update is called once per frame + void Update() { + this.strength -= (Time.deltaTime / duration); + if (this.strength < 0) { + // Debug.Log($"destroyed {this.name}"); + Destroy(this.gameObject); + } + } +} diff --git a/Runtime/Scripts/Pheromone.cs.meta b/Runtime/Scripts/Pheromone.cs.meta new file mode 100644 index 0000000..345cdc2 --- /dev/null +++ b/Runtime/Scripts/Pheromone.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8fa1bfe8c0b8b03e68a7557b345340c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests.meta b/Tests.meta new file mode 100644 index 0000000..b6af52f --- /dev/null +++ b/Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 141272d99626acc4a8055d90fa390dee +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json new file mode 100644 index 0000000..16facf8 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "life.passer.ant", + "version": "0.0.1", + "displayName": "NanoBrain Ant", + "description": "An 3D ant model with behaviour controlled by a neural network", + "unity": "2022.3", + "author": { + "name": "Passer Life", + "email": "support@passer.life", + "url": "https://passer.life" + }, + "documentationUrl": "https://passer.life/docs/Ant/Unity/index.html", + "changelogUrl": "https://git.passer.life/CreatureControl/Ant/releases", + "license": "MPL-2.0", + "licensesUrl": "https://git.passer.life/CreatureControl/Ant/src/branch/main/LICENSE", + "keywords": [ + "creatire", + "insect", + "ant", + "animation", + "ai", + "behaviour", "behavior", + "neuron", "neural network" + ], + "samples": [ + ] +} diff --git a/package.json.meta b/package.json.meta new file mode 100644 index 0000000..c525a07 --- /dev/null +++ b/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e422443485922f791a702b10ce70c06b +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: