Ejemplo n.º 1
0
    public void UpdateDrone()
    {
        if (ShouldSleep())
        {
            lightObject.shadows = LightShadows.None;
            if (motor_alive)
            {
                distance_sleep = true;
                GetComponent <Rigidbody>().Sleep();
            }
            if (audiosource_motor.isPlaying)
            {
                audiosource_motor.Stop();
            }
            return;
        }
        else
        {
            if (lightObject.intensity > 0.0f)
            {
                lightObject.shadows = LightShadows.Hard;
            }
            else
            {
                lightObject.shadows = LightShadows.None;
            }
            if (motor_alive && distance_sleep)
            {
                GetComponent <Rigidbody>().WakeUp();
                distance_sleep = false;
            }
            if (!audiosource_motor.isPlaying)
            {
                audiosource_motor.volume = Preferences.sound_volume;
                audiosource_motor.Play();
            }

            if (level_creator != null)
            {
                int new_tile_position = level_creator.GetTilePosition(transform.position);
                if (tile_parent_position != new_tile_position)
                {
                    tile_parent_position = new_tile_position;
                    transform.parent     = level_creator.GetPositionTileEnemiesParent(transform.position);
                }
            }
        }

        if (audiosource_taser.isPlaying && (!barrel_alive || ai_state != AIState.FIRING))  // Turn off taser if we no longer fire
        {
            audiosource_taser.Stop();
        }

        Vector3 rel_pos = target_pos - transform.position;

        if (motor_alive)
        {
            float   kFlyDeadZone = 0.2f;
            float   kFlySpeed    = 10.0f;
            Vector3 target_vel   = (target_pos - transform.position) / kFlyDeadZone;
            if (target_vel.magnitude > 1.0f)
            {
                target_vel = target_vel.normalized;
            }
            target_vel *= kFlySpeed;
            Vector3 target_accel = (target_vel - GetComponent <Rigidbody>().velocity);
            if (ai_state == AIState.IDLE)
            {
                target_accel *= 0.1f;
            }
            target_accel.y += 9.81f;

            rotor_speed = target_accel.magnitude;
            rotor_speed = Mathf.Clamp(rotor_speed, 0.0f, 14.0f);

            Vector3    up         = transform.rotation * new Vector3(0.0f, 1.0f, 0.0f);
            Quaternion correction = Quaternion.identity;
            correction.SetFromToRotation(up, target_accel.normalized);
            Vector3 correction_vec   = Vector3.zero;
            float   correction_angle = 0.0f;
            correction.ToAngleAxis(out correction_angle, out correction_vec);
            tilt_correction  = correction_vec * correction_angle;
            tilt_correction -= GetComponent <Rigidbody>().angularVelocity;


            Vector3 x_axis = transform.rotation * new Vector3(1.0f, 0.0f, 0.0f);
            Vector3 y_axis = transform.rotation * new Vector3(0.0f, 1.0f, 0.0f);
            Vector3 z_axis = transform.rotation * new Vector3(0.0f, 0.0f, 1.0f);
            if (ai_state != AIState.IDLE)
            {
                Vector3 y_plane_pos = (new Vector3(Vector3.Dot(rel_pos, z_axis), 0.0f, -Vector3.Dot(rel_pos, x_axis))).normalized;
                float   target_y    = Mathf.Atan2(y_plane_pos.x, y_plane_pos.z) / Mathf.PI * 180 - 90;
                while (target_y > 180)
                {
                    target_y -= 360.0f;
                }
                while (target_y < -180)
                {
                    target_y += 360.0f;
                }
                tilt_correction += y_axis * target_y;
                tilt_correction *= 5.0f;
            }
            else
            {
                tilt_correction += y_axis;
            }

            if (ai_state == AIState.IDLE)
            {
                tilt_correction *= 0.1f;
            }

            if (GetComponent <Rigidbody>().velocity.magnitude < 0.2f)
            {
                stuck_delay += Time.deltaTime;
                if (stuck_delay > 1.0f)
                {
                    target_pos  = transform.position + new Vector3(UnityEngine.Random.Range(-1.0f, 1.0f), UnityEngine.Random.Range(-1.0f, 1.0f), UnityEngine.Random.Range(-1.0f, 1.0f));
                    stuck_delay = 0.0f;
                }
            }
            else
            {
                stuck_delay = 0.0f;
            }
        }
        else
        {
            rotor_speed = Mathf.Max(0.0f, rotor_speed - Time.deltaTime * 5.0f);
            GetComponent <Rigidbody>().angularDrag = 0.05f;
        }

        top_rotor_rotation    += rotor_speed * Time.deltaTime * 1000.0f;
        bottom_rotor_rotation -= rotor_speed * Time.deltaTime * 1000.0f;
        if (rotor_speed * Time.timeScale > 7.0f)
        {
            bottom_rotor.gameObject.GetComponent <Renderer>().enabled = false;
            top_rotor.gameObject.GetComponent <Renderer>().enabled    = false;
        }
        else
        {
            bottom_rotor.gameObject.GetComponent <Renderer>().enabled = true;
            top_rotor.gameObject.GetComponent <Renderer>().enabled    = true;
        }
        var tmp_cs1 = bottom_rotor.localEulerAngles;

        tmp_cs1.y = bottom_rotor_rotation;
        bottom_rotor.localEulerAngles = tmp_cs1;
        var tmp_cs2 = top_rotor.localEulerAngles;

        tmp_cs2.y = top_rotor_rotation;
        top_rotor.localEulerAngles = tmp_cs2;

        //rigidbody.velocity += transform.rotation * Vector3(0,1,0) * rotor_speed * Time.deltaTime;
        RaycastHit hit = new RaycastHit();

        if (camera_alive)
        {
            if (ai_state == AIState.IDLE)
            {
                switch (camera_pivot_state)
                {
                case CameraPivotState.DOWN:
                    camera_pivot_angle += Time.deltaTime * 25.0f;
                    if (camera_pivot_angle > 50)
                    {
                        camera_pivot_angle = 50.0f;
                        camera_pivot_state = CameraPivotState.WAIT_UP;
                        camera_pivot_delay = 0.2f;
                    }
                    break;

                case CameraPivotState.UP:
                    camera_pivot_angle -= Time.deltaTime * 25.0f;
                    if (camera_pivot_angle < 0)
                    {
                        camera_pivot_angle = 0.0f;
                        camera_pivot_state = CameraPivotState.WAIT_DOWN;
                        camera_pivot_delay = 0.2f;
                    }
                    break;

                case CameraPivotState.WAIT_DOWN:
                    camera_pivot_delay -= Time.deltaTime;
                    if (camera_pivot_delay < 0)
                    {
                        camera_pivot_state = CameraPivotState.DOWN;
                    }
                    break;

                case CameraPivotState.WAIT_UP:
                    camera_pivot_delay -= Time.deltaTime;
                    if (camera_pivot_delay < 0)
                    {
                        camera_pivot_state = CameraPivotState.UP;
                    }
                    break;
                }
            }
            else
            {
                camera_pivot_angle -= Time.deltaTime * 25.0f;
                if (camera_pivot_angle < 0)
                {
                    camera_pivot_angle = 0.0f;
                }
            }

            // Target interactions
            var target = GetTarget();
            if (target != null)
            {
                // Taser
                if (barrel_alive && ai_state == AIState.FIRING)
                {
                    if (!audiosource_taser.isPlaying)
                    {
                        audiosource_taser.volume = Preferences.sound_volume;
                        audiosource_taser.Play();
                    }
                    else
                    {
                        audiosource_taser.volume = Preferences.sound_volume;
                    }
                    if (gun_delay <= 0.0f)
                    {
                        gun_delay = 0.1f;
                        Instantiate(muzzle_flash, point_spark.position, RandomOrientation());
                        if (Vector3.Distance(point_spark.position, target.position + targetoffsetpos) < 1)
                        {
                            target.GetComponent <AimScript>().Shock();
                        }
                    }
                }
                gun_delay = Mathf.Max(0.0f, gun_delay - Time.deltaTime);

                // Danger state
                var tmp_cs3 = camera_pivot.localEulerAngles;
                tmp_cs3.x = camera_pivot_angle;
                camera_pivot.localEulerAngles = tmp_cs3;
                float dist   = Vector3.Distance(target.position + targetoffsetpos, transform.position);
                float danger = Mathf.Max(0.0f, 1.0f - dist / kMaxRange);
                if (danger > 0.0f)
                {
                    danger = Mathf.Min(0.2f, danger);
                }
                if (ai_state == AIState.AIMING || ai_state == AIState.FIRING)
                {
                    danger = 1.0f;
                }
                if (ai_state == AIState.ALERT || ai_state == AIState.ALERT_COOLDOWN)
                {
                    danger += 0.5f;
                }
                target.GetComponent <MusicScript>().AddDangerLevel(danger);

                // Target finding
                rel_pos = (target.position + targetoffsetpos) - drone_camera.position;
                bool sees_target = false;
                if (dist < kMaxRange && Vector3.Dot(drone_camera.rotation * new Vector3(0.0f, -1.0f, 0.0f), rel_pos.normalized) > 0.7f)
                {
                    hit = new RaycastHit();
                    if (!Physics.Linecast(drone_camera.position, target.position + targetoffsetpos, out hit, 1 << 0))
                    {
                        sees_target = true;
                    }
                }

                // Attacking
                if (sees_target)
                {
                    Vector3 new_target = (target.position + targetoffsetpos) + target.GetComponent <AimScript>().GetVelocity() *
                                         Mathf.Clamp(Vector3.Distance(target.position + targetoffsetpos, transform.position) * 0.1f, 0.5f, 1.0f);
                    switch (ai_state)
                    {
                    case AIState.IDLE:
                        ai_state    = AIState.ALERT;
                        alert_delay = kAlertDelay;
                        audiosource_effect.PlayOneShot(sound_alert, 0.3f * Preferences.sound_volume);
                        break;

                    case AIState.AIMING:
                        target_pos = new_target;
                        if (Vector3.Distance(transform.position, target_pos) < 4)
                        {
                            ai_state = AIState.FIRING;
                        }
                        target_pos.y += 1.0f;
                        break;

                    case AIState.FIRING:
                        target_pos = new_target;
                        if (Vector3.Distance(transform.position, target_pos) > 4)
                        {
                            ai_state = AIState.AIMING;
                        }
                        break;

                    case AIState.ALERT:
                        alert_delay  -= Time.deltaTime;
                        target_pos    = new_target;
                        target_pos.y += 1.0f;
                        if (alert_delay <= 0.0f)
                        {
                            ai_state = AIState.AIMING;
                        }
                        break;

                    case AIState.ALERT_COOLDOWN:
                        ai_state    = AIState.ALERT;
                        alert_delay = kAlertDelay;
                        break;
                    }
                }
                else
                {
                    switch (ai_state)
                    {
                    case AIState.AIMING:
                    case AIState.FIRING:
                    case AIState.ALERT:
                        ai_state             = AIState.ALERT_COOLDOWN;
                        alert_cooldown_delay = kAlertCooldownDelay;
                        break;

                    case AIState.ALERT_COOLDOWN:
                        alert_cooldown_delay -= Time.deltaTime;
                        if (alert_cooldown_delay <= 0.0f)
                        {
                            ai_state = AIState.IDLE;
                            audiosource_effect.PlayOneShot(sound_unalert, 0.3f * Preferences.sound_volume);
                        }
                        break;
                    }
                }
            }
            switch (ai_state)
            {
            case AIState.IDLE:
                lightObject.color = new Color(0.0f, 0.0f, 1.0f);
                break;

            case AIState.AIMING:
                lightObject.color = new Color(1.0f, 0.0f, 0.0f);
                break;

            case AIState.ALERT:
            case AIState.ALERT_COOLDOWN:
                lightObject.color = new Color(1.0f, 1.0f, 0.0f);
                break;
            }
        }
        if (!camera_alive)
        {
            lightObject.intensity *= Mathf.Pow(0.01f, Time.deltaTime);
        }
        lensFlareObject.color      = lightObject.color;
        lensFlareObject.brightness = lightObject.intensity;
        float target_pitch = rotor_speed * 0.2f;

        target_pitch             = Mathf.Clamp(target_pitch, 0.2f, 3.0f);
        audiosource_motor.pitch  = Mathf.Lerp(audiosource_motor.pitch, target_pitch, Mathf.Pow(0.0001f, Time.deltaTime));
        audiosource_motor.volume = rotor_speed * 0.1f * Preferences.sound_volume;

        audiosource_motor.volume -= Vector3.Distance(Camera.main.transform.position, transform.position) * 0.0125f * Preferences.sound_volume;

        bool line_of_sight = true;

        if (Physics.Linecast(transform.position, Camera.main.transform.position, out hit, 1 << 0))
        {
            line_of_sight = false;
        }
        if (line_of_sight)
        {
            sound_line_of_sight += Time.deltaTime * 3.0f;
        }
        else
        {
            sound_line_of_sight -= Time.deltaTime * 3.0f;
        }
        sound_line_of_sight = (float)Mathf.Clamp((int)sound_line_of_sight, 0, 1);

        audiosource_motor.volume *= 0.5f + sound_line_of_sight * 0.5f;
        object_audiosource_motor.GetComponent <AudioLowPassFilter>().cutoffFrequency =
            Mathf.Lerp(5000.0f, 44000.0f, sound_line_of_sight);
    }