diff --git a/schema/improbable/fish/fish.schema b/schema/improbable/fish/fish.schema new file mode 100644 index 0000000..d195b3d --- /dev/null +++ b/schema/improbable/fish/fish.schema @@ -0,0 +1,13 @@ +package improbable.general; + +component FishParameters { + // Schema file ID, unique within the project + id = 1003; + + // Entity's parameters + uint32 numfish = 1; + float initialspeed = 2; + float tanksize = 3; //from +tnksize to -tansize in all dimensions + + +} \ No newline at end of file diff --git a/schema/improbable/goal/Goal.schema b/schema/improbable/goal/Goal.schema index 0a64cac..b2c0738 100644 --- a/schema/improbable/goal/Goal.schema +++ b/schema/improbable/goal/Goal.schema @@ -7,7 +7,5 @@ component GoalParameters { // Entity's parameters float tanksize = 1; float goalspeed = 2; - uint32 numfish = 3; - float initialspeed = 4; - + } \ No newline at end of file diff --git a/snapshots/initial_world.snapshot b/snapshots/initial_world.snapshot index b6a3d36..4b12303 100644 Binary files a/snapshots/initial_world.snapshot and b/snapshots/initial_world.snapshot differ diff --git a/workers/unity/Assets/Editor/SnapshotMenu.cs b/workers/unity/Assets/Editor/SnapshotMenu.cs index 57ca414..ae216eb 100644 --- a/workers/unity/Assets/Editor/SnapshotMenu.cs +++ b/workers/unity/Assets/Editor/SnapshotMenu.cs @@ -18,11 +18,10 @@ private static void GenerateSnapshotProgrammatically() { var snapshotEntities = new Dictionary(); var currentEntityId = 0; - int numFish = 0; //Return the number of Fish to be spawned, so that Goal knows about it, and get stored as a component - numFish = FishEntityTemplate.PopulateSnapshotWithFishEntities( ref snapshotEntities, ref currentEntityId); - SwarmGoalEntityTemplate.PopulateSnapshotWithSwarmGoalEntities( ref snapshotEntities, ref currentEntityId, numFish); + FishEntityTemplate.PopulateSnapshotWithFishEntities( ref snapshotEntities, ref currentEntityId); + SwarmGoalEntityTemplate.PopulateSnapshotWithSwarmGoalEntities( ref snapshotEntities, ref currentEntityId); SaveSnapshot(snapshotEntities); } diff --git a/workers/unity/Assets/EntityPrefabs/Goal.prefab b/workers/unity/Assets/EntityPrefabs/Goal.prefab index e322b10..c0dfeb6 100644 Binary files a/workers/unity/Assets/EntityPrefabs/Goal.prefab and b/workers/unity/Assets/EntityPrefabs/Goal.prefab differ diff --git a/workers/unity/Assets/EntityTemplates/FishEntityTemplate.cs b/workers/unity/Assets/EntityTemplates/FishEntityTemplate.cs index 7bfcca1..8deb7b0 100644 --- a/workers/unity/Assets/EntityTemplates/FishEntityTemplate.cs +++ b/workers/unity/Assets/EntityTemplates/FishEntityTemplate.cs @@ -13,21 +13,23 @@ namespace Assets.EntityTemplates { public class FishEntityTemplate : MonoBehaviour { - private static int numFish = 10; - private static float spawnDiameter = 10.0f; //TODO: Have to find a way to connect this to global variable, tankSize - private static float initialSpeed = 3.0f; //TODO: Have to find a way to connect this to global variable, initialSpeed + private static UInt32 numFish = 100; + private static float initialSpeed = 3.0f; + private static float tankSize = 50.0f; // Template definition for a Fish entity public static SnapshotEntity GenerateFishSnapshotEntityTemplate() { //Spawn to a random position - Coordinates fishInitialCoordinates = new Coordinates (Random.Range (-spawnDiameter, spawnDiameter), - Random.Range (-spawnDiameter, spawnDiameter), - Random.Range (-spawnDiameter, spawnDiameter)); + Coordinates fishInitialCoordinates = new Coordinates (Random.Range (-tankSize, tankSize), + Random.Range (-tankSize, tankSize), + Random.Range (-tankSize, tankSize)); Vector3f fishInitialRotation = new Vector3f (Random.Range (-30, 30), Random.Range (-30, 30), Random.value * 360); //roll, pitch, yaw + float speed = Random.Range (initialSpeed / 2.0f, initialSpeed); + //float fishInitialSpeed = Random.Range (initialSpeed / 2.0f, initialSpeed); // Set name of Unity prefab associated with this entity @@ -36,8 +38,8 @@ public static SnapshotEntity GenerateFishSnapshotEntityTemplate() // Define components attached to snapshot entity - FishEntity.Add(new WorldTransform.Data(new WorldTransformData(fishInitialCoordinates, fishInitialRotation, initialSpeed))); - + FishEntity.Add(new WorldTransform.Data(new WorldTransformData(fishInitialCoordinates, fishInitialRotation, speed))); + FishEntity.Add (new FishParameters.Data (new FishParametersData (numFish, initialSpeed, tankSize))); // Grant UnityWorker (server-side) workers write-access over all of this entity's components, read-access for visual (e.g. client) workers //var acl = Acl.GenerateServerAuthoritativeAcl (FishEntity); //Does not currently work @@ -45,7 +47,8 @@ public static SnapshotEntity GenerateFishSnapshotEntityTemplate() //Alastair's recommendation: var acl = Acl.Build() .SetReadAccess(CommonRequirementSets.PhysicsOrVisual) - .SetWriteAccess(CommonRequirementSets.PhysicsOnly); + .SetWriteAccess(CommonRequirementSets.PhysicsOnly) + .SetWriteAccess(CommonRequirementSets.PhysicsOnly); FishEntity.SetAcl(acl); @@ -54,13 +57,11 @@ public static SnapshotEntity GenerateFishSnapshotEntityTemplate() //This function is *not* autogenerated, but can be called anything; it is called in SnapshotMenu.cs - public static int PopulateSnapshotWithFishEntities(ref Dictionary snapshotEntities, ref int nextAvailableId) + public static void PopulateSnapshotWithFishEntities(ref Dictionary snapshotEntities, ref int nextAvailableId) { for (var i = 0; i < numFish; i++) snapshotEntities.Add (new EntityId (nextAvailableId++), GenerateFishSnapshotEntityTemplate ()); - return numFish; - } diff --git a/workers/unity/Assets/EntityTemplates/SwarmGoalEntityTemplate.cs b/workers/unity/Assets/EntityTemplates/SwarmGoalEntityTemplate.cs index a7dbc1c..753e056 100644 --- a/workers/unity/Assets/EntityTemplates/SwarmGoalEntityTemplate.cs +++ b/workers/unity/Assets/EntityTemplates/SwarmGoalEntityTemplate.cs @@ -13,12 +13,11 @@ namespace Assets.EntityTemplates { public class SwarmGoalEntityTemplate : MonoBehaviour { - private static float spawnDiameter = 10.0f; //TODO: Have to find a way to connect this to global variable, tankSize + private static float spawnDiameter = 50.0f; //TODO: Have to find a way to connect this to global variable, tankSize private static float goalSpeed = 1.0f; - private static UInt32 numFish; // Template definition for a Swarm Goal entity - public static SnapshotEntity GenerateGoalSnapshotEntityTemplate(int F) + public static SnapshotEntity GenerateGoalSnapshotEntityTemplate() { //Spawn to a random position Coordinates goalInitialCoordinates = new Coordinates (Random.Range (-spawnDiameter, spawnDiameter), @@ -27,16 +26,14 @@ public static SnapshotEntity GenerateGoalSnapshotEntityTemplate(int F) Vector3f zero = new Vector3f (); - numFish = (UInt32) F; - + // Set name of Unity prefab associated with this entity - //var SwarmGoalEntity = new SnapshotEntity { Prefab = "ExampleEntity" }; - var SwarmGoalEntity = new SnapshotEntity { Prefab = "Goal" }; + var SwarmGoalEntity = new SnapshotEntity { Prefab = "Goal" }; // Define components attached to snapshot entity SwarmGoalEntity.Add(new WorldTransform.Data(new WorldTransformData(goalInitialCoordinates, zero, 0.0f))); - SwarmGoalEntity.Add (new GoalParameters.Data (new GoalParametersData (spawnDiameter, goalSpeed, numFish, 1.0f))); + SwarmGoalEntity.Add (new GoalParameters.Data (new GoalParametersData (spawnDiameter, goalSpeed))); //Alastair's recommendation: var acl = Acl.Build() @@ -50,9 +47,9 @@ public static SnapshotEntity GenerateGoalSnapshotEntityTemplate(int F) //This function is *not* autogenerated, but can be called anything; it is called in SnapshotMenu.cs - public static void PopulateSnapshotWithSwarmGoalEntities(ref Dictionary snapshotEntities, ref int nextAvailableId, int numFish) + public static void PopulateSnapshotWithSwarmGoalEntities(ref Dictionary snapshotEntities, ref int nextAvailableId) { - snapshotEntities.Add (new EntityId (nextAvailableId++), GenerateGoalSnapshotEntityTemplate (numFish)); + snapshotEntities.Add (new EntityId (nextAvailableId++), GenerateGoalSnapshotEntityTemplate ()); } diff --git a/workers/unity/Assets/Gamelogic/Fish/Behaviors/FishController.cs b/workers/unity/Assets/Gamelogic/Fish/Behaviors/FishController.cs index 109e2d8..7f93ff1 100644 --- a/workers/unity/Assets/Gamelogic/Fish/Behaviors/FishController.cs +++ b/workers/unity/Assets/Gamelogic/Fish/Behaviors/FishController.cs @@ -28,8 +28,8 @@ public class FishController : MonoBehaviour * which has write-access for its WorldTransform component. */ [Require] private WorldTransform.Writer WorldTransformWriter; + [Require] private FishParameters.Reader FishParametersReader; - public float initialSpeed = 3.0f; public float maxSpeed = 3.5f; public float angularSpeed = 10.0f; public double neighborDistance = 5.0; // The max distance to its closest neighbor, within which it will display swarming behavior @@ -41,59 +41,34 @@ public class FishController : MonoBehaviour //From Goal Parameters private GameObject goalObj; - private EntityId goalId; + private EntityId goalEntity; private float numFish; private float tankSize; public void OnEnable() { transform.position = WorldTransformWriter.Data.position.ToVector3 (); - speed = initialSpeed; - } - - - void Start() - { - - //Pick up the Goal Entity - var query = Query.HasComponent().ReturnOnlyEntityIds(); - - SpatialOS.Commands.SendQuery (WorldTransformWriter, query, result => { - if (result.StatusCode != StatusCode.Success) { - Debug.LogError ("Goal Query failed with error: " + result.ErrorMessage); - return; - } - - - if (result.Response.Count < 1) { - Debug.LogError ("Goal NOT found!"); - return; //No goal - } - - - Map resultMapG = result.Response.Value.Entities; - goalId = resultMapG.First.Value.Key; - - if (SpatialOS.Universe.ContainsEntity (goalId)) { - goalObj = SpatialOS.Universe.Get(goalId).UnderlyingGameObject; // this works also - numFish = SpatialOS.GetLocalEntityComponent(goalId).Get().Value.numfish; - tankSize = SpatialOS.GetLocalEntityComponent(goalId).Get().Value.tanksize; - - Debug.Log ("Goal Found @" + goalObj.transform.position + " with ID: " + goalId.Id + "And Num Fish: " + numFish +" in tank of size" + tankSize); + speed = WorldTransformWriter.Data.speed; + numFish = FishParametersReader.Data.numfish; + tankSize = FishParametersReader.Data.tanksize; - - } else { - Debug.LogError ("Goal NOT found!"); - return; - } - }); + Debug.Log("Fish Startup Params: speed:" + speed + ", NumFish: " + numFish + ", Tank Size: " +tankSize ); } - public void Update() { + //Assign the goalObj : originally done in start, but lots of random 'assigned to null reference' errprs propped up + goalEntity = new EntityId ((long)numFish); //Since goal is created after all the fish, the entityID of the goal = numFish + goalObj = SpatialOS.Universe.Get(goalEntity).UnderlyingGameObject; + if (goalObj == null) { + + Debug.LogError ("Goal not found by this fish!! Abort!!"); + return; + } + + Debug.Log ("Goal found at pos (" + goalObj.transform.position + ")"); + //Check if it's too far from center - //float distanceFromCenter = Vector3.Distance(this.transform.position, Vector3.zero); if( (transform.position.x >= tankSize) || (transform.position.y >= tankSize) || (transform.position.z >= tankSize)) ApplyReturn (); else { @@ -157,12 +132,7 @@ private void ApplySwarmMechanics() if (idRef.Id == numFish) //i.e. == goal continue; - //Entity SwarmGoalEntity = item.Value; - - //Debug.Log("Looking for key in loop#" + groupSize ); - //if(SpatialOS.Universe.ContainsEntity(item.Key)) //From Improbable.Core.Entity.SpatialOS.Universe - //{ - + //GameObject otherFish = SpatialOS.Universe.Get(idRef).UnderlyingGameObject; // this works also Vector3 otherFishPos = SpatialOS.GetLocalEntityComponent(idRef).Get().Value.position.ToVector3(); float otherSpeed = SpatialOS.GetLocalEntityComponent(idRef).Get().Value.speed; @@ -176,23 +146,23 @@ private void ApplySwarmMechanics() groupSpeed += otherSpeed; groupSize++; - //} - } - - //Debug.Log ("Group Size1: " + groupSize); - - - //Debug.Log ("Group Size2: " + groupSize); + } + if (groupSize > 0) { //EntityId id = new EntityId (1003); + if(goalObj == null) + { + Debug.Log("Goal OBJ missing!"); + return; + } goalPos = goalObj.transform.position; vCenter = (vCenter / groupSize) + (goalPos - this.transform.position); - //speed = groupSpeed/groupSize; + speed = groupSpeed/groupSize; Debug.Log("Goal Pos : (" + goalPos.x + "," + goalPos.y + "," + goalPos.z + ")" + " Center ("+ vCenter.x + "," + vCenter.y + "," + vCenter.z + ")" + " GroupSize: " + groupSize + " Speed: " + speed); @@ -233,7 +203,7 @@ private void ApplyReturn() //reset speed: //speed = Random.Range (startingSpeed/2.0f, startingSpeed); - speed = Mathf.Lerp (speed, initialSpeed, Time.deltaTime); + speed = Mathf.Lerp (speed, FishParametersReader.Data.initialspeed, Time.deltaTime); } diff --git a/workers/unity/Assets/Gamelogic/Goal/Behaviors/GoalController.cs b/workers/unity/Assets/Gamelogic/Goal/Behaviors/GoalController.cs index a14b5fb..b4af9c6 100644 --- a/workers/unity/Assets/Gamelogic/Goal/Behaviors/GoalController.cs +++ b/workers/unity/Assets/Gamelogic/Goal/Behaviors/GoalController.cs @@ -25,7 +25,7 @@ public class GoalController : MonoBehaviour { private Vector3 goalPos, newGoalPos = Vector3.zero; private float tankSize, goalSpeed; - private float getAwayRadius = 0.1f; + private double getAwayRadius = 0.1; private bool getAway; @@ -37,7 +37,7 @@ public class GoalController : MonoBehaviour { tankSize = GoalParametersReader.Data.tanksize; goalSpeed = GoalParametersReader.Data.goalspeed; - + Debug.Log ("Goal Startup params: tankSize: " + tankSize + ", Goal Speed:" + goalSpeed); } @@ -58,7 +58,7 @@ void Update () } - if ((result.Response.Count > 0) && (Random.Range (0, 50) < 1)) + if ((result.Response.Count > 0) && (Random.Range (0, 200) < 1)) { //Debug.Log("Found " + result.Response.Count + " fish. Goal needs to escape!!"); getAway = true;