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(); } }
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); }