Пример #1
0
    IEnumerator shootZRootCoroutine(Vector3 originPosition, Vector3 direction)
    {
        zRootObject.gameObject.SetActive(true);

        float distance = 0;

        currentAngle = 0;
        bool isHit = false;
        ZRootInteractableObject interactable = null;
        Vector3 hitPos = originPosition + direction * zRootMaximumDistance;

        shakeOffset = new Vector2(Random.Range(0f, 10f), Random.Range(0f, 10f));

        StartCoroutine(spawnGauntletVFX());

        // Find object to attach
        RaycastHit[] hits;
        hits = Physics.RaycastAll(originPosition, direction, zRootMaximumDistance, ~characterLayerMask ^ Physics.IgnoreRaycastLayer);
        float   closestDist = zRootMaximumDistance;
        Vector3 hitNormal   = -direction;

        foreach (RaycastHit hit in hits)
        {
            ZRootInteractableObject t = hit.collider.transform.GetComponent <ZRootInteractableObject>();
            float dist = float.MaxValue;
            if (t)
            {
                if (t.zRootGrabHandle)
                {
                    dist = (t.zRootGrabHandle.position - originPosition).magnitude - t.zRootGrabOffset;
                }
                else
                {
                    dist = (hit.point - originPosition).magnitude - t.zRootGrabOffset;
                }
            }
            else if (!hit.collider.isTrigger)
            {
                dist = (hit.point - originPosition).magnitude;
            }
            if (dist < closestDist)
            {
                closestDist = dist;
                isHit       = true;
                if (t)
                {
                    interactable = t;
                    if (t.zRootGrabHandle)
                    {
                        hitPos = t.zRootGrabHandle.position - direction * t.zRootGrabOffset;
                    }
                    else
                    {
                        hitPos    = hit.point - direction * t.zRootGrabOffset;
                        hitNormal = hit.normal;
                    }
                }
                else
                {
                    interactable = null;
                    hitPos       = hit.point;
                }
            }
        }

        // Animate ZRoot to reach object
        AkSoundEngine.PostEvent("lev_zroot_shoot", gameObject);
        playVFX();
        direction = (hitPos - originPosition).normalized;
        float timeToReach = closestDist / zRootSpeed;
        float currentTime = 0;
        int   zRootShape  = 0;

        if (interactable)
        {
            zRootShape = (int)interactable.zRootClawType;
        }
        zRootObject.GetComponent <Animator> ().SetInteger("shape", zRootShape);
        zRootObject.GetComponent <Animator> ().SetTrigger("shot");
        while (currentTime < timeToReach)
        {
            currentTime += Time.deltaTime;
            if (currentTime > timeToReach)
            {
                currentTime = timeToReach;
            }

            distance      = zRootSpeed * currentTime;
            attachPoint   = originPosition + direction * distance;
            currentAngle += angularSpeed * Time.deltaTime;

            updateVFX();

            yield return(null);
        }
        AkSoundEngine.PostEvent("lev_zroot_stop", gameObject);
        stopVFX();

        // Notify the object when it's hit
        AkSoundEngine.PostEvent("lev_zroot_impact", gameObject);
        zRootObject.GetComponent <Animator> ().SetTrigger("onImpact");
        if (isHit)
        {
            if (interactable)
            {
                if (interactable.zRootClawType != ZRootClawType.Knuckle)
                {
                    yield return(new WaitForSeconds(0.05f));

                    shakeTime       = 0.35f;
                    shakeMultiplier = 1;
                    yield return(new WaitForSeconds(0.35f));

                    shakeTime = 0;
                }
                interactable.HitByZRoot(this, levController.GetComponent <Rigidbody> ());
                if (interactable.zRootClawType == ZRootClawType.Knuckle)
                {
                    float t = 0;
                    MainObjectSingleton.shared(MainObjectType.Camera).GetComponent <CameraController> ().shake(0.1f, 0.3f);
                    while (currentTime + t < timeToReach + 0.2f)
                    {
                        t += Time.deltaTime;
                        if (t > 0.2f)
                        {
                            t = 0.2f;
                        }

                        distance      = zRootSpeed * currentTime + zRootSpeed / 10 * t;
                        attachPoint   = originPosition + direction * distance;
                        currentAngle += angularSpeed * Time.deltaTime;

                        yield return(null);
                    }
                }
                if (interactable.interactDefinition == ZRootInteractableObject.InteractType.Grapple)
                {
                    yield return(new WaitForSeconds(0.1f));
                }
            }
        }
        yield return(null);

        // Animate ZRoot back to Lev's gauntlet
        AkSoundEngine.PostEvent("lev_zroot_retract", gameObject);
        zRootObject.GetComponent <Animator> ().ResetTrigger("onImpact");
        zRootObject.GetComponent <Animator> ().SetTrigger("retracted");
        direction = attachPoint - transform.position;
        distance  = direction.magnitude;
        direction.Normalize();
        while (distance > 0.1f)
        {
            distance -= zRootSpeed * Time.deltaTime;
            if (distance < 0.1f)
            {
                distance = 0.1f;
            }
            attachPoint   = transform.position + direction * distance;
            currentAngle -= angularSpeed * Time.deltaTime;

            yield return(null);
        }
        zRootObject.GetComponent <Animator> ().ResetTrigger("retracted");

        zRootObject.gameObject.SetActive(false);
    }