예제 #1
0
    // Update is called every frame
    public new void Update()
    {
        base.Update();
        time += Time.deltaTime;
        // Speed deterioration, destroy without any behavior if expires
        if (deterioration * time >= 0.9)
        {
            time = 0;
            ObjectPoolManager.SharedInstance.ReturnPooledObject(gameObject.name, gameObject);
        }
        if (curSpeed > 0)
        {
            rb.velocity = curSpeed * (1f - deterioration * time) * rb.transform.up;
        }
        else
        {
            rb.velocity = new Vector2(0, 0);
        }

        // Effect calls
        if (time >= selfDestructTime && selfDestructTime > 0)
        {
            FragShell fs   = gameObject.GetComponent <FragShell>();
            Explosion expl = gameObject.GetComponent <Explosion>();

            // Frag shell effect
            if (fs != null)
            {
                fs.Fracture();
            }

            // Explosion effect
            if (expl != null)
            {
                expl.Detonate();
            }

            // Generate hit effect (assuming explosion)
            if (hitEffect != null)
            {
                ParticleSystem curHitEffect = Instantiate(hitEffect, this.transform.position, Quaternion.identity) as ParticleSystem;
                var            main         = curHitEffect.main;
                main.simulationSpeed = main.duration / hitEffectDuration;
                float scale = hitEffectRadius / baseExplosionRadius;
                curHitEffect.transform.localScale = new Vector3(scale, scale, scale);
                curHitEffect.Play(true);
            }

            // Return shell to object pool
            time = 0;
            ObjectPoolManager.SharedInstance.ReturnPooledObject(gameObject.name, gameObject);
        }
    }
예제 #2
0
    // Collision behavior
    public void OnCollisionEnter2D(Collision2D collision)
    {
        // Check if the collision was with a viable target
        foreach (string targetTag in targetTags)
        {
            if (collision.collider.tag == targetTag)
            {
                //TODO add hit effect
                Destructible e = collision.collider.GetComponent <Destructible>();

                // Hit behavior (allow first frame tolerance so bullet doesn't collide with shooter upon spawn)
                if (e != null && time > 0)
                {
                    // Effect calls
                    FragShell fs   = gameObject.GetComponent <FragShell>();
                    Explosion expl = gameObject.GetComponent <Explosion>();

                    // Calculate effective defense [Effective defense = defense / cos(angle of contact)]
                    RaycastHit2D hit      = Physics2D.Raycast(transform.position, transform.up, 5);
                    Vector3      normal   = hit.normal;
                    float        penCoeff = Mathf.Abs(Vector3.Cross(rb.velocity.normalized, normal).z);
                    // Debug penCoeff for "bullet traps"
                    if (penCoeff < 0.2f)
                    {
                        penCoeff = 1f - penCoeff;
                    }
                    if (float.IsNaN(penCoeff) || float.IsInfinity(penCoeff))
                    {
                        penCoeff = 1f;
                    }
                    float effectiveDefense = e.defense / penCoeff;

                    // Calculate effective damage [Damage = power * (1- det*time)^2 - Max (effective defense - penetration, 0)]
                    float damage = curPower * Mathf.Pow(1f - deterioration * time, 2f) - Mathf.Max(effectiveDefense - penetration, 0);
                    e.TakeDamage(damage);

                    // Determine penetration status
                    if (damage > 0)
                    {
                        // Frag shell effect
                        if (fs != null)
                        {
                            fs.Fracture();
                        }

                        // Explosion effect
                        if (expl != null)
                        {
                            expl.Detonate();
                        }

                        // Generate hit effect (assuming explosion)
                        if (hitEffect != null)
                        {
                            ParticleSystem curHitEffect = Instantiate(hitEffect, this.transform.position, Quaternion.identity) as ParticleSystem;
                            var            main         = curHitEffect.main;
                            main.simulationSpeed = main.duration / hitEffectDuration;
                            float scale = hitEffectRadius / baseExplosionRadius;
                            curHitEffect.transform.localScale = new Vector3(scale, scale, scale);
                            curHitEffect.Play(true);
                        }
                        // Return shell to object pool
                        time = 0;
                        ObjectPoolManager.SharedInstance.ReturnPooledObject(gameObject.name, gameObject);
                    }
                    // Non-penetration, reflect with energy loss.
                    else
                    {
                        time = time + (1f / deterioration - time) * penCoeff; // HAX
                        // Check to make sure velocity can be assigned (THIS IS SOLELY TO HOLD OFF VELOCITY BUG)
                        if (curSpeed > 0)
                        {
                            rb.velocity = Vector3.Reflect(curSpeed * (1f - deterioration * time) * rb.velocity.normalized, normal); //Need to fix as a error is causing NaN
                        }
                        else
                        {
                            rb.velocity = new Vector2(0, 0);
                        }
                        //Store new direction
                        Vector3 newDirection = Vector3.Reflect(transform.up, normal);
                        //Rotate bullet to new direction
                        newDirection = Quaternion.Euler(0, 0, -90) * newDirection;
                        Quaternion targetRotation = Quaternion.LookRotation(forward: Vector3.forward, upwards: newDirection);
                        transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, 100000);
                        break;
                    }
                }
            }
        }
    }