5/8/21

 

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


namespace BNG {


    public class ARGOS_Character_Movement : MonoBehaviour
    {
        public enum LOC_Mode
        {
            NORMAL,
            GRAB_SPACE,
        }

        private Vector3 swimTran;

        //For Damped Floating Rotations
        private float rightHand_Damped_Angle = 0f;
        private Vector3 rightHand_Damped_AXIS = Vector3.one;

        private float leftHand_Damped_Angle = 0f;
        private Vector3 leftHand_Damped_AXIS = Vector3.one;

        [Range(0f, 1f)]
        public float linearFlow_LowBound = 0.04f;//Where to stop damped linear movement on Grab

        [Range(0f, 50f)]
        public float swimAmplification;

        [Range(0f, 50f)]
        public float swimAmp_Rota;

        public LOC_Mode locomotionMODE = LOC_Mode.NORMAL;

        public Material LH_Material_GrabSpace;
        public Material RH_Material_GrabSpace;

        public Material LH_Material_NORMAL;
        public Material RH_Material_NORMAL;

        public SkinnedMeshRenderer skinnedMesh_LH;
        public SkinnedMeshRenderer skinnedMesh_RH;

        private Vector3 slerp_Ctrl_Pos_Right;
        private Quaternion slerp_Rotation_Right;

        private Vector3 slerp_Ctrl_Pos_Left;
        private Quaternion slerp_Rotation_Left;

        private Vector3 vCtrl1_Last_Pos;
        private Vector3 vCtrl2_Last_Pos;
        private Vector3 vCtrl1_Right;
        private Vector3 vCtrl1_Last_Right;
        private Vector3 vCtrl1_Up;
        private Vector3 vCtrl1_Last_Up;

        private Vector3 vCtrl2_Right;
        private Vector3 vCtrl2_Last_Right;
        private Vector3 vCtrl2_Up;
        private Vector3 vCtrl2_Last_Up;

        private Vector3 slerp_Ctrl_Pos_1;
        private Quaternion slerp_Rotation_1;

        private Vector3 slerp_Ctrl_Pos_2;
        private Quaternion slerp_Rotation_2;
        public float grab_Rotate_Damping = 1.61803f;

        public float JetForce = 10;
        public Transform rightController;
        public Transform leftController;

        Vector3 accumVector_LH;
        Vector3 accumVector_RH;

        public Transform head;

        int countDamp;
        public int dampFrameCount;
        private List<Vector3> moveStack_LH = new List<Vector3>();
        private List<Vector3> moveStack_RH = new List<Vector3>();

        [Header("Input")]
        [Tooltip("Set to false to skip Update")]
        public bool AllowInput = true;

        [Tooltip("Used to determine whether to turn left / right. This can be an X Axis on the thumbstick, for example. -1 to snap left, 1 to snap right.")]
        public List<InputAxis> inputAxis_LH = new List<InputAxis>() { InputAxis.LeftThumbStickAxis };
        public List<InputAxis> inputAxis_RH = new List<InputAxis>() { InputAxis.RightThumbStickAxis };

        [Tooltip("How fast to rotate the player if RotationType is set to 'Smooth'")]
        public float SmoothTurnSpeed = 40f;

        [Tooltip("Thumbstick X axis must be >= this amount to be considered an input event")]
        public float SmoothTurnMinInput = 0.1f;

        [Header("Keyboard Input")]
        /// <summary>
        /// Allow Q,E to rotate player
        /// </summary>
        [Tooltip("Allow Q,E to rotate player")]
        public bool AllowKeyboardInputs = true;    

        Grabber leftGrabber;
        Grabber rightGrabber;
        bool handOccupied = false;

        void Start()
        {

            for (int i = 0; i < dampFrameCount; i++)
            {
                moveStack_LH.Add(new Vector3(0, 0, 0));
                moveStack_RH.Add(new Vector3(0, 0, 0));
            }

            // Assign left / right grabbers
            Grabber[] grabs = GameObject.FindGameObjectWithTag("Player").GetComponentsInChildren<Grabber>();
            foreach (var g in grabs)
            {
                if (g.HandSide == ControllerHand.Left)
                {
                    leftGrabber = g;
                }
                else if (g.HandSide == ControllerHand.Right)
                {
                    rightGrabber = g;
                }
            }
        }

        void Update()
        {
            if (!AllowInput) {
                return;
            }
            Swimming_In_The_VU();
            DoSmoothRotation();

            if (BNG.InputBridge.Instance.RightThumbstickDown)
            {
                if(locomotionMODE == LOC_Mode.NORMAL)
                {
                    locomotionMODE = LOC_Mode.GRAB_SPACE;
                    skinnedMesh_LH.material = LH_Material_GrabSpace;
                    skinnedMesh_RH.material = RH_Material_GrabSpace;
                }
                else
                {
                    locomotionMODE = LOC_Mode.NORMAL;
                    skinnedMesh_LH.material = LH_Material_NORMAL;
                    skinnedMesh_RH.material = RH_Material_NORMAL;
                }
            }
        }

        public void Swimming_In_The_VU()
        {
            Vector3 currSwimTran= Vector3.zero;
            float currSwimQ_Angle_RH = 0f;
            float currSwimQ_Angle_LH = 0f;

            bool grabbersExist = leftGrabber != null && rightGrabber != null;

            // Holding Item
            handOccupied = grabbersExist && (leftGrabber.HoldingItem || rightGrabber.HoldingItem);

            // Not a valid Grab
            if (grabbersExist && !leftGrabber.FreshGrip && !rightGrabber.FreshGrip)
            {
                handOccupied = true;
            }

            Vector3 axis;
            float angle;

            float fRH_GRIP = BNG.InputBridge.Instance.RightGrip;
            float fLH_GRIP = BNG.InputBridge.Instance.LeftGrip;

            bool bRH_GRIP_PRESSED = fRH_GRIP > 0.3f;
            bool bLH_GRIP_PRESSED = fLH_GRIP > 0.3f;

            bool bAGripPressed = bRH_GRIP_PRESSED || bLH_GRIP_PRESSED;

            if (!handOccupied)
            {
                if (bRH_GRIP_PRESSED /*&& bClimb1*/)
                {
                    //print("Climb Frame Trigger & bClimb -  1");
                    vCtrl1_Right = rightController.transform.right;
                    Quaternion q = Quaternion.FromToRotation(vCtrl1_Right, vCtrl1_Last_Right);

                    vCtrl1_Up = rightController.transform.up;
                    Quaternion q2 = Quaternion.FromToRotation(vCtrl1_Up, vCtrl1_Last_Up);
                    Quaternion q3 = q * q2;

                    slerp_Ctrl_Pos_1 = Vector3.Slerp(slerp_Ctrl_Pos_1, rightController.transform.position, Time.deltaTime * grab_Rotate_Damping);

                    slerp_Rotation_1 = Quaternion.Slerp(slerp_Rotation_1, q3, Time.deltaTime * grab_Rotate_Damping);

                    slerp_Rotation_1.ToAngleAxis(out angle, out axis);

                    transform.RotateAround(rightController.transform.position, axis, angle * 0.99f);

                    if(angle < 0.5f)//No flowing rotation if below this value
                    {
                        angle = 0;
                    }
                    currSwimQ_Angle_RH = angle;
                    rightHand_Damped_AXIS = axis;
                    //VU_UI.transform.RotateAround(ctrl1.transform.position, axis, angle * 0.99f);
                }
                else if (bLH_GRIP_PRESSED /*&& bClimb2*/)
                {
                    //print("Climb Frame Trigger & bClimb -  2");
                    vCtrl2_Right = leftController.transform.right;
                    Quaternion q = Quaternion.FromToRotation(vCtrl2_Right, vCtrl2_Last_Right);

                    vCtrl2_Up = leftController.transform.up;
                    Quaternion q2 = Quaternion.FromToRotation(vCtrl2_Up, vCtrl2_Last_Up);
                    Quaternion q3 = q * q2;
                    slerp_Ctrl_Pos_2 = Vector3.Slerp(slerp_Ctrl_Pos_2, leftController.transform.position, Time.deltaTime * grab_Rotate_Damping);

                    slerp_Rotation_2 = Quaternion.Slerp(slerp_Rotation_2, q3, Time.deltaTime * grab_Rotate_Damping);

                    slerp_Rotation_2.ToAngleAxis(out angle, out axis);

                    transform.RotateAround(leftController.transform.position, axis, angle * 0.99f);

                    if (angle < 0.5f)//No flowing rotation if below this value
                    {
                        angle = 0;
                    }
                    currSwimQ_Angle_LH = angle;
                    leftHand_Damped_AXIS = axis;

                    //VU_UI.transform.RotateAround(ctrl2.transform.position, axis, angle * 0.99f);
                }

                float c = 1;
                //if (current_USER_LOCATION == USER_LOCATION.IN_THE_VU)
                //{
                //    c = curr_Flight_Tran;
                //}

                //Linear Movement
                if (bRH_GRIP_PRESSED)
                {
                    //print("Climb Frame GRIP & bClimb -  1");
                    Vector3 vDelt = rightController.transform.position -vCtrl1_Last_Pos;
                    Vector3 vTran = c * vDelt; //argos_Teleport.transform.InverseTransformDirection(c * vDelt);
                    transform.position -= vTran;

                    Check_Flow_Linear_Movement(vTran, ref currSwimTran);

                    //VU_UI.transform.position -= vTran;
                }
                else if (bLH_GRIP_PRESSED)
                {
                    //print("Climb Frame GRIP & bClimb -  2");
                    Vector3 vDelt = leftController.transform.position - vCtrl2_Last_Pos;
                    Vector3 vTran = c * vDelt; //argos_Teleport.transform.InverseTransformDirection(c *vDelt);
                    transform.position -= vTran;

                    Check_Flow_Linear_Movement(vTran, ref currSwimTran);
                }

                //Clear State
                if (!bAGripPressed)
                {
                    if (true /*active_Ctrl_States.bCtrl_1_On*/)
                    {
                        //slerp_Ctrl_Pos_1 = ctrl1.transform.position;
                        //slerp_Rotation_1 = Quaternion.identity;

                        vCtrl1_Right = rightController.transform.right;
                        Quaternion q = Quaternion.FromToRotation(vCtrl1_Right, vCtrl1_Right);

                        vCtrl1_Up = rightController.transform.up;
                        Quaternion q2 = Quaternion.FromToRotation(vCtrl1_Up, vCtrl1_Up);
                        Quaternion q3 = q * q2;

                        slerp_Ctrl_Pos_1 = rightController.transform.position;

                        slerp_Rotation_1 = q3;
                    }
                    if (true/*active_Ctrl_States.bCtrl_2_On*/)
                    {
                        //slerp_Ctrl_Pos_2 = ctrl2.transform.position;
                        //slerp_Rotation_2 = Quaternion.identity;

                        vCtrl2_Right = leftController.transform.right;
                        Quaternion q = Quaternion.FromToRotation(vCtrl2_Right, vCtrl2_Right);

                        vCtrl2_Up = leftController.transform.up;
                        Quaternion q2 = Quaternion.FromToRotation(vCtrl2_Up, vCtrl2_Up);
                        Quaternion q3 = q * q2;
                        slerp_Ctrl_Pos_2 = leftController.transform.position;

                        slerp_Rotation_2 = q3;
                    }
                }
            }
            else
            {
                if (true /*active_Ctrl_States.bCtrl_1_On*/)
                {
                    //slerp_Ctrl_Pos_1 = ctrl1.transform.position;
                    //slerp_Rotation_1 = Quaternion.identity;

                    vCtrl1_Right = rightController.transform.right;
                    Quaternion q = Quaternion.FromToRotation(vCtrl1_Right, vCtrl1_Right);

                    vCtrl1_Up = rightController.transform.up;
                    Quaternion q2 = Quaternion.FromToRotation(vCtrl1_Up, vCtrl1_Up);
                    Quaternion q3 = q * q2;

                    slerp_Ctrl_Pos_1 = rightController.transform.position;

                    slerp_Rotation_1 = q3;
                }
                if (true/*active_Ctrl_States.bCtrl_2_On*/)
                {
                    //slerp_Ctrl_Pos_2 = ctrl2.transform.position;
                    //slerp_Rotation_2 = Quaternion.identity;

                    vCtrl2_Right = leftController.transform.right;
                    Quaternion q = Quaternion.FromToRotation(vCtrl2_Right, vCtrl2_Right);

                    vCtrl2_Up = leftController.transform.up;
                    Quaternion q2 = Quaternion.FromToRotation(vCtrl2_Up, vCtrl2_Up);
                    Quaternion q3 = q * q2;
                    slerp_Ctrl_Pos_2 = leftController.transform.position;

                    slerp_Rotation_2 = q3;
                }
            }
            vCtrl1_Last_Right = rightController.transform.right;
            vCtrl2_Last_Right = leftController.transform.right;
            vCtrl1_Last_Up = rightController.transform.up;
            vCtrl2_Last_Up = leftController.transform.up;

            vCtrl1_Last_Pos = rightController.transform.position;
            vCtrl2_Last_Pos = leftController.transform.position;

            //SWIM Tran
            swimTran = Vector3.Lerp(swimTran, currSwimTran, 0.1f*Time.deltaTime );
            transform.position += swimAmplification*swimTran;



            if (bRH_GRIP_PRESSED)
            {
                rightHand_Damped_Angle = currSwimQ_Angle_RH;
                //    rightHand_Damped_Angle = Mathf.Lerp(rightHand_Damped_Angle, 0, Time.deltaTime);
                //    transform.RotateAround(rightController.transform.position, rightHand_Damped_AXIS, rightHand_Damped_Angle * swimAmp_Rota);
            }
            else
            {
                rightHand_Damped_Angle = Mathf.Lerp(rightHand_Damped_Angle, currSwimQ_Angle_RH, 0.1f*Time.deltaTime);
                transform.RotateAround(rightController.transform.position, rightHand_Damped_AXIS, rightHand_Damped_Angle * swimAmp_Rota);
            }
            if (bLH_GRIP_PRESSED)
            {
                leftHand_Damped_Angle = currSwimQ_Angle_LH;
                //    rightHand_Damped_Angle = Mathf.Lerp(rightHand_Damped_Angle, 0, Time.deltaTime);
                //    transform.RotateAround(rightController.transform.position, rightHand_Damped_AXIS, rightHand_Damped_Angle * swimAmp_Rota);
            }
            else
            {
                leftHand_Damped_Angle = Mathf.Lerp(leftHand_Damped_Angle, currSwimQ_Angle_LH, 0.1f * Time.deltaTime);
                transform.RotateAround(leftController.transform.position, leftHand_Damped_AXIS, leftHand_Damped_Angle * swimAmp_Rota);
            }
        }

        public void Check_Flow_Linear_Movement(Vector3 vTran, ref Vector3 currSwimTran)
        {
            if (vTran.magnitude < linearFlow_LowBound)
            {
                currSwimTran = Vector3.zero;
                swimTran = Vector3.zero;
            }
            else
            {
                currSwimTran -= vTran;
            }
        }

        public virtual void DoSmoothRotation()
        {

            Vector2 axisVal_LH = BNG.InputBridge.Instance.GetInputAxisValue(inputAxis_LH[0]);
            Vector2 axisVal_RH = BNG.InputBridge.Instance.GetInputAxisValue(inputAxis_RH[0]);

            // Reset rotation amount before retrieving inputs
            float rotationAmount = 0;
            float xInput = axisVal_LH.x;

            // Smooth Rotate Right
            if (xInput >= SmoothTurnMinInput) {
                rotationAmount += xInput * xInput * xInput * SmoothTurnSpeed * Time.deltaTime;
            }
            // Smooth Rotate Left
            else if (xInput <= -SmoothTurnMinInput) {
                rotationAmount += xInput * xInput * xInput * SmoothTurnSpeed * Time.deltaTime;
            }

            // Apply rotation
            transform.rotation = Quaternion.Euler(new Vector3(transform.eulerAngles.x, transform.eulerAngles.y + rotationAmount, transform.eulerAngles.z));

            //TRANSLATION LH
            Vector3 moveDirection_LH = leftController.forward * JetForce;
            Vector3 moveVector_LH = moveDirection_LH * axisVal_LH.y * axisVal_LH.y * axisVal_LH.y * axisVal_LH.y * axisVal_LH.y;

            Vector3 moveDirection_RH = rightController.forward * JetForce;//   head.forward * JetForce;
            Vector3 moveSideways_RH  = rightController.right * JetForce;

            Vector3 moveVector_RH = moveDirection_RH * axisVal_RH.y * axisVal_RH.y * axisVal_RH.y * axisVal_RH.y * axisVal_RH.y
                         + moveSideways_RH * axisVal_RH.x * axisVal_RH.x * axisVal_RH.x * axisVal_RH.x * axisVal_RH.x;

            moveStack_LH[countDamp] = moveVector_LH;
            moveStack_RH[countDamp] = moveVector_RH;

            if (++countDamp >= dampFrameCount)
            {
                countDamp = 0;
            }
            accumVector_LH = Vector3.zero;
            for (int i = 0; i < dampFrameCount; i++)
            {
                accumVector_LH += moveStack_LH[i];
                accumVector_RH += moveStack_RH[i];
            }
            accumVector_LH /= dampFrameCount;
            accumVector_RH /= dampFrameCount;
            transform.position += (accumVector_LH * Time.deltaTime + accumVector_RH * Time.deltaTime);
        }
    }
}