Esempio n. 1
0
    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);
            }
        }
    }
Esempio n. 2
0
    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();
        }
    }