//Events for when the projectile collides with objects in the world with appropriate layers #region Collision Response Methods private void OnHitObject(RaycastHit a_hit, bool a_hitEntity) { IDamagable damagableObject = a_hit.collider.GetComponent <IDamagable>(); if (damagableObject != null) { damagableObject.TakeImpact(m_damage, a_hit, this); } if (m_targetInvincible) { if (m_entityInvincibleParticle != null) { GameObject GO = Instantiate(m_entityInvincibleParticle, a_hit.point, transform.rotation); Destroy(GO, m_entityInvincibleParticleTimer); } if (m_entityInvincibleAudioClip != null && m_spawnedSpeaker != null) { SpawnedSpeaker SS = Instantiate(m_spawnedSpeaker, a_hit.point, transform.rotation) as SpawnedSpeaker; SS.AudioSource.clip = m_entityInvincibleAudioClip; SS.AudioSource.Play(); } if (m_destroy == false) { m_destroy = true; return; } Destroy(gameObject); if (m_trailRenderer != null) { Destroy(m_instancedTrailRenderer, m_trailRendererLifeTime); } return; } m_insideEntity = a_hitEntity; if (m_insideEntity) { return; } if (m_destroy == false) { m_destroy = true; return; } Destroy(gameObject); if (m_trailRenderer != null) { Destroy(m_instancedTrailRenderer, m_trailRendererLifeTime); } }
//Create the trail renderer and check for initial collisions private void Start() { m_insideEntity = false; //Merge all layers into a new layer set for checking with a ray m_hittableCollisionMask = m_ricochetCollisionMask | m_entityCollisionMask | m_environmentCollisionMask; for (int i = 0; i < m_environmentCollisionMasks.Count; i++) { m_hittableCollisionMask = m_hittableCollisionMask | m_environmentCollisionMasks[i]; } #region one layer at a time /* * //If the projectile spawns within a collider, it will activate the appropriate collision response * Collider[] initialEnemyCollision = Physics.OverlapSphere(transform.position, .1f, m_entityCollisionMask); * if (initialEnemyCollision.Length > 0) { * OnHitObject(initialEnemyCollision[0], true); * return; * } * * Collider[] initialEnvironmentCollision = Physics.OverlapSphere(transform.position, .1f, m_environmentCollisionMask); * if (initialEnvironmentCollision.Length > 0) { * OnHitObject(initialEnvironmentCollision[0], false); * return; * } * * Collider[] initialRicochetCollision = Physics.OverlapSphere(transform.position, .1f, m_ricochetCollisionMask); * if (initialRicochetCollision.Length > 0) { * OnHitObject(initialRicochetCollision[0], false); * return; * } * /* */ #endregion #region multilayer //If the projectile spawns within a collider, it will activate the appropriate collision response Collider[] initialCollision = Physics.OverlapSphere(transform.position, .1f, m_hittableCollisionMask); if (initialCollision.Length > 0) { LayerMask hitLayer = (1 << initialCollision[0].transform.gameObject.layer); if (hitLayer == m_ricochetCollisionMask) { if (m_ricochetParticle != null) { GameObject GO = Instantiate(m_ricochetParticle, transform.position, transform.rotation); Destroy(GO, m_ricochetParticleTimer); } if (m_ricochetAudioClip != null && m_spawnedSpeaker != null) { SpawnedSpeaker SS = Instantiate(m_spawnedSpeaker, transform.position, transform.rotation) as SpawnedSpeaker; SS.AudioSource.clip = m_ricochetAudioClip; SS.AudioSource.Play(); } m_destroy = false; OnHitObject(initialCollision[0], false); } else if (hitLayer == m_entityCollisionMask) { if (m_insideEntity == false) { OnHitObject(initialCollision[0], true); m_currentlyInside = initialCollision[0].transform.gameObject; } } else if (hitLayer == m_environmentCollisionMask) { OnHitObject(initialCollision[0], false); } else { for (int i = 0; i < m_environmentCollisionMasks.Count; i++) { if (hitLayer == m_environmentCollisionMasks[i]) { if (m_environmentParticles[i] != null) { //Gross horrible way of seperating a specific layer change Quaternion goRot = transform.rotation; if (i != 1) { GameObject GO = Instantiate(m_environmentParticles[i], transform.position, Quaternion.LookRotation(-transform.forward)); Destroy(GO, m_environmentParticleTimers[i]); } //Cactus grossness else { GameObject GO = Instantiate(m_environmentParticles[i], transform.position, goRot); Destroy(GO, m_environmentParticleTimers[i]); } } if (m_environmentAudioClips[i] != null) { SpawnedSpeaker audio = Instantiate(m_spawnedSpeaker, transform.position, transform.rotation) as SpawnedSpeaker; audio.AudioSource.clip = m_environmentAudioClips[i]; audio.AudioSource.Play(); } if (i == 1) { m_destroy = false; } OnHitObject(initialCollision[0], false); } } } } /* */ #endregion if (m_trailRenderer != null) { m_instancedTrailRenderer = Instantiate(m_trailRenderer, transform.position, transform.rotation) as GameObject; } Quaternion rot = Quaternion.Euler(0f, transform.rotation.eulerAngles.y, 0f); transform.rotation = rot; }
//Use ray casts to check for collisions #region Collision Detection and First Response Methods private void CheckCollisions(float a_distanceToMove) { Ray ray = new Ray(transform.position, transform.forward); RaycastHit hit; #region Multilayered layer detection //Casts a ray checking all they layers it could potentially hit and then reacting accoridingly if (Physics.Raycast(ray, out hit, a_distanceToMove + m_skinWidth, m_hittableCollisionMask)) { //Stores the raycasthit's layer for checking what what hit LayerMask hitLayer = (1 << hit.transform.gameObject.layer); if (hitLayer == m_ricochetCollisionMask) { if (m_ricochetParticle != null) { GameObject GO = Instantiate(m_ricochetParticle, hit.point, transform.rotation); Destroy(GO, m_ricochetParticleTimer); } if (m_ricochetAudioClip != null && m_spawnedSpeaker != null) { SpawnedSpeaker SS = Instantiate(m_spawnedSpeaker, hit.point, hit.transform.rotation) as SpawnedSpeaker; SS.AudioSource.clip = m_ricochetAudioClip; SS.AudioSource.Play(); } m_destroy = false; OnHitObject(hit, this, false); } else if (hitLayer == m_entityCollisionMask) { if (m_insideEntity == false) { OnHitObject(hit, true); m_currentlyInside = hit.transform.gameObject; } } else if (hitLayer == m_environmentCollisionMask) { OnHitObject(hit, false); } //Checking the list of extra environmental collisions which will have their own effect else { for (int i = 0; i < m_environmentCollisionMasks.Count; i++) { if (hitLayer == m_environmentCollisionMasks[i]) { if (m_environmentParticles[i] != null) { //Gross horrible way of seperating a specific layer change Quaternion goRot = transform.rotation; if (i != 1) { GameObject GO = Instantiate(m_environmentParticles[i], hit.point, Quaternion.LookRotation(-transform.forward)); Destroy(GO, m_environmentParticleTimers[i]); } //Cactus grossness else { GameObject GO = Instantiate(m_environmentParticles[i], hit.point, goRot); Destroy(GO, m_environmentParticleTimers[i]); m_destroy = false; } } if (m_environmentAudioClips[i] != null) { SpawnedSpeaker audio = Instantiate(m_spawnedSpeaker, hit.point, transform.rotation) as SpawnedSpeaker; audio.AudioSource.clip = m_environmentAudioClips[i]; audio.AudioSource.Play(); } OnHitObject(hit, false); } } } } /* */ #endregion #region Original collision detection /* * //The case where the projectile hits a ricochet object * if (Physics.Raycast(ray, out hit, a_distanceToMove + m_skinWidth, m_ricochetCollisionMask)) { * //if (hit.transform.gameObject.layer == m_ricochetCollisionMask) { * if (m_ricochetParticle != null) { * GameObject GO = Instantiate(m_ricochetParticle, hit.point, transform.rotation); * Destroy(GO, m_ricochetParticleTimer); * } * * if (m_ricochetAudioClip != null && m_spawnedSpeaker != null) { * SpawnedSpeaker SS = Instantiate(m_spawnedSpeaker, transform) as SpawnedSpeaker; * SS.AudioSource.clip = m_ricochetAudioClip; * SS.AudioSource.Play(); * } * OnHitObject(hit, this, false); * //} * } * * //The case where the projectile hits an entity * if (m_insideEntity == false) { * if (Physics.Raycast(ray, out hit, a_distanceToMove + m_skinWidth, m_entityCollisionMask)) { * //if (hit.transform.gameObject.layer == m_entityCollisionMask) { * OnHitObject(hit, true); * m_currentlyInside = hit.transform.gameObject; * //} * } * } * * * //Checking for the case where the projectile hits an environment object with custom effects * if (Physics.Raycast(ray, out hit, a_distanceToMove + m_skinWidth, m_environmentCollisionMask)) * OnHitObject(hit, false); * * for (int i = 0; i < m_environmentCollisionMasks.Count; i++) { * if (Physics.Raycast(ray, out hit, a_distanceToMove + m_skinWidth, m_environmentCollisionMasks[i])) { * * //if (hit.transform.gameObject.layer == m_environmentCollisionMasks[i]) { * //Gross horrible way of seperating a specific layer change * if (m_environmentParticles[i] != null) { * Quaternion goRot = transform.rotation; * if (i != 1) { * GameObject GO = Instantiate(m_environmentParticles[i], hit.point, Quaternion.LookRotation(-transform.forward)); * Destroy(GO, m_environmentParticleTimers[i]); * } * //Cactus grossness * else { * GameObject GO = Instantiate(m_environmentParticles[i], hit.point, goRot); * Destroy(GO, m_environmentParticleTimers[i]); * m_destroy = false; * } * } * * if (m_environmentAudioClips[i] != null) { * SpawnedSpeaker audio = Instantiate(m_spawnedSpeaker, hit.point, transform.rotation) as SpawnedSpeaker; * audio.AudioSource.clip = m_environmentAudioClips[i]; * audio.AudioSource.Play(); * } * OnHitObject(hit, false); * //} * } * } * /* */ #endregion }