Facebook
From Haarou, 3 Years ago, written in C#.
Embed
Download Paste or View Raw
Hits: 47
  1. using System;
  2. using TMPro;
  3. using UnityEngine;
  4. using UnityEngine.SceneManagement;
  5.  
  6. public class playerMovement : MonoBehaviour
  7. {
  8.     //Assingables
  9.     public Transform playerCam;
  10.     public Transform orientation;
  11.  
  12.     //Other
  13.     private Rigidbody rb;
  14.  
  15.     //Rotation and look
  16.     public bool lockLook;
  17.     private float xRotation;
  18.     private float sensitivity = 50f;
  19.     private float sensMultiplier = 1f;
  20.  
  21.     public int health, regen;
  22.     int maxHealth;
  23.  
  24.     //Movement
  25.     public Vector3 inputVector;
  26.     public float moveSpeed = 4500;
  27.     public bool grounded, onSlope, fullAirControl;
  28.     public LayerMask whatIsGround;
  29.  
  30.     public float counterMovement = 0.175f;
  31.     private float threshold = 0.01f;
  32.     public float maxSlopeAngle = 35f;
  33.  
  34.     //Base speed handling
  35.     public float startBaseSpeed = 15f, baseSpeed, maxBaseSpeed;
  36.     public float baseSpeedAccel, baseSpeedDeccel;
  37.     public float bSAccelPoint, bSDeccelPoint, slowDownPoint;
  38.     public float dragToSlowDown;
  39.  
  40.     //Crouch & Slide
  41.     private Vector3 crouchScale = new Vector3(1, 0.5f, 1);
  42.     private Vector3 playerScale;
  43.     public float slideForce = 400;
  44.     public float slideCounterMovement = 0.2f;
  45.     public float crouchGravityMultiplier;
  46.  
  47.     //Jumping
  48.     private bool readyToJump = true;
  49.     private float jumpCooldown = 0.25f;
  50.     public float jumpForce = 550f;
  51.  
  52.     public int startDoubleJumps = 1;
  53.     int doubleJumpsLeft;
  54.  
  55.     //Input
  56.     public float x, y;
  57.     bool jumping, sprinting, crouching;
  58.  
  59.     //Air contorl
  60.     public float airForwardForce;
  61.  
  62.     //AirDash
  63.  
  64.     //Sliding
  65.     private Vector3 normalVector = Vector3.up;
  66.     private Vector3 wallNormalVector;
  67.     public float slopeDownwardForce;
  68.  
  69.     //Wallrunning
  70.     public LayerMask whatIsWall;
  71.     RaycastHit wallHitR, wallHitL;
  72.     public bool isWallRight, isWallLeft;
  73.     public float maxWallrunTime;
  74.     public float wallrunForce, wallrunUpwardForce, wallSpeedAdd;
  75.     public int wallJumps, wallJumpsLeft;
  76.     public bool readyToWallrun, isWallRunning;
  77.     public bool resetDoubleJumpsOnWall;
  78.     public GameObject lastWall;
  79.     //CamTilt
  80.     public float maxWallRunCameraTilt;
  81.     public float wallRunCameraTilt = 0;
  82.  
  83.     //Climbing
  84.     public float climbForce, climbSpeedAdd;
  85.     public LayerMask whatIsLadder;
  86.     bool alreadyStoppedAtLadder;
  87.  
  88.     //Slow-Mo
  89.     public GameObject slowMoPlane;
  90.     public float slowMoCooldown, slowMoTime;
  91.     [Range(0f, 1f)]
  92.     public float slowMoStrength;
  93.   //  bool readyForSlowMo = true;
  94.  
  95.     //Speed Display
  96.     public float speedRecord;
  97.     public TextMeshProUGUI baseVelocityDisplay, currentVelocityDisplay, recordVelocityDisplay;
  98.     void Awake()
  99.     {
  100.         rb = GetComponent<Rigidbody>();
  101.         maxHealth = health;
  102.         baseSpeed = startBaseSpeed;
  103.     }
  104.     void Start()
  105.     {
  106.         playerScale = transform.localScale;
  107.         Cursor.lockState = CursorLockMode.Locked;
  108.         Cursor.visible = false;
  109.         allowDrag = true;
  110.     }
  111.  
  112.     private void FixedUpdate()
  113.     {
  114.         Movement();
  115.     }
  116.     private void Update()
  117.     {
  118.         MyInput();
  119.         if (!lockLook) Look();
  120.         CheckForWall();
  121.  
  122.         //Stuff
  123.         if (Input.GetKeyDown(KeyCode.L)) SceneManager.LoadScene(1);
  124.  
  125.         //Trail renderer
  126.         //if (rb.velocity.magnitude <= 25) GetComponent<TrailRenderer>().startWidth
  127.  
  128.         //Set speed display
  129.         if (currentVelocityDisplay != null)
  130.             currentVelocityDisplay.SetText("currVel: " + Mathf.RoundToInt(rb.velocity.magnitude));
  131.         if (baseVelocityDisplay != null)
  132.             baseVelocityDisplay.SetText("baseVel: " + baseSpeed);
  133.         if (recordVelocityDisplay != null)
  134.             recordVelocityDisplay.SetText("recordVel: " + speedRecord);
  135.  
  136.         //new speed record
  137.         if (speedRecord < rb.velocity.magnitude)
  138.             speedRecord = Mathf.RoundToInt(rb.velocity.magnitude);
  139.         //reset Record
  140.         if (Input.GetKeyDown(KeyCode.R)) speedRecord = 0;
  141.  
  142.     }
  143.     private void MyInput()
  144.     {
  145.         x = Input.GetAxisRaw("Horizontal");
  146.         y = Input.GetAxisRaw("Vertical");
  147.         jumping = Input.GetButton("Jump");
  148.         crouching = Input.GetKey(KeyCode.LeftControl);
  149.  
  150.         //Crouching
  151.         if (Input.GetKeyDown(KeyCode.LeftControl))
  152.             StartCrouch();
  153.         if (Input.GetKeyUp(KeyCode.LeftControl))
  154.             StopCrouch();
  155.  
  156.         //If holding jump && ready to jump, then jump
  157.         if (readyToJump && jumping && grounded) Jump();
  158.         //Double Jumping
  159.         if (Input.GetButtonDown("Jump") && !grounded && doubleJumpsLeft >= 1)
  160.         {
  161.             Jump();
  162.         }
  163.         //Wall jumping
  164.         if(Input.GetButtonDown("Jump") && wallJumpsLeft >= 1 && isWallRunning)
  165.         {
  166.             Jump();
  167.         }
  168.  
  169.         //Dashing
  170.  
  171.  
  172.         //Wallrun
  173.         if (isWallRight && !grounded && readyToWallrun) StartWallrun();
  174.         if (isWallLeft && !grounded && readyToWallrun) StartWallrun();
  175.         //reset wallrun
  176.         if (!isWallRight && !isWallLeft && !readyToWallrun) readyToWallrun = true;
  177.  
  178.         //Climbing
  179.         if (Physics.Raycast(transform.position, orientation.forward, 1, whatIsLadder) && y > .9f)
  180.             Climb();
  181.         else alreadyStoppedAtLadder = false;
  182.  
  183.         //Slow-Mo
  184.        // if (Input.GetKeyDown(KeyCode.LeftControl) && readyForSlowMo) StartSlowMo();
  185.     }
  186.  
  187.  
  188.     private void Movement()
  189.     {
  190.         //Extra gravity
  191.         //Needed that the Ground Check works better!
  192.         float gravityMultiplier = 10f;
  193.  
  194.         if (crouching) gravityMultiplier = crouchGravityMultiplier;
  195.  
  196.         rb.AddForce(Vector3.down * Time.deltaTime * gravityMultiplier);
  197.  
  198.         //Find actual velocity relative to where player is looking
  199.         Vector2 mag = FindVelRelativeToLook();
  200.         float xMag = mag.x, yMag = mag.y;
  201.  
  202.         //Counteract sliding and sloppy movement
  203.         CounterMovement(x, y, mag);
  204.  
  205.         //Air Control
  206.         //if (!grounded) rb.AddForce(orientation.forward * Time.deltaTime * airForwardForce);
  207.  
  208.         //ResetStuff when touching ground
  209.         if (grounded){
  210.             doubleJumpsLeft = startDoubleJumps;
  211.             wallJumpsLeft = wallJumps;
  212.         }
  213.  
  214.         //Set max speed
  215.         float maxSpeed = this.baseSpeed;
  216.  
  217.         if (crouching && grounded && readyToJump)
  218.         {
  219.             rb.AddForce(Vector3.down * Time.deltaTime * 3000);
  220.             return;
  221.         }
  222.         //Build up speed on slope
  223.         if (crouching && onSlope)
  224.         {
  225.             rb.AddForce(Vector3.down * Time.deltaTime * slopeDownwardForce);
  226.         }
  227.  
  228.         //If speed is larger than maxSpeed, cancel out the input so you don't go over max speed
  229.         if (x > 0 && xMag > maxSpeed) x = 0;
  230.         if (x < 0 && xMag < -maxSpeed) x = 0;
  231.         if (y > 0 && yMag > maxSpeed) y = 0;
  232.         if (y < 0 && yMag < -maxSpeed) y = 0;
  233.  
  234.         //Slow down, don't allow going to fast
  235.         ///if (rb.velocity.magnitude > baseSpeed) SlowDown();
  236.  
  237.         //Some multipliers
  238.         float multiplier = 1f, multiplierV = 1f;
  239.  
  240.         // Movement in air
  241.         if (!grounded && !fullAirControl)
  242.         {
  243.             multiplier = 0.5f;
  244.             multiplierV = 0.5f;
  245.         }
  246.         if (fullAirControl)
  247.         {
  248.             multiplier = 0.35f;
  249.         }
  250.  
  251.         // Movement while sliding
  252.         if (grounded && crouching) multiplierV = 0f;
  253.  
  254.         //Apply forces to move player
  255.         rb.AddForce(orientation.transform.forward * y * moveSpeed * Time.deltaTime * multiplier * multiplierV);
  256.         rb.AddForce(orientation.transform.right * x * moveSpeed * Time.deltaTime * multiplier);
  257.  
  258.         //Base speed handling (old
  259.         ///if (rb.velocity.magnitude > baseSpeed - 3) IncreaseBaseSpeed();
  260.         ///else if (baseSpeed > startBaseSpeed) DecreaseBaseSpeed();
  261.  
  262.         //Base speed handling
  263.         if (rb.velocity.magnitude > baseSpeed + bSAccelPoint) IncreaseBaseSpeed();
  264.         if (rb.velocity.magnitude < baseSpeed - bSDeccelPoint) DecreaseBaseSpeed();
  265.         //Slow down if curr vel reaches slowDownPoint
  266.         if (rb.velocity.magnitude > baseSpeed + slowDownPoint) SlowDown();
  267.         else rb.drag = 0;
  268.     }
  269.  
  270.     private void StartCrouch()
  271.     {
  272.         transform.localScale = crouchScale;
  273.         transform.position = new Vector3(transform.position.x, transform.position.y - 0.5f, transform.position.z);
  274.         if (rb.velocity.magnitude > 0.5f)
  275.         {
  276.             if (grounded)
  277.             {
  278.                 rb.AddForce(orientation.transform.forward * slideForce);
  279.             }
  280.         }
  281.     }
  282.  
  283.     private void StopCrouch()
  284.     {
  285.         transform.localScale = playerScale;
  286.         transform.position = new Vector3(transform.position.x, transform.position.y + 0.5f, transform.position.z);
  287.     }
  288.  
  289.     private void Jump()
  290.     {
  291.         if (grounded) {
  292.             readyToJump = false;
  293.  
  294.             //Add jump forces
  295.             rb.AddForce(Vector3.up * jumpForce * 1.5f);
  296.             rb.AddForce(normalVector * jumpForce * 0.5f);
  297.  
  298.             //If jumping while falling, reset y velocity.
  299.             Vector3 vel = rb.velocity;
  300.             if (rb.velocity.y < 0.5f)
  301.                 rb.velocity = new Vector3(vel.x, 0, vel.z);
  302.             else if (rb.velocity.y > 0)
  303.                 rb.velocity = new Vector3(vel.x, vel.y / 2, vel.z);
  304.  
  305.             Invoke(nameof(ResetJump), jumpCooldown);
  306.         }
  307.         if (!grounded && !isWallRunning && doubleJumpsLeft >= 1){
  308.            
  309.             readyToJump = false;
  310.             doubleJumpsLeft--;
  311.  
  312.             //Debug.Log("DoubleJump");
  313.  
  314.             //Add jump forces
  315.             rb.AddForce(orientation.forward * jumpForce * 1f);
  316.             rb.AddForce(Vector2.up * jumpForce * 1.7f);
  317.             rb.AddForce(normalVector * jumpForce * 0.7f);
  318.  
  319.             //Dampen y velocity
  320.             rb.velocity = new Vector3(rb.velocity.x, rb.velocity.y * 0.4f, rb.velocity.z);
  321.  
  322.             Invoke(nameof(ResetJump), jumpCooldown);
  323.         }
  324.  
  325.         //Walljump
  326.         if (isWallRunning && wallJumpsLeft >= 1)
  327.         {
  328.  
  329.             //Debug.Log("WallJump");
  330.  
  331.             readyToJump = false;
  332.             wallJumpsLeft--;
  333.  
  334.             //normal jump
  335.             rb.AddForce(Vector2.up * jumpForce * 0.85f);
  336.             rb.AddForce(normalVector * jumpForce * 0.5f);
  337.             rb.AddForce(orientation.forward * jumpForce * 0.5f);
  338.             if (isWallRight) rb.AddForce(-orientation.right * jumpForce * 1.5f);
  339.             if (isWallLeft) rb.AddForce(orientation.right * jumpForce * 1.5f);
  340.  
  341.             /*sidwards wallhop
  342.             if (isWallRight||isWallLeft && Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D)) rb.AddForce(-orientation.up * jumpForce * 1f);
  343.             if (isWallRight && Input.GetKey(KeyCode.A)) rb.AddForce(-orientation.right * jumpForce * 3.2f);
  344.             if (isWallLeft && Input.GetKey(KeyCode.D)) rb.AddForce(orientation.right * jumpForce * 3.2f);
  345.             */
  346.  
  347.             //Always add forward force
  348.             rb.AddForce(orientation.forward * jumpForce * 1f);
  349.  
  350.             //Reset Velocity
  351.             rb.velocity = Vector3.zero;
  352.  
  353.             Invoke(nameof(ResetJump), jumpCooldown);
  354.         }
  355.     }
  356.     private void ResetJump()
  357.     {
  358.         readyToJump = true;
  359.     }
  360.  
  361.  
  362.     float elapsedWallTime;
  363.     private void StartWallrun()
  364.     {
  365.         //Debug.Log("Wallrunning");
  366.  
  367.         //When to stop
  368.         if (grounded) StopWallRun();
  369.  
  370.         //Count up timer
  371.         elapsedWallTime += Time.deltaTime;
  372.  
  373.         //Leave wall run when timer reaches maximum
  374.         if (elapsedWallTime > maxWallrunTime)
  375.         {
  376.             //StopWallRun();
  377.         }
  378.  
  379.         //rb.useGravity = false;
  380.         isWallRunning = true;
  381.  
  382.         //Add upward force
  383.         rb.AddForce(orientation.up * wallrunUpwardForce * Time.deltaTime);
  384.  
  385.         if (rb.velocity.magnitude <= baseSpeed + wallSpeedAdd)
  386.         {
  387.             rb.AddForce(orientation.forward * wallrunForce * Time.deltaTime);
  388.  
  389.             //Make sure char sticks to wall
  390.             if (isWallRight)
  391.             rb.AddForce(orientation.right * wallrunForce / 5 * Time.deltaTime);
  392.             else
  393.                 rb.AddForce(-orientation.right * wallrunForce / 5* Time.deltaTime);
  394.         }
  395.     }
  396.     private void StopWallRun()
  397.     {
  398.         isWallRunning = false;
  399.         readyToWallrun = false;
  400.  
  401.         //Reset timer
  402.         elapsedWallTime = 0;
  403.     }
  404.     private void CheckForWall()
  405.     {
  406.        isWallRight = Physics.Raycast(transform.position, orientation.right, out wallHitR, 1f, whatIsGround);
  407.        isWallLeft = Physics.Raycast(transform.position, -orientation.right, out wallHitL, 1f, whatIsGround);
  408.  
  409.         //if (!isWallLeft && !isWallRight) wallJumpsLeft = wallJumps;
  410.         if (!isWallLeft && !isWallRight && isWallRunning) StopWallRun();
  411.         if ((isWallLeft || isWallRight) && resetDoubleJumpsOnWall) doubleJumpsLeft = startDoubleJumps;
  412.     }
  413.     private void Climb()
  414.     {
  415.         //Makes possible to climb even when falling down fast
  416.         Vector3 vel = rb.velocity;
  417.         if (rb.velocity.y < 0.5f && !alreadyStoppedAtLadder){
  418.             rb.velocity = new Vector3(vel.x, 0, vel.z);
  419.             //Make sure char get's at wall
  420.             alreadyStoppedAtLadder = true;
  421.             rb.AddForce(orientation.forward * 500 * Time.deltaTime);
  422.         }
  423.  
  424.         //Push character up
  425.         if (rb.velocity.magnitude < baseSpeed + climbSpeedAdd)
  426.         rb.AddForce(orientation.up * climbForce * Time.deltaTime);
  427.  
  428.         //Doesn't Push into the wall
  429.         if (!Input.GetKey(KeyCode.S)) y = 0;
  430.     }
  431.  
  432.     private void StartSlowMo()
  433.     {
  434.        // readyForSlowMo = false;
  435.         slowMoPlane.SetActive(true);
  436.  
  437.         Time.timeScale = slowMoStrength;
  438.  
  439.         Invoke(nameof(StopSlowMo), slowMoTime * slowMoStrength);
  440.     }
  441.     private void StopSlowMo()
  442.     {
  443.         slowMoPlane.SetActive(false);
  444.  
  445.         Time.timeScale = 1f;
  446.  
  447.         Invoke(nameof(ResetSlowMo), slowMoCooldown);
  448.     }
  449.     private void ResetSlowMo()
  450.     {
  451.        // readyForSlowMo = true;
  452.     }
  453.  
  454.     private float desiredX;
  455.     private void Look()
  456.     {
  457.         float mouseX = Input.GetAxis("Mouse X") * sensitivity * Time.fixedDeltaTime * sensMultiplier;
  458.         float mouseY = Input.GetAxis("Mouse Y") * sensitivity * Time.fixedDeltaTime * sensMultiplier;
  459.  
  460.         //Find current look rotation
  461.         Vector3 rot = playerCam.transform.localRotation.eulerAngles;
  462.         desiredX = rot.y + mouseX;
  463.  
  464.         //Rotate, and also make sure we dont over- or under-rotate.
  465.         xRotation -= mouseY;
  466.         xRotation = Mathf.Clamp(xRotation, -90f, 90f);
  467.  
  468.         //Perform the rotations
  469.         playerCam.transform.localRotation = Quaternion.Euler(xRotation, desiredX, wallRunCameraTilt);
  470.         orientation.transform.localRotation = Quaternion.Euler(0, desiredX, 0);
  471.  
  472.         //While Wallrunning
  473.         //Tilts camera in .5 second
  474.         if (Math.Abs(wallRunCameraTilt) < maxWallRunCameraTilt && isWallRunning && isWallRight)
  475.             wallRunCameraTilt += Time.deltaTime * maxWallRunCameraTilt * 2;
  476.         if (Math.Abs(wallRunCameraTilt) < maxWallRunCameraTilt && isWallRunning && isWallLeft)
  477.             wallRunCameraTilt -= Time.deltaTime * maxWallRunCameraTilt * 2;
  478.  
  479.         //Tilts camera back again
  480.         if (wallRunCameraTilt > 0 && !isWallRight && !isWallLeft)
  481.             wallRunCameraTilt -= Time.deltaTime * maxWallRunCameraTilt * 2;
  482.         if (wallRunCameraTilt < 0 && !isWallRight && !isWallLeft)
  483.             wallRunCameraTilt += Time.deltaTime * maxWallRunCameraTilt * 2;
  484.     }
  485.  
  486.     float timer1, timer2;
  487.     float extraBaseDeccel; //Exponentially decrease base speed
  488.     private void IncreaseBaseSpeed()
  489.     {
  490.         if (baseSpeed >= maxBaseSpeed) return;
  491.  
  492.         ///Debug.Log("Decreasing BaseSpeed");
  493.  
  494.         //Only increase in .1 ticks
  495.         timer1 += Time.deltaTime * baseSpeedAccel;
  496.  
  497.         extraBaseDeccel = 0;
  498.  
  499.         if (timer1 > 1f)
  500.         {
  501.             baseSpeed += 0.1f;
  502.             timer1 = 0;
  503.         }
  504.     }
  505.     private void DecreaseBaseSpeed()
  506.     {
  507.         if (baseSpeed <= startBaseSpeed) return;
  508.  
  509.         ///Debug.Log("Increasing BaseSpeed");
  510.  
  511.         //Only decrease in .1 ticks
  512.         timer2 += Time.deltaTime * baseSpeedDeccel * extraBaseDeccel;
  513.         extraBaseDeccel += Time.deltaTime * 0.5f;
  514.  
  515.         if (timer2 > 1f)
  516.         {
  517.             baseSpeed -= 0.1f;
  518.             timer2 = 0;
  519.         }    
  520.     }
  521.  
  522.     private bool allowDrag = true;
  523.     private void SlowDown()
  524.     {
  525.         //Debug.Log("SlowingDown");
  526.  
  527.         ///Vector3 baseVelVector = rb.velocity.normalized * baseSpeed;
  528.  
  529.         ///rb.AddForce(-rb.velocity * 1f * Time.deltaTime, ForceMode.Impulse);
  530.  
  531.         //Debug.Log("Drag = 1");
  532.         if (allowDrag) rb.drag = 1;
  533.     }
  534.     private void CounterMovement(float x, float y, Vector2 mag)
  535.     {
  536.         /*Limit diagonal running. Only when holding down W and D or W and A
  537.         if (x != 0 && y != 0)
  538.         {
  539.             if (Mathf.Sqrt((Mathf.Pow(rb.velocity.x, 2) + Mathf.Pow(rb.velocity.z, 2))) > baseSpeed)
  540.             {
  541.                 float fallspeed = rb.velocity.y;
  542.                 Vector3 n = rb.velocity.normalized * baseSpeed;
  543.                 rb.velocity = new Vector3(n.x, fallspeed, n.z);
  544.             }
  545.         } */
  546.  
  547.         //if (!grounded || jumping) return;
  548.         if (!grounded || jumping || isWallRunning) return;
  549.  
  550.         //Slow down sliding
  551.         if (crouching)
  552.         {
  553.             rb.AddForce(moveSpeed * Time.deltaTime * -rb.velocity.normalized * slideCounterMovement);
  554.             return;
  555.         }
  556.  
  557.         //Counter movement:
  558.         ///Counters when no Input and still moving || Input in opposite direction then velocity
  559.         if (Math.Abs(mag.x) > threshold && Math.Abs(x) < 0.05f || (mag.x < -threshold && x > 0) || (mag.x > threshold && x < 0))
  560.         {
  561.             rb.AddForce(moveSpeed * orientation.transform.right * Time.deltaTime * -mag.x * counterMovement);
  562.         }
  563.         if (Math.Abs(mag.y) > threshold && Math.Abs(y) < 0.05f || (mag.y < -threshold && y > 0) || (mag.y > threshold && y < 0))
  564.         {
  565.             rb.AddForce(moveSpeed * orientation.transform.forward * Time.deltaTime * -mag.y * counterMovement);
  566.         }
  567.  
  568.         //Limit diagonal running. This will also cause a full stop if sliding fast and un-crouching, so not optimal.
  569.         if (Mathf.Sqrt((Mathf.Pow(rb.velocity.x, 2) + Mathf.Pow(rb.velocity.z, 2))) > baseSpeed)
  570.         {
  571.             float fallspeed = rb.velocity.y;
  572.             Vector3 n = rb.velocity.normalized * baseSpeed;
  573.             rb.velocity = new Vector3(n.x, fallspeed, n.z);
  574.         }
  575.     }
  576.  
  577.     /// Find the velocity relative to where the player is looking
  578.     /// Useful for vectors calculations regarding movement and limiting movement
  579.     public Vector2 FindVelRelativeToLook()
  580.     {
  581.         float lookAngle = orientation.transform.eulerAngles.y;
  582.         float moveAngle = Mathf.Atan2(rb.velocity.x, rb.velocity.z) * Mathf.Rad2Deg;
  583.  
  584.         float u = Mathf.DeltaAngle(lookAngle, moveAngle);
  585.         float v = 90 - u;
  586.  
  587.         float magnitue = rb.velocity.magnitude;
  588.         float yMag = magnitue * Mathf.Cos(u * Mathf.Deg2Rad);
  589.         float xMag = magnitue * Mathf.Cos(v * Mathf.Deg2Rad);
  590.  
  591.         return new Vector2(xMag, yMag);
  592.     }
  593.  
  594.     private bool IsFloor(Vector3 v)
  595.     {
  596.         float angle = Vector3.Angle(Vector3.up, v);
  597.         return angle < maxSlopeAngle;
  598.     }
  599.  
  600.     private bool cancellingGrounded;
  601.  
  602.     /// Handle ground detection
  603.     private void OnCollisionEnter(Collision collision)
  604.     {
  605.         //Debug.Log(Vector3.Angle(transform.up, collision.contacts[0].normal));
  606.     }
  607.     private void OnCollisionStay(Collision other)
  608.     {
  609.         //Make sure we are only checking for walkable layers
  610.         int layer = other.gameObject.layer;
  611.         if (whatIsGround != (whatIsGround | (1 << layer))) return;
  612.  
  613.         //Iterate through every collision in a physics update
  614.         for (int i = 0; i < other.contactCount; i++)
  615.         {
  616.             Vector3 normal = other.contacts[i].normal;
  617.             //FLOOR
  618.             if (IsFloor(normal))
  619.             {
  620.                 onSlope = false;
  621.                 grounded = true;
  622.                 cancellingGrounded = false;
  623.                 normalVector = normal;
  624.                 CancelInvoke(nameof(StopGrounded));
  625.             }
  626.             else
  627.             {
  628.                 onSlope = true;
  629.             }
  630.  
  631.             //Save lastWall
  632.             if (isWallRunning)
  633.             {
  634.                 if (lastWall != other.gameObject)
  635.                 {
  636.                    // Debug.Log("WallChanged!");
  637.                     lastWall = other.gameObject;
  638.                     wallJumpsLeft = wallJumps;
  639.                 }
  640.             }
  641.         }
  642.  
  643.         //Invoke ground/wall cancel, since we can't check normals with CollisionExit
  644.         float delay = 3f;
  645.         if (!cancellingGrounded)
  646.         {
  647.             cancellingGrounded = true;
  648.             Invoke(nameof(StopGrounded), Time.deltaTime * delay);
  649.         }
  650.     }
  651.  
  652.     private void StopGrounded()
  653.     {
  654.         grounded = false;
  655.     }
  656.  
  657.     #region abilityFunctions
  658.  
  659.     public void DashInDirection(Vector3 dir, float force)
  660.     {
  661.         rb.AddForce(dir * force, ForceMode.Impulse);
  662.     }
  663.  
  664.     public void PreventDrag(float time)
  665.     {
  666.         allowDrag = false;
  667.         Invoke(nameof(ResetAllowDrag), time);
  668.     }
  669.     private void ResetAllowDrag()
  670.     {
  671.         allowDrag = true;
  672.     }
  673.  
  674.     #endregion
  675. }
  676.  
captcha