private void GenerateCBodiesAsteroids(int nCBodiesAsteroidClusters, GameObject centreCBodyStar) { //Properties float minimumDistanceBetweenClusters = 100f; float distanceOut = 1300f - minimumDistanceBetweenClusters; float randSpacing; float spawnRadius; float spawnAngle; int clusterSize; byte clusterType; //Spawn all for (int i = 0; i < nCBodiesAsteroidClusters; i++) { //Instance cBody randSpacing = Random.Range(0f, 600f) + Mathf.Pow(Random.Range(0f, 15f), 2f); spawnRadius = distanceOut + minimumDistanceBetweenClusters + randSpacing; distanceOut = spawnRadius; //increment distanceOut for the next cBody spawnAngle = Random.Range(0f, 360f); clusterSize = Control.LowBiasedRandomIntSquared(4); //range of 1 to 16 (4^2 = 16) //We don't have to add 1 here to format for Random.Range max being exclusive for ints because the length is already 1 greater than the index (since index starts at 0) clusterType = (byte)Random.Range(0, Ore.typeLength); for (int clusterI = 0; clusterI < clusterSize; clusterI++) { GameObject instanceCBodyAsteroid = Instantiate( cBodyAsteroid, new Vector3( Mathf.Cos(spawnAngle) * spawnRadius, 0f, Mathf.Sin(spawnAngle) * spawnRadius ), Quaternion.Euler( Random.Range(0f, 360f), Random.Range(0f, 360f), Random.Range(0f, 360f) ) ); //Put in CBodies tree instanceCBodyAsteroid.transform.parent = cBodiesAsteroids.transform; //Spread out within cluster instanceCBodyAsteroid.transform.position += 2f * new Vector3(Random.value, Random.value, Random.value); Gravity instanceCBodyGravityScript = instanceCBodyAsteroid.GetComponent <Gravity>(); //Orbit central star instanceCBodyGravityScript.SetVelocityToOrbit(centreCBodyStar, spawnAngle); CBodyAsteroid instanceCBodyAsteroidScript = instanceCBodyAsteroid.GetComponent <CBodyAsteroid>(); //Randomize size and type instanceCBodyAsteroidScript.SetSize(CBodyAsteroid.GetRandomSize()); //MUST SET SIZE FIRST SO THAT MODEL IS SELECTED instanceCBodyAsteroidScript.SetType(clusterType); //Give control reference instanceCBodyAsteroidScript.control = control; instanceCBodyGravityScript.control = control; } } }
private void DealExplosionDamageAndForce() { //Check for colliders in the area Collider[] collidersInRadius = Physics.OverlapSphere(transform.position, EXPLOSION_RADIUS); foreach (Collider collider in collidersInRadius) { //Don't bother raycasting unless the collider in the area is an asteroid if (StringIsAnAsteroidModel(collider.gameObject.name)) { //Cast a ray to make sure the asteroid is in LOS LayerMask someLayerMask = -1; Vector3 rayDirection = (collider.transform.position - transform.position).normalized; float rayDistanceMax = (collider.transform.position - transform.position).magnitude; if (Physics.Raycast(transform.position, rayDirection, out RaycastHit hit, rayDistanceMax, someLayerMask, QueryTriggerInteraction.Ignore)) { //Debug.LogFormat("{0}", hit.collider.name); //We need to be ignoring triggers? //Make sure the ray is hitting an asteroid (something else could be in the way blocking LOS) that is within range float distanceBetweenHitAndEpicentre = (transform.position - hit.point).magnitude; //Debug.Log(hit.transform.name); if (distanceBetweenHitAndEpicentre < EXPLOSION_RADIUS && hit.transform.name == control.generation.cBodyAsteroid.name + "(Clone)") { CBodyAsteroid asteroidScript = hit.transform.GetComponent <CBodyAsteroid>(); //Don't bother with already destroyed asteroids if (!asteroidScript.destroyed) { //THIS RUNS FOUR TIMES BECAUSE IT IS HITTING THE TRIGGER COLLIDERS //Explosion push force //collider.GetComponent<Rigidbody>().AddExplosionForce(EXPLOSION_STRENGTH, transform.position, EXPLOSION_RADIUS); Vector3 directionFromEpicentreToHit = (hit.point - transform.position).normalized; Vector3 finalForceVector = directionFromEpicentreToHit * EXPLOSION_PUSH_STRENGTH * (1f - (distanceBetweenHitAndEpicentre / EXPLOSION_RADIUS)); //Debug.Log(finalForceVector.magnitude); //Model Object -> Model Size Folder -> All Models Folder -> Complete Asteroid //collider.transform.parent.parent.parent.GetComponent<Rigidbody>().AddForce(finalForceVector); //hit.transform.GetComponent<Rigidbody>().AddForce(finalForceVector); //Explosion damage Vector3 directionHitFrom = (transform.position - hit.point).normalized; asteroidScript.Damage(2, directionHitFrom, hit.point); } } } } } }
private void UpdateCollisionDetection() { /* * Unity's collision detection system is great for some things, * But for weapon projectiles it often doesn't do a good enough job at detecting them * So we use this custom method instead * * Here we use raycasting to check the space in front of the projectile for collidables * The distance we check ahead increases with the projectile's speed to prevent phasing * * We also have to be careful to ignore the trigger colliders since those are used for the waypoint and target system * * In the raycast, we cast out from the transform.right direction since the model is rotated */ float minimumRaycastDistance = 20f; //this value must be high enough that the projectile does not phase through objects directly in front of the player float raycastDistance = minimumRaycastDistance * rb.velocity.magnitude * Time.deltaTime; //Debug.Log(raycastDistance); //Debug.DrawRay(transform.position, transform.right * raycastDistance, Color.red); //if (Physics.Raycast(transform.position, transform.right, out RaycastHit hit, raycastDistance)) LayerMask someLayerMask = -1; if (Physics.Raycast(transform.position, transform.right, out RaycastHit hit, raycastDistance, someLayerMask, QueryTriggerInteraction.Ignore)) { //Debug.Log("Laser hit object: " + hit.transform.name); if (hit.transform.name == "CBodyAsteroid(Clone)") { CBodyAsteroid asteroidScript = hit.transform.GetComponent <CBodyAsteroid>(); //Break apart asteroid if (!asteroidScript.destroyed) { Vector3 direction = (transform.position - hit.point).normalized; asteroidScript.Damage(1, direction, hit.point); //Reset tooltip certainty control.ui.tipAimCertainty = 0f; } } //Deactivate self DeactivateSelf(); } }
public GameObject SpawnAsteroidManually(Vector3 position, Vector3 velocity, string size, byte type, byte health) //bool randomType) { GameObject instanceCBodyAsteroid = Instantiate( cBodyAsteroid, position, Quaternion.Euler( Random.Range(0f, 360f), Random.Range(0f, 360f), Random.Range(0f, 360f) ) ); CBodyAsteroid instanceCBodyAsteroidScript = instanceCBodyAsteroid.GetComponent <CBodyAsteroid>(); //Put in CBodies tree instanceCBodyAsteroid.transform.parent = cBodiesAsteroids.transform; //Give control reference instanceCBodyAsteroidScript.control = control; instanceCBodyAsteroid.GetComponent <Gravity>().control = control; //Set velocity instanceCBodyAsteroid.GetComponent <Rigidbody>().velocity = velocity; //Randomize size and type instanceCBodyAsteroidScript.SetSize(size); //instanceCBodyAsteroidScript.SetSize(instanceCBodyAsteroidScript.RandomSize()); //MUST SET SIZE FIRST SO THAT MODEL IS SELECTED //Type instanceCBodyAsteroidScript.SetType(type); /* * if (randomType) * { * instanceCBodyAsteroidScript.SetType((byte)Random.Range(0, Ore.typeLength)); * } * else * { * instanceCBodyAsteroidScript.SetType(0); * } */ //Health instanceCBodyAsteroidScript.health = health; return(instanceCBodyAsteroid); }
private void SpawnAsteroid(string size) { //Instantiate at parent position, plus some randomness GameObject instanceCBodyAsteroid = Instantiate( control.generation.cBodyAsteroid, transform.position + (1.2f * new Vector3(Random.value, Random.value, Random.value)), Quaternion.Euler( Random.Range(0f, 360f), Random.Range(0f, 360f), Random.Range(0f, 360f) ) ); //Put in CBodies tree instanceCBodyAsteroid.transform.parent = control.generation.cBodiesAsteroids.transform; //Pass control reference instanceCBodyAsteroid.GetComponent <Gravity>().control = control; //Rigidbody Rigidbody instanceCBodyAsteroidRb = instanceCBodyAsteroid.GetComponent <Rigidbody>(); //Ignore all collisions unless explicitly enabled (once asteroid is separated from siblings) instanceCBodyAsteroidRb.detectCollisions = false; //Copy velocity and add some random impulse force instanceCBodyAsteroidRb.velocity = rb.velocity; instanceCBodyAsteroidRb.angularVelocity = rb.angularVelocity; instanceCBodyAsteroidRb.inertiaTensor = rb.inertiaTensor; instanceCBodyAsteroidRb.inertiaTensorRotation = rb.inertiaTensorRotation; instanceCBodyAsteroidRb.AddForce(25f * new Vector3( 0.5f + (0.5f * Random.value), 0.5f + (0.5f * Random.value), 0.5f + (0.5f * Random.value) )); instanceCBodyAsteroidRb.AddTorque(100f * new Vector3( Random.value, Random.value, Random.value )); //Script CBodyAsteroid instanceCBodyAsteroidScript = instanceCBodyAsteroid.GetComponent <CBodyAsteroid>(); instanceCBodyAsteroidScript.control = control; instanceCBodyAsteroidScript.SetSize(size); instanceCBodyAsteroidScript.SetType(type); }
public void DisableSelfAndPlanDestroy() { //Emit particles GetComponent <ParticlesDamageRock>().EmitDamageParticles(7, Vector3.zero, transform.position, true); //Disable self GetComponent <SphereCollider>().enabled = false; //Disable waypoint trigger rb.detectCollisions = false; model.SetActive(false); transform.Find("Map Model").gameObject.SetActive(false); //Disable Station if (hasStation) { Destroy(instancedStation, 0f); } //Gravitate toward centre star only (so that the lack of the hitbox doesn't cause it to accelerate to infinity) GetComponent <Gravity>().gravitateTowardCentreStarOnly = true; //Spawn regular asteroids byte type = CBodyAsteroid.GetRandomType(); for (int i = 0; i < 7; i++) { //Spawn GameObject asteroid = control.generation.SpawnAsteroidManually( transform.position, rb.velocity, CBodyAsteroid.GetRandomSize(), type, CBodyAsteroid.HEALTH_MAX ); //Spread out asteroid.transform.position += 16f * new Vector3(Random.value, Random.value, Random.value); } //Play sound GetComponent <AudioSource>().Play(); //Remember is disabled disabled = true; }
private void Start() { //Check for colliders in the area Collider[] collidersInRadius = Physics.OverlapSphere(transform.position, EXPLOSION_RADIUS); foreach (Collider collider in collidersInRadius) { //Don't bother raycasting unless the collider in the area is an asteroid if (collider.gameObject.name == control.generation.cBodyAsteroid.name + "(Clone)") { //Cast a ray to make sure the asteroid is in LOS LayerMask someLayerMask = -1; Vector3 rayDirection = (collider.transform.position - transform.position).normalized; float rayDistanceMax = (collider.transform.position - transform.position).magnitude; if (Physics.Raycast(transform.position, rayDirection, out RaycastHit hit, rayDistanceMax, someLayerMask, QueryTriggerInteraction.Ignore)) { //Make sure the ray is hitting an asteroid (something else could be in the way blocking LOS) if (hit.transform.name == "CBodyAsteroid(Clone)") { CBodyAsteroid asteroidScript = hit.transform.GetComponent <CBodyAsteroid>(); //Don't bother with already destroyed asteroids if (!asteroidScript.destroyed) { //Explosion push force collider.GetComponent <Rigidbody>().AddExplosionForce(EXPLOSION_STRENGTH, transform.position, EXPLOSION_RADIUS); //Explosion damage Vector3 directionHitFrom = (transform.position - hit.point).normalized; asteroidScript.Damage(1, directionHitFrom, hit.point); } } } } } //Destroy self quickly after being created Destroy(gameObject, 2f); }
private void Update() { //DEBUG //--------------------------------------------------- //Free money if (binds.GetInputDown(binds.bindCheat1)) { currency += 1000; control.ui.UpdateAllPlayerResourcesUI(); control.ui.SetTip("Show me the money."); } //Add ore water /* * if (binds.GetInputDown(binds.bindThrustVectorDecrease)) * { * ore[ORE_WATER] += 1.0; * control.ui.UpdateAllPlayerResourcesUI(); * } */ //Teleport forward /* * if (binds.GetInputDown(binds.bindThrustVectorIncrease)) * { * transform.position += transform.forward * 1e4f; * Debug.Log("Teleported forward: distance to star " + (control.generation.instanceCentreStar.transform.position - transform.position).magnitude); * } */ //Spawn if (binds.GetInputDown(binds.bindCheat2)) { control.generation.SpawnAsteroidManually( transform.position + transform.forward * 3f, rb.velocity, CBodyAsteroid.GetRandomSize(), CBodyAsteroid.GetRandomType(), CBodyAsteroid.HEALTH_MAX ); control.ui.SetTip("Spawned one asteroid."); upgradeLevels[control.commerce.UPGRADE_SEISMIC_CHARGES] = 1; control.ui.SetTip("Seismic charges unlocked."); } /* * if (binds.GetInputDown(binds.bindThrustVectorDecrease)) * { * control.SpawnPlanetoidManually(transform.position + transform.forward * 20f, rb.velocity, null); * Debug.Log("Spawned one planetoid"); * } */ //Slow motion /* * if (binds.GetInput(binds.bindPrimaryFire)) * { * Time.timeScale = 0.01f; * } * else if (!Menu.menuOpenAndGamePaused) * { * Time.timeScale = 1f; * } */ //--------------------------------------------------- //Slow update if (Time.frameCount % 3 == 0) { SlowUpdate(); } //Have the position mount follow the player position positionMount.transform.position = transform.position; //Setup the camera if (!fovSet) { SetCameraSettings(); } //AUDIO UpdateAudio(); //Don't run if paused if (!Menu.menuOpenAndGamePaused) { UpdateGetIfMoving(); //Check if moving at all so that it only has to be checked once per update UpdatePlayerWeapons(); //Shoot stuff UpdatePlayerEngineEffect(); //Set engine glow relative to movement //Fuel decrement if (canAndIsMoving) { vitalsFuel = Math.Max(0.0, vitalsFuel - ((vitalsFuelConsumptionRate / (1 + upgradeLevels[control.commerce.UPGRADE_FUEL_EFFICIENCY])) * Time.deltaTime)); } //Fuel increment (in-situ refinery) bool missingEnoughFuel = vitalsFuel < vitalsFuelMax - REFINERY_FUEL_OUT_RATE; bool hasUpgrade = upgradeLevels[control.commerce.UPGRADE_IN_SITU_FUEL_REFINERY] >= 1; bool hasEnoughOre = ore[ORE_WATER] > REFINERY_ORE_WATER_IN_RATE; bool enoughTimeHasPassed = Time.time > refineryTimeAtLastRefine + REFINERY_TIME_BETWEEN_REFINES; if (missingEnoughFuel && hasUpgrade && hasEnoughOre && enoughTimeHasPassed && control.settings.refine) { ore[ORE_WATER] -= REFINERY_ORE_WATER_IN_RATE; vitalsFuel += REFINERY_FUEL_OUT_RATE; control.ui.UpdatePlayerOreWaterText(); refineryTimeAtLastRefine = Time.time; } //Warn on loop if out of fuel if (vitalsFuel <= 0d && warningUIFlashTime <= 0f) { FlashWarning("Fuel reserves empty"); //Loop smoothly and indefinitely warningUIFlashTime = warningUIFlashTotalDuration * 100f; } //Without this it would be possible for the out of fuel warning to flash indefinitely if you ran out of fuel right as you entered a station if (vitalsFuel > 0d && warningUIText.text == "Fuel reserves empty") { warningUIFlashTime = 0f; warningUIFlashPosition = 1f; } //Update map player ship position transform.parent.Find("Ship Map Model").position = transform.position; /* * transform.parent.Find("Ship Map Model").position.Set( * transform.position.x, * 1000f, * transform.position.z * ); */ } }