Advertisement
Guest User

Quake-like movement system

a guest
Jul 11th, 2016
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.24 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.UI;
  4. using System.Collections.Generic;
  5.  
  6. public class cl_kveik: MonoBehaviour {
  7.     // Player view stuff
  8.     public float playerViewYOffset;
  9.     private Transform playerView;
  10.     private Transform tform;
  11.     private float sensitivity;
  12.     private float invert;
  13.  
  14.     public float PhysGravity = 7.5f;
  15.     public float gravity = 16f;     // For player
  16.     public float friction = 3.0f;   // Friction applied to player on the ground
  17.     private float frictionMulti;    // Friction multiplier (needed?)
  18.  
  19.     // Movement stuff
  20.     [Header("Movement")]
  21.     public float moveSpeed              = 3.2f;
  22.     public float runAcceleration        = 20.0f;
  23.     public float runDeacceleration      = 5.0f;
  24.     //public float airAcceleration      = 2.0f;
  25.     //public float airDeacceleration    = 2.0f;
  26.     //public float airControl           = 0.3f;
  27.     public float sideStrafeAcceleration = 9000f;
  28.     public float sideStrafeSpeed        = 0.2f;
  29.     public float jumpSpeed              = 6.0f;
  30.     public float moveScale              = 1.0f;
  31.  
  32.  
  33.  
  34.     // Ramp stuff
  35.     [Header("Ramps")]
  36.     public float downLandBoost          = 0.5f;
  37.     public float downJumpBoost          = 0.4f;
  38.     public float upJumpBoost            = 0.15f;
  39.     public float upSlow                 = 0.3f;
  40.  
  41.     public AudioClip[] jumpSounds;
  42.  
  43.     // Camera rotationals
  44.     private float rotX;
  45.     private float rotY;
  46.  
  47.     private Vector3 moveDirection;
  48.     private Vector3 playerVelocity;
  49.  
  50.     // If true then the player is fully on the ground
  51.     private bool grounded = false;
  52.  
  53.     // Players can queue the next jump just before he hits the ground
  54.     private bool wishJump = false;
  55.     RaycastHit hit;
  56.  
  57.     private float playerFriction;
  58.     private CharacterController controller;
  59.     private Vector3 playerSpawnPos;
  60.     private Quaternion playerSpawnRot;
  61.     private Vector3 udp;
  62.  
  63.     public Text speed;
  64.     public Text drag;
  65.     public Text sensi;
  66.  
  67.     float wishvel;
  68.     float wishspeed, wishspeedcpm;
  69.     float accel;
  70.  
  71.     Vector3 colNormal;
  72.  
  73.     private float forwardmove;
  74.     private float rightmove;
  75.     private float upmove;
  76.  
  77.     // WEAPON STUFF
  78.     public float expKnockback;      // Power of knockback on player
  79.     [HideInInspector]
  80.     public List<Vector3> knockback; // All the knockbacks
  81.     [HideInInspector]
  82.     public Vector3 gaussKnockback;  // Power of gauss cannon kick
  83.     void Start() {
  84.         Physics.gravity = new Vector3(0, -PhysGravity, 0);
  85.         List<Vector3> knockback = new List<Vector3>();
  86.         tform = GetComponent<Transform>();
  87.         playerView = Camera.main.transform;
  88.         controller = GetComponent<CharacterController>();
  89.         //cmd = new Cmd();
  90.         rotY = 0.0f;
  91.         Cursor.lockState = CursorLockMode.Locked;
  92.         Cursor.visible = false;
  93.  
  94.         // Set sensitivity
  95.         if (PlayerPrefs.HasKey("kveiksensi")) sensitivity = PlayerPrefs.GetFloat("kveiksensi");
  96.         else { sensitivity = 1f; PlayerPrefs.SetFloat("kveiksensi", 1f); }
  97.         // Set invert
  98.         if (PlayerPrefs.HasKey("kveikinvert")) invert = PlayerPrefs.GetFloat("kveikinvert");
  99.         else { invert = -1f; PlayerPrefs.SetFloat("kveikinvert", -1f); }
  100.     }
  101.     void FixedUpdate() {
  102.         if (Input.GetAxis("sensiChange") != 0) {
  103.             sensitivity += Input.GetAxis("sensiChange");
  104.             PlayerPrefs.SetFloat("kveiksensi", sensitivity);
  105.         }
  106.         sensi.text = sensitivity.ToString("f3");
  107.     }
  108.     void Update() {
  109.         if (Input.GetButtonDown("Invert")) {
  110.             invert *= -1;
  111.             PlayerPrefs.SetFloat("kveikinvert", invert);
  112.         }
  113.         // Check ground below
  114.         Ray ray = new Ray(tform.position, -tform.up);
  115.        
  116.         Physics.Raycast(ray, out hit, 1f);
  117.         Debug.DrawLine(hit.point, hit.normal.normalized);
  118.         forwardmove = Input.GetAxisRaw("Vertical");
  119.         rightmove = Input.GetAxisRaw("Horizontal");
  120.  
  121.         /* Camera rotation stuff, mouse controls this shit */
  122.         rotX += Input.GetAxisRaw("Mouse Y") * sensitivity * invert;
  123.         rotY += Input.GetAxisRaw("Mouse X") * sensitivity;
  124.         // Clamp the X rotation
  125.         if (rotX < -90)
  126.             rotX = -90;
  127.         else if (rotX > 90)
  128.             rotX = 90;
  129.  
  130.         tform.rotation = Quaternion.Euler(0, rotY, 0); // Rotates the collider
  131.         playerView.rotation = Quaternion.Euler(rotX, rotY, 0);
  132.  
  133.         // Movement
  134.         QueueJump();
  135.         if (controller.isGrounded) GroundMove();
  136.         else {
  137.             AirMove();
  138.  
  139.         }
  140.  
  141.         //if (Input.GetButtonDown("Jump")) playerVelocity.y = jumpSpeed; // This is just for testing
  142.  
  143.         // Move the controller
  144.         if (gaussKnockback.magnitude > 0) {
  145.             playerVelocity += gaussKnockback;
  146.             gaussKnockback = Vector3.zero;
  147.         }
  148.  
  149.         /* This is where you check whether the rocket object that has the script obj_bullet.cs
  150.          * has added any knockback vectors into the list. If so, you add them up to the total knockback
  151.          * allowing the player to be affected by multiple knockbacks at once. */
  152.         for (int i = 0; i < knockback.Count; i++) {
  153.             Vector3 test = (knockback[i].normalized * Mathf.Clamp(3 - knockback[i].magnitude, 0, 1)) * expKnockback;
  154.             playerVelocity += test;
  155.             drag.text = test.magnitude.ToString();
  156.             knockback.RemoveAt(i);
  157.         }
  158.         controller.Move(playerVelocity * Time.deltaTime);
  159.  
  160.     }
  161.     void Accelerate(Vector3 wishdir, float wishspeed, float accel) {
  162.         float addspeed;
  163.         float accelspeed;
  164.         float currentspeed;
  165.  
  166.         // This is from Quake source code, not mew's stuff
  167.  
  168.         currentspeed = Vector3.Dot(playerVelocity, wishdir);
  169.         addspeed = wishspeed - currentspeed;
  170.         if (addspeed <= 0) return;
  171.         accelspeed = accel * wishspeed * Time.deltaTime;
  172.         if (accelspeed > addspeed) accelspeed = addspeed;
  173.  
  174.         playerVelocity.x += accelspeed * wishdir.x;
  175.         playerVelocity.z += accelspeed * wishdir.z;
  176.         playerVelocity.y += accelspeed * wishdir.y;
  177.     }
  178.     // Happens when the player is in the air
  179.     void AirMove() {
  180.         Vector3 wishdir;
  181.         float accel;
  182.  
  183.         float scale = CmdScale();
  184.  
  185.         wishdir = new Vector3(rightmove, 0, forwardmove);
  186.         wishdir = transform.TransformDirection(wishdir);
  187.  
  188.         wishspeed = wishdir.magnitude * moveSpeed;// *scale;
  189.         wishdir.Normalize();
  190.  
  191.         if (wishspeed > sideStrafeSpeed) wishspeed = sideStrafeSpeed;
  192.        
  193.         float turnAngle = Vector3.Dot(wishdir, new Vector3(playerVelocity.x, 0, playerVelocity.z).normalized * 1.3f);
  194.         accel = sideStrafeAcceleration * (1f - Mathf.Clamp(Mathf.Abs(turnAngle), 0, 0.98f));
  195.         //drag.text = (turnAngle * turnAngle).ToString();
  196.         Accelerate(wishdir, wishspeed, accel);
  197.  
  198.         //playerVelocity += gravity * Vector3.down * Time.deltaTime;
  199.         playerVelocity.y -= gravity * Time.deltaTime;
  200.  
  201.         if (controller.collisionFlags == CollisionFlags.Above && playerVelocity.y > 0)
  202.             playerVelocity.y -= 100f * Time.deltaTime ;
  203.     }
  204.  
  205.    
  206.     void GroundMove() {
  207.         Vector3 wishdir;
  208.  
  209.         // Do not apply friction if the player is queuing up the next jump
  210.         if (!wishJump) {
  211.             frictionMulti = 1.0f;
  212.             // This adds the delay to friction, so you can do the ground accel stuff between jumps
  213.             Invoke("ApplyFriction", 0.2f);
  214.         } else {
  215.             frictionMulti = 0.0f;
  216.             ApplyFriction();
  217.         }
  218.  
  219.         wishdir = new Vector3(rightmove, 0, forwardmove);
  220.         wishdir = transform.TransformDirection(wishdir);
  221.         wishdir.Normalize();
  222.  
  223.         float wishspeed = wishdir.magnitude * moveSpeed;
  224.  
  225.         Accelerate(wishdir, wishspeed, runAcceleration);
  226.  
  227.         // THEJUMP (this is by mew, a decent ramp jump functionality)
  228.         if (wishJump) {
  229.             wishJump = false;
  230.  
  231.             float oldYvel = playerVelocity.y;
  232.             Vector2 inVelHor = new Vector2(playerVelocity.x, playerVelocity.z).normalized;
  233.             Vector2 hitNormalHor = new Vector2(hit.normal.x, hit.normal.z);
  234.             float rampDir = Vector3.Dot(inVelHor, hitNormalHor);
  235.  
  236.             if (playerVelocity.y < 0) playerVelocity.y = 0;
  237.  
  238.             Vector3 horVel = new Vector3(playerVelocity.x, 0, playerVelocity.z);
  239.  
  240.             if (rampDir > 0) {
  241.                 playerVelocity += horVel.normalized * Mathf.Abs(oldYvel) * rampDir * downLandBoost;
  242.             } else if (rampDir < 0)
  243.                 playerVelocity -= horVel.normalized * Mathf.Abs(oldYvel) * Mathf.Abs(rampDir) * upSlow;
  244.  
  245.             playerVelocity.y = jumpSpeed * (1 - rampDir * playerVelocity.magnitude * upJumpBoost)
  246.                 + rampDir * Mathf.Abs(oldYvel) * downJumpBoost;
  247.         } else playerVelocity.y = 0f;
  248.        
  249.  
  250.  
  251.     }
  252.  
  253.     // Applies friction to the player, called in both the air and on the ground
  254.     void ApplyFriction() {
  255.         Vector3 vec = playerVelocity;
  256.         float speed;
  257.         float newspeed;
  258.         float control;
  259.         float drop;
  260.  
  261.         vec.y = 0.0f;
  262.         speed = vec.magnitude;
  263.         drop = 0.0f;
  264.  
  265.         // Apply friction only if the player is on the ground
  266.         if (controller.isGrounded) {
  267.             control = speed < runDeacceleration ? runDeacceleration : speed;
  268.             drop = control * friction * frictionMulti * Time.deltaTime;
  269.         }
  270.         newspeed = speed - drop;
  271.         playerFriction = newspeed;
  272.         if (newspeed < 0) newspeed = 0;
  273.         if (speed != 0)
  274.             newspeed /= speed;
  275.  
  276.         playerVelocity.x *= newspeed;
  277.         playerVelocity.z *= newspeed;
  278.         //playerVelocity.y *= newspeed;
  279.     }
  280.     void QueueJump() {
  281.         if (Input.GetButton("Jump") && !wishJump) wishJump = true;
  282.         if (Input.GetButtonUp("Jump")) wishJump = false;
  283.     }
  284.  
  285.     private float CmdScale() {
  286.         // This is from Quake source code, I have no idea what this does. - mew
  287.         int max;
  288.         float total;
  289.         float scale;
  290.  
  291.         max = (int)Mathf.Abs(forwardmove);
  292.         if ((int)Mathf.Abs(rightmove) > max) {
  293.             max = (int)Mathf.Abs(rightmove);
  294.         }
  295.         if ((int)Mathf.Abs(upmove) > max) {
  296.             max = (int)Mathf.Abs(upmove);
  297.         }
  298.         if (max <= 0) {
  299.             return 0;
  300.         }
  301.  
  302.         total = Mathf.Sqrt(forwardmove * forwardmove + rightmove * rightmove);
  303.         scale = moveSpeed * max / (moveScale * total);
  304.  
  305.         return scale;
  306.     }
  307.     void OnGUI() {
  308.         Vector3 ups;
  309.  
  310.         ups = controller.velocity;
  311.         ups.y = 0;
  312.  
  313.         speed.text = (ups * 100).magnitude.ToString("f0");
  314.        
  315.     }
  316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement