public static bool GetBelowGroundSpawnPoint(ref SpawnPoint spawnPoint, SpawnerStateSetting setting, Location spawnLocation, WIGroup spawnGroup) { bool succeeded = false; spawnPoint = new SpawnPoint(); switch (setting.Method) { case SpawnerPlacementMethod.SherePoint: //cast a ray from the center of the location outwards Vector3 starget = (UnityEngine.Random.onUnitSphere * spawnLocation.worlditem.ActiveRadius) + spawnLocation.worlditem.tr.position; Vector3 sscale = Vector3.one; RaycastHit hit; if (Physics.Linecast(spawnLocation.worlditem.tr.position, starget, out hit, Globals.LayersTerrain)) { spawnPoint.Transform.Position = spawnLocation.worlditem.tr.InverseTransformPoint(hit.point); spawnPoint.Transform.Rotation = Quaternion.FromToRotation(Vector3.up, hit.normal).eulerAngles; //random forward vector, normal up vector spawnPoint.Transform.Scale = sscale; switch (hit.collider.gameObject.layer) { case Globals.LayerNumFluidTerrain: spawnPoint.HitWater = true; break; case Globals.LayerNumSolidTerrain: default: spawnPoint.HitTerrainMesh = true; break; } succeeded = true; } break; case SpawnerPlacementMethod.TopDown: default: //get a random point in sphere scaled to the location's radius mTerrainHit.groundedHeight = spawnLocation.worlditem.ActiveRadius; mRandomSphere = UnityEngine.Random.onUnitSphere * mTerrainHit.groundedHeight; mRandomSphere.y = 0f; mTerrainHit.feetPosition = mRandomSphere + spawnLocation.worlditem.tr.position; //get the terrain height in world space, then store it in local space //WorldChunk chunk = spawnLocation.worlditem.Group.GetParentChunk (); mTerrainHit.feetPosition.y = GameWorld.Get.TerrainHeightAtInGamePosition(ref mTerrainHit); spawnPoint.Transform.Position = spawnLocation.worlditem.tr.InverseTransformPoint(mTerrainHit.feetPosition); spawnPoint.Transform.Rotation = Quaternion.LookRotation(SVector3.Random(-1f, 1f), mTerrainHit.normal).eulerAngles; spawnPoint.Transform.Scale = Vector3.one; spawnPoint.HitWater = mTerrainHit.hitWater; spawnPoint.HitTerrainMesh = mTerrainHit.hitTerrainMesh; if (!mTerrainHit.isGrounded) { Debug.Log("TERRAIN HIT WAS NOT GROUNDED"); } succeeded = true; break; } return(succeeded); }
public static bool GetAboveGroundSpawnPoint(ref SpawnPoint spawnPoint, SpawnerStateSetting setting, Location spawnLocation, WIGroup spawnGroup) { bool succeeded = false; spawnPoint = new SpawnPoint(); switch (setting.Method) { case SpawnerPlacementMethod.SherePoint: //cast a ray from the center of the location outwards Vector3 starget = (UnityEngine.Random.onUnitSphere * spawnLocation.worlditem.ActiveRadius) + spawnLocation.worlditem.tr.position; Vector3 sscale = Vector3.one; RaycastHit hit; if (Physics.Linecast(spawnLocation.worlditem.tr.position, starget, out hit, Globals.LayersTerrain)) { spawnPoint.Transform.Position = spawnLocation.worlditem.tr.InverseTransformPoint(hit.point); spawnPoint.Transform.Rotation = Quaternion.FromToRotation(Vector3.up, hit.normal).eulerAngles; //random forward vector, normal up vector spawnPoint.Transform.Scale = sscale; switch (hit.collider.gameObject.layer) { case Globals.LayerNumFluidTerrain: spawnPoint.HitWater = true; break; case Globals.LayerNumSolidTerrain: default: spawnPoint.HitTerrainMesh = true; break; } succeeded = true; } break; case SpawnerPlacementMethod.SpawnPoint: STransform manualPoint = null; if (!setting.NextManualSpawnPoint(out manualPoint)) { //whoops, we're out return(false); } //no need to do any searching spawnPoint.Transform.CopyFrom(manualPoint); spawnPoint.HitWater = false; spawnPoint.HitTerrainMesh = false; succeeded = true; break; case SpawnerPlacementMethod.TopDown: default: //get a random point in sphere scaled to the location's radius mTerrainHit.groundedHeight = spawnLocation.worlditem.ActiveRadius; mTerrainHit.feetPosition = (UnityEngine.Random.insideUnitSphere * mTerrainHit.groundedHeight) + spawnLocation.worlditem.tr.position; mTerrainHit.feetPosition.y = GameWorld.Get.TerrainHeightAtInGamePosition(ref mTerrainHit); if (mTerrainHit.hitTerrain || mTerrainHit.hitTerrainMesh || (setting.SpawnOnStructureMeshes && mTerrainHit.hitStructureMesh)) { spawnPoint.Transform.Position = spawnLocation.worlditem.tr.InverseTransformPoint(mTerrainHit.feetPosition); spawnPoint.Transform.Rotation = Quaternion.LookRotation(SVector3.Random(-1f, 1f), mTerrainHit.normal).eulerAngles; spawnPoint.Transform.Scale = Vector3.one; spawnPoint.HitWater = mTerrainHit.hitWater; spawnPoint.HitTerrainMesh = mTerrainHit.hitTerrainMesh; succeeded = true; } else { Debug.Log("SPAWNER " + spawnLocation.name + ": Failed because either didn't hit terrain (" + mTerrainHit.hitTerrain.ToString() + ") or didn't hit terrain mesh (" + mTerrainHit.hitTerrainMesh.ToString() + ") or can't spawn on structures (" + mTerrainHit.hitStructureMesh.ToString()); succeeded = false; } break; } return(succeeded); }