public void Update() { if (!hit_something) { life_time += Time.deltaTime; if (life_time > 1.5f) { hit_something = true; } velocity -= velocity * velocityFalloff * Time.deltaTime; Vector3 old_pos = transform.position; transform.position += velocity * Time.deltaTime; velocity += Physics.gravity * Time.deltaTime; RaycastHit hit = new RaycastHit(); if (Physics.Linecast(old_pos, transform.position, out hit, 1 << 0 | 1 << 9 | 1 << 11)) { GameObject hit_obj = hit.collider.gameObject; GameObject hit_transform_obj = hit.transform.gameObject; Rigidbody hit_rigidbody = hit.collider.attachedRigidbody; ShootableLight light_script = RecursiveHasScript(hit_obj, typeof(ShootableLight), 1) as ShootableLight; AimScript aim_script = RecursiveHasScript(hit_obj, typeof(AimScript), 1) as AimScript; RobotScript turret_script = RecursiveHasScript(hit_obj, typeof(RobotScript), 3) as RobotScript; transform.position = hit.point; float ricochet_amount = Vector3.Dot(velocity.normalized, hit.normal) * -1.0f; if (UnityEngine.Random.Range(0.0f, 1.0f) > ricochet_amount && Vector3.Magnitude(velocity) * (1.0 - ricochet_amount) > 10.0) { var ricochet = Instantiate(bullet_obj, hit.point, transform.rotation); var ricochet_vel = velocity * 0.3f * (1.0f - ricochet_amount); velocity -= ricochet_vel; ricochet_vel = Vector3.Reflect(ricochet_vel, hit.normal); ricochet.GetComponent <BulletScript>().SetVelocity(ricochet_vel); PlaySoundFromGroup(sound_hit_ricochet, hostile ? 1.0f : 0.6f); } else if (turret_script && velocity.magnitude > 100.0f) { RaycastHit new_hit; if (Physics.Linecast(hit.point + velocity.normalized * 0.001f, hit.point + velocity.normalized, out new_hit, 1 << 11 | 1 << 12)) { if (new_hit.collider.gameObject.layer == 12) { turret_script.WasShotInternal(new_hit.collider.gameObject); } } } if (turret_script && turret_script.GetComponent <Rigidbody>()) { turret_script.GetComponent <Rigidbody>().AddForceAtPosition(velocity * 0.01f, hit.point, ForceMode.Impulse); } else if (hit_rigidbody) { hit_rigidbody.AddForceAtPosition(velocity * 0.01f, hit.point, ForceMode.Impulse); } bool broke_glass = false; if (light_script) { broke_glass = light_script.WasShot(hit_obj, hit.point, velocity); if (hit.collider.material.name == "glass (Instance)") { PlaySoundFromGroup(sound_glass_break, 1.0f); } } if (Vector3.Magnitude(velocity) > 50) { GameObject hole = null; GameObject effect; if (turret_script) { PlaySoundFromGroup(sound_hit_metal, hostile ? 1.0f : 0.8f); hole = Instantiate(metal_bullet_hole_obj, hit.point, RandomOrientation()); effect = Instantiate(spark_effect, hit.point, RandomOrientation()); turret_script.WasShot(hit_obj, hit.point, velocity, damageMultiplier); } else if (aim_script) { hole = Instantiate(bullet_hole_obj, hit.point, RandomOrientation()); effect = Instantiate(puff_effect, hit.point, RandomOrientation()); PlaySoundFromGroup(sound_hit_body, 1.0f); aim_script.WasShot(); } else if (hit.collider.material.name.Contains("metal")) { PlaySoundFromGroup(sound_hit_metal, hostile ? 1.0f : 0.4f); hole = Instantiate(metal_bullet_hole_decal_obj, hit.point, Quaternion.FromToRotation(new Vector3(0, 0, -1), hit.normal) * Quaternion.AngleAxis(UnityEngine.Random.Range(0, 360), new Vector3(0, 0, 1))); effect = Instantiate(spark_effect, hit.point, RandomOrientation()); } else if (hit.collider.material.name.Contains("glass")) { PlaySoundFromGroup(sound_hit_glass, hostile ? 1.0f : 0.4f); if (!broke_glass) // Don't make bullet hole if glass is no longer there { hole = Instantiate(glass_bullet_hole_obj, hit.point, RandomOrientation()); } effect = Instantiate(spark_effect, hit.point, RandomOrientation()); } else { PlaySoundFromGroup(sound_hit_concrete, hostile ? 1.0f : 0.4f); hole = Instantiate(bullet_hole_decal_obj, hit.point, Quaternion.FromToRotation(new Vector3(0, 0, -1), hit.normal) * Quaternion.AngleAxis(UnityEngine.Random.Range(0, 360), new Vector3(0, 0, 1))); effect = Instantiate(puff_effect, hit.point, RandomOrientation()); } effect.transform.position += hit.normal * 0.05f; if (hole != null) { if (aim_script) { hole.transform.parent = aim_script.main_camera.transform; } else if (turret_script) { hole.transform.parent = turret_script.transform; turret_script.AttachHole(hole.transform, hit.transform); } else if (hit_rigidbody) { hole.transform.parent = hit.collider.transform; } else if (level_creator != null) { hole.transform.parent = level_creator.GetPositionTileDecalsParent(hole.transform.position); } } } hit_something = true; } line_renderer.positionCount = segment + 1; line_renderer.SetPosition(segment, transform.position); ++segment; } else { life_time += Time.deltaTime; death_time += Time.deltaTime; //Destroy(this.gameObject); } for (int i = 0; i < segment; ++i) { Color start_color = new Color(1.0f, 1.0f, 1.0f, (1.0f - life_time * 5.0f) * 0.05f); Color end_color = new Color(1.0f, 1.0f, 1.0f, (1.0f - death_time * 5.0f) * 0.05f); line_renderer.startColor = start_color; line_renderer.endColor = end_color; if (death_time > 1.0f) { Destroy(this.gameObject); } } }
void OnCollisionEnter(Collision col) { GameObject other = col.gameObject; ContactPoint contact = col.GetContact(0); Vector3 velocity = col.relativeVelocity; if (!own_colliders.Contains(contact.thisCollider)) { return; } #if UNITY_EDITOR if (log_collision_data) { Debug.Log($"COLLISION @ vel: {velocity.magnitude} ({this.gameObject.name} -> {other.name})"); } #endif ShootableLight light_script = RecursiveHasScript(other, typeof(ShootableLight), 1) as ShootableLight; AimScript aim_script = RecursiveHasScript(other, typeof(AimScript), 1) as AimScript; RobotScript robot_script = RecursiveHasScript(other, typeof(RobotScript), 3) as RobotScript; Rigidbody rigidbody = RecursiveHasScript(other, typeof(Rigidbody), 3) as Rigidbody; if (rigidbody) { rigidbody.AddForceAtPosition(velocity * 0.01f, contact.point, ForceMode.Impulse); } if (velocity.magnitude > lethal_speed) { bool broke_glass = false; if (light_script) { broke_glass = light_script.WasShot(other, contact.point, velocity); if (col.collider.material.name.Contains("glass")) { PlaySoundFromGroup(sound_glass_break, 1.0f); } } GameObject hole = null; GameObject effect; if (robot_script) { PlaySoundFromGroup(sound_hit_metal, 0.8f); hole = TryInstantiate(metal_bullet_hole_obj, contact.point, RandomOrientation()); effect = TryInstantiate(spark_effect, contact.point, RandomOrientation()); robot_script.WasShot(other, contact.point, velocity, damageMultiplier); } else if (aim_script) { hole = TryInstantiate(bullet_hole_obj, contact.point, RandomOrientation()); effect = TryInstantiate(puff_effect, contact.point, RandomOrientation()); PlaySoundFromGroup(sound_hit_body, 1.0f); aim_script.WasShot(); } else if (col.collider.material.name.Contains("metal")) { PlaySoundFromGroup(sound_hit_metal, 0.4f); hole = TryInstantiate(metal_bullet_hole_obj, contact.point, Quaternion.FromToRotation(new Vector3(0, 0, -1), contact.normal) * Quaternion.AngleAxis(UnityEngine.Random.Range(0, 360), new Vector3(0, 0, 1))); effect = TryInstantiate(spark_effect, contact.point, RandomOrientation()); } else if (col.collider.material.name.Contains("glass")) { PlaySoundFromGroup(sound_hit_glass, 0.4f); if (!broke_glass) // Don't make bullet hole if glass is no longer there { hole = TryInstantiate(glass_bullet_hole_obj, contact.point, RandomOrientation()); } effect = TryInstantiate(spark_effect, contact.point, RandomOrientation()); } else { PlaySoundFromGroup(sound_hit_concrete, 0.4f); hole = TryInstantiate(bullet_hole_obj, contact.point, Quaternion.FromToRotation(new Vector3(0, 0, -1), contact.normal) * Quaternion.AngleAxis(UnityEngine.Random.Range(0, 360), new Vector3(0, 0, 1))); effect = TryInstantiate(puff_effect, contact.point, RandomOrientation()); } // Offset effect if (effect) { effect.transform.position += contact.normal * 0.05f; } // Attach hole if (hole) { if (aim_script) { hole.transform.parent = aim_script.main_camera.transform; } else if (robot_script) { hole.transform.parent = robot_script.transform; robot_script.AttachHole(hole.transform, col.transform); } else if (rigidbody) { hole.transform.parent = col.transform; } else if (level_creator) { hole.transform.parent = level_creator.GetPositionTileDecalsParent(hole.transform.position); } } } if (velocity.magnitude > lethal_speed || other.layer != LayerMask.NameToLayer("Character")) { if (attach_on_hit) { if (aim_script) { transform.parent = aim_script.main_camera.transform; } else if (robot_script) { transform.parent = robot_script.transform; robot_script.AttachHole(transform, col.transform); } else if (level_creator) { transform.parent = level_creator.GetPositionTileDecalsParent(transform.position); } else { transform.parent = col.transform; } } on_collision.Invoke(); } }