daily pastebin goal
41%
SHARE
TWEET

Untitled

a guest Jan 29th, 2018 49 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. // Contains the command the user wishes upon the character
  6. struct Cmd
  7. {
  8.     public float forwardMove;
  9.     public float rightMove;
  10.     public float upMove;
  11. }
  12.  
  13. public class GMSPlayer : MonoBehaviour
  14. {
  15.     public Transform playerView;     // Camera
  16.     public float playerViewYOffset = 0.6f; // The height at which the camera is bound to
  17.     public float xMouseSensitivity = 30.0f;
  18.     public float yMouseSensitivity = 30.0f;
  19. //
  20.     /*Frame occuring factors*/
  21.     public float gravity = 20.0f;
  22.  
  23.     public float friction = 6; //Ground friction
  24.  
  25.     /* Movement stuff */
  26.     public float moveSpeed = 7.0f;                // Ground move speed
  27.     public float runAcceleration = 14.0f;         // Ground accel
  28.     public float runDeacceleration = 10.0f;       // Deacceleration that occurs when running on the ground
  29.     public float airAcceleration = 2.0f;          // Air accel
  30.     public float airDecceleration = 2.0f;         // Deacceleration experienced when ooposite strafing
  31.     public float airControl = 0.3f;               // How precise air control is
  32.     public float sideStrafeAcceleration = 50.0f;  // How fast acceleration occurs to get up to sideStrafeSpeed when
  33.     public float sideStrafeSpeed = 1.0f;          // What the max speed to generate when side strafing
  34.     public float jumpSpeed = 8.0f;                // The speed at which the character's up axis gains when hitting jump
  35.     public float moveScale = 1.0f;
  36.  
  37.     /*print() style */
  38.     public GUIStyle style;
  39.  
  40.     /*FPS Stuff */
  41.     public float fpsDisplayRate = 4.0f; // 4 updates per sec
  42.  
  43.     private int frameCount = 0;
  44.     private float dt = 0.0f;
  45.     private float fps = 0.0f;
  46.  
  47.     private CharacterController _controller;
  48.  
  49.     // Camera rotations
  50.     private float rotX = 0.0f;
  51.     private float rotY = 0.0f;
  52.  
  53.     private Vector3 moveDirectionNorm = Vector3.zero;
  54.     private Vector3 playerVelocity = Vector3.zero;
  55.     private float playerTopVelocity = 0.0f;
  56.  
  57.     // Q3: players can queue the next jump just before he hits the ground
  58.     private bool wishJump = false;
  59.  
  60.     // Used to display real time fricton values
  61.     private float playerFriction = 0.0f;
  62.  
  63.     // Player commands, stores wish commands that the player asks for (Forward, back, jump, etc)
  64.     private Cmd _cmd;
  65.  
  66.     private void Start()
  67.     {
  68.         // Hide the cursor
  69.         Cursor.visible = false;
  70.         Cursor.lockState = CursorLockMode.Locked;
  71.  
  72.         // Put the camera inside the capsule collider
  73.         playerView.position = new Vector3(
  74.             transform.position.x,
  75.             transform.position.y + playerViewYOffset,
  76.             transform.position.z);
  77.  
  78.         _controller = GetComponent<CharacterController>();
  79.     }
  80.  
  81.     private void Update()
  82.     {
  83.         // Do FPS calculation
  84.         frameCount++;
  85.         dt += Time.deltaTime;
  86.         if (dt > 1.0 / fpsDisplayRate)
  87.         {
  88.             fps = Mathf.Round(frameCount / dt);
  89.             frameCount = 0;
  90.             dt -= 1.0f / fpsDisplayRate;
  91.                  }
  92.         /* Ensure that the cursor is locked into the screen */
  93.         if (Cursor.lockState != CursorLockMode.Locked) {
  94.             if (Input.GetButtonDown("Fire1"))
  95.                 Cursor.lockState = CursorLockMode.Locked;
  96.         }
  97.  
  98.         /* Camera rotation stuff, mouse controls this shit */
  99.         rotX -= Input.GetAxisRaw("Mouse Y") * xMouseSensitivity * 0.02f;
  100.         rotY += Input.GetAxisRaw("Mouse X") * yMouseSensitivity * 0.02f;
  101.  
  102.         // Clamp the X rotation
  103.         if(rotX < -90)
  104.             rotX = -90;
  105.         else if(rotX > 90)
  106.             rotX = 90;
  107.  
  108.         this.transform.rotation = Quaternion.Euler(0, rotY, 0); // Rotates the collider
  109.         playerView.rotation     = Quaternion.Euler(rotX, rotY, 0); // Rotates the camera
  110.  
  111.        
  112.  
  113.         /* Movement, here's the important part */
  114.         QueueJump();
  115.         if(_controller.isGrounded)
  116.             GroundMove();
  117.         else if(!_controller.isGrounded)
  118.             AirMove();
  119.  
  120.         // Move the controller
  121.         _controller.Move(playerVelocity * Time.deltaTime);
  122.  
  123.         /* Calculate top velocity */
  124.         Vector3 udp = playerVelocity;
  125.         udp.y = 0.0f;
  126.         if(playerVelocity.magnitude > playerTopVelocity)
  127.             playerTopVelocity = playerVelocity.magnitude;
  128.  
  129.         //Need to move the camera after the player has been moved because otherwise the camera will clip the player if going fast enough and will always be 1 frame behind.
  130.         // Set the camera's position to the transform
  131.         playerView.position = new Vector3(
  132.             transform.position.x,
  133.             transform.position.y + playerViewYOffset,
  134.             transform.position.z);
  135.     }
  136.  
  137.      /*******************************************************************************************************\
  138.     |* MOVEMENT
  139.     \*******************************************************************************************************/
  140.  
  141.     /**
  142.      * Sets the movement direction based on player input
  143.      */
  144.     private void SetMovementDir()
  145.     {
  146.         _cmd.forwardMove = Input.GetAxisRaw("Vertical");
  147.         _cmd.rightMove   = Input.GetAxisRaw("Horizontal");
  148.     }
  149.  
  150.     /**
  151.      * Queues the next jump just like in Q3
  152.      */
  153.     private void QueueJump()
  154.     {
  155.         if(Input.GetButtonDown("Jump") && !wishJump)
  156.             wishJump = true;
  157.         if(Input.GetButtonUp("Jump"))
  158.             wishJump = false;
  159.     }
  160.  
  161.     /**
  162.      * Execs when the player is in the air
  163.     */
  164.     private void AirMove()
  165.     {
  166.         Vector3 wishdir;
  167.         float wishvel = airAcceleration;
  168.         float accel;
  169.  
  170.         float scale = CmdScale();
  171.  
  172.         SetMovementDir();
  173.  
  174.         wishdir =  new Vector3(_cmd.rightMove, 0, _cmd.forwardMove);
  175.         wishdir = transform.TransformDirection(wishdir);
  176.  
  177.         float wishspeed = wishdir.magnitude;
  178.         wishspeed *= moveSpeed;
  179.  
  180.         wishdir.Normalize();
  181.         moveDirectionNorm = wishdir;
  182.         wishspeed *= scale;
  183.  
  184.         // CPM: Aircontrol
  185.         float wishspeed2 = wishspeed;
  186.         if (Vector3.Dot(playerVelocity, wishdir) < 0)
  187.             accel = airDecceleration;
  188.         else
  189.             accel = airAcceleration;
  190.         // If the player is ONLY strafing left or right
  191.         if(_cmd.forwardMove == 0 && _cmd.rightMove != 0)
  192.         {
  193.             if(wishspeed > sideStrafeSpeed)
  194.                 wishspeed = sideStrafeSpeed;
  195.             accel = sideStrafeAcceleration;
  196.         }
  197.  
  198.         Accelerate(wishdir, wishspeed, accel);
  199.         if(airControl > 0)
  200.             AirControl(wishdir, wishspeed2);
  201.         // !CPM: Aircontrol
  202.  
  203.         // Apply gravity
  204.         playerVelocity.y -= gravity * Time.deltaTime;
  205.     }
  206.  
  207.     /**
  208.      * Air control occurs when the player is in the air, it allows
  209.      * players to move side to side much faster rather than being
  210.      * 'sluggish' when it comes to cornering.
  211.      */
  212.     private void AirControl(Vector3 wishdir, float wishspeed)
  213.     {
  214.         float zspeed;
  215.         float speed;
  216.         float dot;
  217.         float k;
  218.  
  219.         // Can't control movement if not moving forward or backward
  220.         if(Mathf.Abs(_cmd.forwardMove) < 0.001 || Mathf.Abs(wishspeed) < 0.001)
  221.             return;
  222.         zspeed = playerVelocity.y;
  223.         playerVelocity.y = 0;
  224.         /* Next two lines are equivalent to idTech's VectorNormalize() */
  225.         speed = playerVelocity.magnitude;
  226.         playerVelocity.Normalize();
  227.  
  228.         dot = Vector3.Dot(playerVelocity, wishdir);
  229.         k = 32;
  230.         k *= airControl * dot * dot * Time.deltaTime;
  231.  
  232.         // Change direction while slowing down
  233.         if (dot > 0)
  234.         {
  235.             playerVelocity.x = playerVelocity.x * speed + wishdir.x * k;
  236.             playerVelocity.y = playerVelocity.y * speed + wishdir.y * k;
  237.             playerVelocity.z = playerVelocity.z * speed + wishdir.z * k;
  238.  
  239.             playerVelocity.Normalize();
  240.             moveDirectionNorm = playerVelocity;
  241.         }
  242.  
  243.         playerVelocity.x *= speed;
  244.         playerVelocity.y = zspeed; // Note this line
  245.         playerVelocity.z *= speed;
  246.     }
  247.  
  248.     /**
  249.      * Called every frame when the engine detects that the player is on the ground
  250.      */
  251.     private void GroundMove()
  252.     {
  253.         Vector3 wishdir;
  254.  
  255.         // Do not apply friction if the player is queueing up the next jump
  256.         if (!wishJump)
  257.             ApplyFriction(1.0f);
  258.         else
  259.             ApplyFriction(0);
  260.  
  261.         float scale = CmdScale();
  262.  
  263.         wishdir = new Vector3(_cmd.rightMove, 0, _cmd.forwardMove);
  264.         wishdir = transform.TransformDirection(wishdir);
  265.         wishdir.Normalize();
  266.         moveDirectionNorm = wishdir;
  267.  
  268.         var wishspeed = wishdir.magnitude;
  269.         wishspeed *= moveSpeed;
  270.  
  271.         Accelerate(wishdir, wishspeed, runAcceleration);
  272.  
  273.         // Reset the gravity velocity
  274.         playerVelocity.y = 0;
  275.  
  276.         if(wishJump)
  277.         {
  278.             playerVelocity.y = jumpSpeed;
  279.             wishJump = false;
  280.         }
  281.     }
  282.  
  283.     /**
  284.      * Applies friction to the player, called in both the air and on the ground
  285.      */
  286.     private void ApplyFriction(float t)
  287.     {
  288.         Vector3 vec = playerVelocity; // Equivalent to: VectorCopy();
  289.         float speed;
  290.         float newspeed;
  291.         float control;
  292.         float drop;
  293.  
  294.         vec.y = 0.0f;
  295.         speed = vec.magnitude;
  296.         drop = 0.0f;
  297.  
  298.         /* Only if the player is on the ground then apply friction */
  299.         if(_controller.isGrounded)
  300.         {
  301.             control = speed < runDeacceleration ? runDeacceleration : speed;
  302.             drop = control * friction * Time.deltaTime * t;
  303.         }
  304.  
  305.         newspeed = speed - drop;
  306.         playerFriction = newspeed;
  307.         if(newspeed < 0)
  308.             newspeed = 0;
  309.         if(speed > 0)
  310.             newspeed /= speed;
  311.  
  312.         playerVelocity.x *= newspeed;
  313.         playerVelocity.z *= newspeed;
  314.     }
  315.  
  316.     private void Accelerate(Vector3 wishdir, float wishspeed, float accel)
  317.     {
  318.         float addspeed;
  319.         float accelspeed;
  320.         float currentspeed;
  321.  
  322.         currentspeed = Vector3.Dot(playerVelocity, wishdir);
  323.         addspeed = wishspeed - currentspeed;
  324.         if(addspeed <= 0)
  325.             return;
  326.         accelspeed = accel * Time.deltaTime * wishspeed;
  327.         if(accelspeed > addspeed)
  328.             accelspeed = addspeed;
  329.  
  330.         playerVelocity.x += accelspeed * wishdir.x;
  331.         playerVelocity.z += accelspeed * wishdir.z;
  332.     }
  333.  
  334.     private void OnGUI()
  335.     {
  336.         GUI.Label(new Rect(0, 0, 400, 100), "FPS: " + fps, style);
  337.         var ups = _controller.velocity;
  338.         ups.y = 0;
  339.         GUI.Label(new Rect(0, 15, 400, 100), "Speed: " + Mathf.Round(ups.magnitude * 100) / 100 + "ups", style);
  340.         GUI.Label(new Rect(0, 30, 400, 100), "Top Speed: " + Mathf.Round(playerTopVelocity * 100) / 100 + "ups", style);
  341.     }
  342.  
  343.     /*
  344.     ============
  345.     PM_CmdScale
  346.     Returns the scale factor to apply to cmd movements
  347.     This allows the clients to use axial -127 to 127 values for all directions
  348.     without getting a sqrt(2) distortion in speed.
  349.     ============
  350.     */
  351.     private float CmdScale()
  352.     {
  353.         int max;
  354.         float total;
  355.         float scale;
  356.  
  357.         max = (int)Mathf.Abs(_cmd.forwardMove);
  358.         if(Mathf.Abs(_cmd.rightMove) > max)
  359.             max = (int)Mathf.Abs(_cmd.rightMove);
  360.         if(max <= 0)
  361.             return 0;
  362.  
  363.         total = Mathf.Sqrt(_cmd.forwardMove * _cmd.forwardMove + _cmd.rightMove * _cmd.rightMove);
  364.         scale = moveSpeed * max / (moveScale * total);
  365.  
  366.         return scale;
  367.     }
  368. }
RAW Paste Data
Pastebin PRO WINTER Special!
Get 40% OFF Pastebin PRO accounts!
Top