Example #1
0
    private void CompensateForWalls(Vector3 fromObject, ref Vector3 toTarget)
    {
        // Compensate for walls between camera
        RaycastHit wallHit = new RaycastHit();

        if (Physics.Linecast(fromObject, toTarget, out wallHit))
        {
            Debug.DrawRay(wallHit.point, wallHit.normal, Color.red);
            toTarget = wallHit.point;
        }

        // Compensate for geometry intersecting with near clip plane
        Vector3 camPosCache = GetComponent <Camera>().transform.position;

        GetComponent <Camera>().transform.position = toTarget;
        viewFrustum = DebugDraw.CalculateViewFrustum(GetComponent <Camera>(), ref nearClipDimensions);

        for (int i = 0; i < (viewFrustum.Length / 2); i++)
        {
            RaycastHit cWHit  = new RaycastHit();
            RaycastHit cCWHit = new RaycastHit();

            // Cast lines in both directions around near clipping plane bounds
            while (Physics.Linecast(viewFrustum[i], viewFrustum[(i + 1) % (viewFrustum.Length / 2)], out cWHit) ||
                   Physics.Linecast(viewFrustum[(i + 1) % (viewFrustum.Length / 2)], viewFrustum[i], out cCWHit))
            {
                Vector3 normal = wallHit.normal;
                if (wallHit.normal == Vector3.zero)
                {
                    // If there's no available wallHit, use normal of geometry intersected by LineCasts instead
                    if (cWHit.normal == Vector3.zero)
                    {
                        if (cCWHit.normal == Vector3.zero)
                        {
                            Debug.LogError("No available geometry normal from near clip plane LineCasts. Something must be amuck.", this);
                        }
                        else
                        {
                            normal = cCWHit.normal;
                        }
                    }
                    else
                    {
                        normal = cWHit.normal;
                    }
                }

                toTarget += (compensationOffset * normal);
                GetComponent <Camera>().transform.position += toTarget;

                // Recalculate positions of near clip plane
                viewFrustum = DebugDraw.CalculateViewFrustum(GetComponent <Camera>(), ref nearClipDimensions);
            }
        }

        GetComponent <Camera>().transform.position = camPosCache;
        viewFrustum = DebugDraw.CalculateViewFrustum(GetComponent <Camera>(), ref nearClipDimensions);
    }
Example #2
0
        /// <summary>
        /// <para>Compensa la camara para que no ocurran colisiones.</para>
        /// </summary>
        /// <param name="fromObject"></param>
        /// <param name="toTarget"></param>
        private void CompensarColisiones(Vector3 fromObject, ref Vector3 toTarget)
        {
            // Compensar las paredes entre la camara
            RaycastHit hitCollider = new RaycastHit();

            if (Physics.Linecast(fromObject, toTarget, out hitCollider))
            {
                Debug.DrawRay(hitCollider.point, hitCollider.normal, Color.red);
                toTarget = hitCollider.point;
            }

            // Compensar geo
            Vector3 camPosCache = GetComponent <Camera>().transform.position;

            GetComponent <Camera>().transform.position = toTarget;
            vistaDebug = DebugDraw.CalculateViewFrustum(GetComponent <Camera>(), ref dimension);

            for (int i = 0; i < (vistaDebug.Length / 2); i++)
            {
                RaycastHit cWHit  = new RaycastHit();
                RaycastHit cCWHit = new RaycastHit();

                // Reparte lineas en ambas direcciones alrededor de los limites del plano de recorte
                while (Physics.Linecast(vistaDebug[i], vistaDebug[(i + 1) % (vistaDebug.Length / 2)], out cWHit) ||
                       Physics.Linecast(vistaDebug[(i + 1) % (vistaDebug.Length / 2)], vistaDebug[i], out cCWHit))
                {
                    Vector3 normal = hitCollider.normal;
                    if (hitCollider.normal == Vector3.zero)
                    {
                        // Si no hay hitCollider disponible, usa la geometria
                        if (cWHit.normal == Vector3.zero)
                        {
                            if (cCWHit.normal == Vector3.zero)
                            {
                                Debug.LogError("No hay geometria disponible cerca del plano de LineCasts.", this);
                            }
                            else
                            {
                                normal = cCWHit.normal;
                            }
                        }
                        else
                        {
                            normal = cWHit.normal;
                        }
                    }

                    toTarget += (0.2f * normal);
                    GetComponent <Camera>().transform.position += toTarget;

                    // Recalcular posicion
                    vistaDebug = DebugDraw.CalculateViewFrustum(GetComponent <Camera>(), ref dimension);
                }
            }

            GetComponent <Camera>().transform.position = camPosCache;
            vistaDebug = DebugDraw.CalculateViewFrustum(GetComponent <Camera>(), ref dimension);
        }
Example #3
0
    void LateUpdate()
    {
        viewFrustum = DebugDraw.CalculateViewFrustum(GetComponent <Camera>(), ref nearClipDimensions);

        // Pull values from controller/keyboard
        float rightX = Input.GetAxis("RightStickX");
        float rightY = Input.GetAxis("RightStickY");
        float leftX  = Input.GetAxis("Horizontal");
        float leftY  = Input.GetAxis("Vertical");
        //float mouseWheel = Input.GetAxis("Mouse ScrollWheel");
        //float mouseWheelScaled = mouseWheel * mouseWheelSensitivity;
        //float leftTrigger = Input.GetAxis("Target");
        //bool bButtonPressed = Input.GetButton("ExitFPV");
        bool qKeyDown      = Input.GetKey(KeyCode.Q);
        bool eKeyDown      = Input.GetKey(KeyCode.E);
        bool lShiftKeyDown = Input.GetKey(KeyCode.LeftShift);

        // Abstraction to set right Y when using mouse


        if (qKeyDown)
        {
            //rightX = 1;
        }
        if (eKeyDown)
        {
            //rightX = -1;
        }
        if (lShiftKeyDown)
        {
            //leftTrigger = 1;
        }

        characterOffset = followXform.position + (distanceUp * followXform.up) - characterOffset2;
        Vector3 lookAt = characterOffset;

        targetPosition = Vector3.zero;

        // Determine camera state
        // * Targeting *

        /*
         * if (leftTrigger > TARGETING_THRESHOLD)
         * {
         *      barEffect.coverage = Mathf.SmoothStep(barEffect.coverage, widescreen, targetingTime);
         *
         *      camState = CamStates.Target;
         * }*/

        if (Input.GetButton("TargetCam"))
        {
            barEffect.coverage = Mathf.SmoothStep(barEffect.coverage, widescreen, targetingTime);

            camState = CamStates.Target;
        }
        else
        {
            barEffect.coverage = Mathf.SmoothStep(barEffect.coverage, 0f, targetingTime);

            // * First Person *
            if (Input.GetButton("FirstPersonCam"))
            {
                // Reset look before entering the first person mode
                //xAxisRot = 0;
                //lookWeight = 0f;
                camState = CamStates.FirstPerson;
            }

            // * Free *
        }

        if (Input.GetButton("BehindCam"))
        {
            camState = CamStates.Behind;
        }

        if (Input.GetButton("FreeCam"))
        {
            camState = CamStates.Free;
        }



        //----

        // Set the Look At Weight - amount to use look at IK vs using the head's animation
//		follow.Animator.SetLookAtWeight(lookWeight);

        // Execute camera state
        switch (camState)
        {
        case CamStates.Behind:
            ResetCamera();

            // Only update camera look direction if moving

            /*
             * if (follow.Speed > follow.LocomotionThreshold && follow.IsInLocomotion() && !follow.IsInPivot())
             *      {
             *              lookDir = Vector3.Lerp(followXform.right * (leftX < 0 ? 1f : -1f), followXform.forward * (leftY < 0 ? -1f : 1f), Mathf.Abs(Vector3.Dot(this.transform.forward, followXform.forward)));
             *              Debug.DrawRay(this.transform.position, lookDir, Color.white);
             *
             *              // Calculate direction from camera to player, kill Y, and normalize to give a valid direction with unit magnitude
             *              curLookDir = Vector3.Normalize(characterOffset - this.transform.position);
             *              curLookDir.y = 0;
             *              Debug.DrawRay(this.transform.position, curLookDir, Color.green);
             *
             *              // Damping makes it so we don't update targetPosition while pivoting; camera shouldn't rotate around player
             *              curLookDir = Vector3.SmoothDamp(curLookDir, lookDir, ref velocityLookDir, lookDirDampTime);
             *      }
             */
            targetPosition = characterOffset + followXform.up * distanceUp - Vector3.Normalize(curLookDir) * distanceAway;
            Debug.DrawLine(followXform.position, targetPosition, Color.magenta);


            firstPersonCamPos.SetActive(false);


            break;

        case CamStates.Target:
            ResetCamera();
            lookDir    = followXform.forward;
            curLookDir = followXform.forward;

            targetPosition = characterOffset + followXform.up * distanceUp - lookDir * distanceAway;
            firstPersonCamPos.SetActive(false);

            break;

        case CamStates.FirstPerson:

            /*// Looking up and down
             *      // Calculate the amount of rotation and apply to the firstPersonCamPos GameObject
             *  xAxisRot += (leftY * 0.5f * firstPersonLookSpeed);
             * xAxisRot = Mathf.Clamp(xAxisRot, firstPersonXAxisClamp.x, firstPersonXAxisClamp.y);
             *      firstPersonCamPos.XForm.localRotation = Quaternion.Euler(xAxisRot, 0, 0);
             *
             *      // Superimpose firstPersonCamPos GameObject's rotation on camera
             *      Quaternion rotationShift = Quaternion.FromToRotation(this.transform.forward, firstPersonCamPos.XForm.forward);
             *      this.transform.rotation = rotationShift * this.transform.rotation;
             *
             *      // Move character model's head
             * follow.Animator.SetLookAtPosition(firstPersonCamPos.XForm.position + firstPersonCamPos.XForm.forward);
             *      lookWeight = Mathf.Lerp(lookWeight, 1.0f, Time.deltaTime * firstPersonLookSpeed);
             *
             *
             *      // Looking left and right
             *      // Similarly to how character is rotated while in locomotion, use Quaternion * to add rotation to character
             *      Vector3 rotationAmount = Vector3.Lerp(Vector3.zero, new Vector3(0f, fPSRotationDegreePerSecond * (leftX < 0f ? -1f : 1f), 0f), Mathf.Abs(leftX));
             *      Quaternion deltaRotation = Quaternion.Euler(rotationAmount * Time.deltaTime);
             * follow.transform.rotation = (follow.transform.rotation * deltaRotation);
             *
             *      // Move camera to firstPersonCamPos
             *      //targetPosition = firstPersonCamPos.XForm.position;
             *
             *      // Smoothly transition look direction towards firstPersonCamPos when entering first person mode
             *      lookAt = Vector3.Lerp(targetPosition + followXform.forward, this.transform.position + this.transform.forward, camSmoothDampTime * Time.deltaTime);
             *      Debug.DrawRay(Vector3.zero, lookAt, Color.black);
             *      Debug.DrawRay(Vector3.zero, targetPosition + followXform.forward, Color.white);
             *      Debug.DrawRay(Vector3.zero, firstPersonCamPos.XForm.position + firstPersonCamPos.XForm.forward, Color.cyan);
             *
             *      // Choose lookAt target based on distance
             *      lookAt = (Vector3.Lerp(this.transform.position + this.transform.forward, lookAt, Vector3.Distance(this.transform.position, firstPersonCamPos.XForm.position)));
             */


            targetPosition = firstPersonCamPos.transform.position;
            lookAt         = Vector3.Lerp(targetPosition + followXform.forward, this.transform.position + this.transform.forward, camSmoothDampTime * Time.deltaTime);

            if (Vector3.Distance(targetPosition, this.transform.position) < 2)
            {
                firstPersonCamPos.SetActive(true);
            }



            break;

        case CamStates.Free:
            lookWeight = Mathf.Lerp(lookWeight, 0.0f, Time.deltaTime * firstPersonLookSpeed);

            Vector3 rigToGoal = characterOffset - cameraXform.position;
            rigToGoal.y = 0f;
            Debug.DrawRay(cameraXform.transform.position, rigToGoal, Color.red);

            // Panning in and out
            // If statement works for positive values; don't tween if stick not increasing in either direction; also don't tween if user is rotating
            // Checked against rightStickThreshold because very small values for rightY mess up the Lerp function
            if (rightY < lastStickMin && rightY < -1f * rightStickThreshold && rightY <= rightStickPrevFrame.y && Mathf.Abs(rightX) < rightStickThreshold)
            {
                // Zooming out
                distanceUpFree   = Mathf.Lerp(distanceUp, distanceUp * distanceUpMultiplier, Mathf.Abs(rightY));
                distanceAwayFree = Mathf.Lerp(distanceAway, distanceAway * distanceAwayMultipler, Mathf.Abs(rightY));
                targetPosition   = characterOffset + followXform.up * distanceUpFree - RigToGoalDirection * distanceAwayFree;
                lastStickMin     = rightY;
            }
            else if (rightY > rightStickThreshold && rightY >= rightStickPrevFrame.y && Mathf.Abs(rightX) < rightStickThreshold)
            {
                // Zooming in
                // Subtract height of camera from height of player to find Y distance
                distanceUpFree = Mathf.Lerp(Mathf.Abs(transform.position.y - characterOffset.y), camMinDistFromChar.y, rightY);
                // Use magnitude function to find X distance
                distanceAwayFree = Mathf.Lerp(rigToGoal.magnitude, camMinDistFromChar.x, rightY);
                targetPosition   = characterOffset + followXform.up * distanceUpFree - RigToGoalDirection * distanceAwayFree;
                lastStickMin     = float.PositiveInfinity;
            }

            // Store direction only if right stick inactive
            if (rightX != 0 || rightY != 0)
            {
                savedRigToGoal = RigToGoalDirection;
            }


            // Rotating around character
            cameraXform.RotateAround(characterOffset, followXform.up, freeRotationDegreePerSecond * -1 * (Mathf.Abs(rightX) > rightStickThreshold ? rightX : 0f));

            // Still need to track camera behind player even if they aren't using the right stick; achieve this by saving distanceAwayFree every frame
            if (targetPosition == Vector3.zero)
            {
                targetPosition = characterOffset + followXform.up * distanceUpFree - savedRigToGoal * distanceAwayFree;
            }
            firstPersonCamPos.SetActive(false);
            break;
        }


        CompensateForWalls(characterOffset, ref targetPosition);
        SmoothPosition(cameraXform.position, targetPosition);
        transform.LookAt(lookAt);

        // Make sure to cache the unscaled mouse wheel value if using mouse/keyboard instead of controller
        rightStickPrevFrame = new Vector2(rightX, rightY);        //mouseWheel != 0 ? mouseWheelScaled : rightY);
    }
Example #4
0
        private void LateUpdate()
        {
            vistaDebug = DebugDraw.CalculateViewFrustum(GetComponent <Camera>(), ref dimension);

            // Obtener valores de controller/teclado
            float rightX            = Input.GetAxis("RightStickX");
            float rightY            = Input.GetAxis("RightStickY");
            float leftX             = Input.GetAxis("Horizontal");
            float leftY             = Input.GetAxis("Vertical");
            float mouseRuleta       = Input.GetAxis("Mouse ScrollWheel");
            float mouseRuletaEscala = mouseRuleta * sensibilidad;
            float leftTrigger       = Input.GetAxis("Target");
            bool  btnB     = Input.GetButton("ExitFPV");
            bool  keyQ     = Input.GetKey(KeyCode.Q);
            bool  keyE     = Input.GetKey(KeyCode.E);
            bool  keyShift = Input.GetKey(KeyCode.LeftShift);

            // Abstraccion para establecer Y correctamente al usar el raton
            if (mouseRuleta != 0)
            {
                rightY = mouseRuletaEscala;
            }
            if (keyQ)
            {
                rightX = 1;
            }
            if (keyE)
            {
                rightX = -1;
            }
            if (keyShift)
            {
                leftTrigger = 1;
            }

            offSetPersonaje = personaje.position + (distanciaArriba * personaje.up);
            Vector3 lookAt = offSetPersonaje;

            posicionTarget = Vector3.zero;

            // Establece el valor del peso
            motor.Animator.SetLookAtWeight(fuerzaLook);

            // Logica

            // Reseteo de camara
            ResetCamara();

            // Solo actualice la direccion de la camara si se mueve
            if (motor.Velocidad > motor.LocomotionLimite && motor.IsInLocomotion() && !motor.IsPivotando())
            {
                dirFija = Vector3.Lerp(personaje.right * (leftX < 0 ? 1f : -1f), personaje.forward * (leftY < 0 ? -1f : 1f), Mathf.Abs(Vector3.Dot(this.transform.forward, personaje.forward)));
                Debug.DrawRay(this.transform.position, dirFija, Color.white);

                // Calcula la direccion de la camara al jugador, mata Y y normaliza para dar una direccion valida con la magnitud de la unidad
                actualDirFija   = Vector3.Normalize(offSetPersonaje - this.transform.position);
                actualDirFija.y = 0;
                Debug.DrawRay(this.transform.position, actualDirFija, Color.green);

                // La interpolacion
                actualDirFija = Vector3.SmoothDamp(actualDirFija, dirFija, ref velActualCam, tiempoLookAt);
            }

            posicionTarget = offSetPersonaje + personaje.up * distanciaArriba - Vector3.Normalize(actualDirFija) * distanciaLejana;
            Debug.DrawLine(personaje.position, posicionTarget, Color.magenta);

            CompensarColisiones(offSetPersonaje, ref posicionTarget);
            TransicionPosicion(camara.position, posicionTarget);
            transform.LookAt(lookAt);
        }
    private void FixedUpdate()
    {
		viewFrustum = DebugDraw.CalculateViewFrustum(GetComponent<Camera>(), ref nearClipDimensions);
    }