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); } } }