Beispiel #1
0
    // Update is called once per frame
    void Update()
    {
        if (target == null)
        {
            Debug.LogWarning("this laser has no target");
            return;
        }

        // Read gradient for laser intensity
        float time           = (Time.time % patternDuration) / patternDuration;
        float laserIntensity = pattern.getAlpha(time);

        // Override linerenderer alpha keys
        for (int i = 0; i < tempAlphaKeys.Length; i++)
        {
            tempAlphaKeys[i].alpha = laserIntensity;
        }
        tempGradient.SetKeys(tempGradient.colorKeys, tempAlphaKeys);
        lineRenderer.colorGradient = tempGradient;

        // Combine masks
        LayerMask collisionMask = waterSurfaceMask | obstacleMask;

        Vector2 thisPos        = transform.position;
        Vector2 targetPos      = target.position;
        Vector2 directionDelta = targetPos - thisPos;
        Vector2 direction      = directionDelta.normalized;

        // Raycast distance
        float laserDistanceCast = directionDelta.magnitude;

        // Test water & terrain
        bool    hitWater          = false;
        Vector2 waterCollisionPos = Vector3.zero;
        bool    hitObstacle       = false;
        Vector2 obstaclePos       = Vector3.zero;
        int     waterSurfaceLayer = waterSurfaceMask.LayerMaskToLayer();

        RaycastHit2D[] hits = Physics2D.RaycastAll(thisPos, direction, laserDistanceCast, collisionMask);
        foreach (RaycastHit2D hit in hits)
        {
            // Extend through water surface
            if (hit.collider.gameObject.layer == waterSurfaceLayer)
            {
                hitWater                  = true;
                prevTouchedWater          = true;
                waterCollisionPos         = hit.point;
                lastDetectedWaterCollider = hit.collider;
                lastDetectedWaterY        = waterCollisionPos.y;
            }
            // Terrain or body, stop extending
            else
            {
                hitObstacle = true;
                obstaclePos = hit.point;

                // Reduce health if has health
                Health targetHealth = hit.collider.GetComponent <Health>();
                if (targetHealth != null)
                {
                    float damage = laserDamage * laserIntensity * Time.deltaTime;
                    if (damage > 0.0f)
                    {
                        targetHealth.damage(damage);
                    }
                }

                break;
            }
        }

        // Laser end point
        Vector2 laserEndPos = Vector2.zero;

        if (hitObstacle)
        {
            laserEndPos = obstaclePos;
        }
        else
        {
            laserEndPos = thisPos + direction * laserDistanceCast;
        }

        // Set line renderer
        lineRenderer.SetPosition(0, Vector2.zero);
        lineRenderer.SetPosition(1, laserEndPos - thisPos);

        // Evaluate if laser shoots into water or out of water
        // or completely submerged pr completely above water
        if (!hitWater)
        {
            // Never touched water OR previously touched water surface went below
            if ((!prevTouchedWater && lastDetectedWaterCollider == null) || (lastDetectedWaterCollider != null && thisPos.y >= lastDetectedWaterCollider.transform.position.y))
            {
                state = aquaMode.aboveWater;
            }
            else
            {
                state = aquaMode.belowWater;
            }
        }
        else
        {
            if (direction.y < 0.0f)
            {
                state = aquaMode.intoWater;
            }
            else
            {
                state = aquaMode.outtaWater;
            }
        }

        // Emit bubbles from submerged laser segment
        if (state != aquaMode.aboveWater && laserIntensity > 0.0f)
        {
            laserParticle.keepOn();
        }
        else
        {
            laserParticle.keepOff();
        }
        Vector2 waterBubbleStartPos = Vector2.zero;
        Vector2 waterBubbleEndPos   = Vector2.zero;

        switch (state)
        {
        case aquaMode.aboveWater:

            break;

        case aquaMode.belowWater:
            waterBubbleStartPos = thisPos;
            waterBubbleEndPos   = laserEndPos;
            break;

        case aquaMode.intoWater:
            waterBubbleStartPos = waterCollisionPos;
            waterBubbleEndPos   = laserEndPos;
            break;

        case aquaMode.outtaWater:
            waterBubbleStartPos = thisPos;
            waterBubbleEndPos   = waterCollisionPos;
            break;
        }
        ParticleSystem.ShapeModule laserParticleShape = laserParticle.shape;
        float directionAngle = Mathf.Atan2(direction.y, direction.x) * 180.0f / 3.14f;

        laserParticleShape.rotation = Vector3.forward * directionAngle;
        laserParticleShape.radius   = Vector2.Distance(waterBubbleStartPos, waterBubbleEndPos) / 2.0f;
        laserParticleShape.position = (waterBubbleStartPos + waterBubbleEndPos) / 2.0f - thisPos;
    }