using System.Collections; using System.Collections.Generic; using UnityEngine; public class FPController : MonoBehaviour { public GameObject cam; public Animator anim; public AudioSource[] footsteps; public AudioSource jump; public AudioSource land; float speed = 0.1f; float Xsensitivity = 2; float Ysensitivity = 2; float MinimumX = -90; float MaximumX = 90; Rigidbody rb; CapsuleCollider capsule; Quaternion cameraRot; Quaternion characterRot; bool cursorIsLocked = true; bool lockCursor = true; float x; float z; bool playingWalking = false; bool previouslyGrounded = true; // Start is called before the first frame update void Start() { rb = this.GetComponent(); capsule = this.GetComponent(); cameraRot = cam.transform.localRotation; characterRot = this.transform.localRotation; } // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.F)) anim.SetBool("arm", !anim.GetBool("arm")); if (Mathf.Abs(x) > 0 || Mathf.Abs(z) > 0) { if (!anim.GetBool("walking")) { anim.SetBool("walking", true); InvokeRepeating("PlayFootStepAudio", 0, 0.4f); } } else if (anim.GetBool("walking")) { anim.SetBool("walking", false); CancelInvoke("PlayFootStepAudio"); playingWalking = false; } bool grounded = IsGrounded(); if (Input.GetKeyDown(KeyCode.Space) && grounded) { rb.AddForce(0, 300, 0); jump.Play(); if (anim.GetBool("walking")) { CancelInvoke("PlayFootStepAudio"); playingWalking = false; } } else if (!previouslyGrounded && grounded) { land.Play(); } previouslyGrounded = grounded; } void PlayFootStepAudio() { AudioSource audioSource = new AudioSource(); int n = Random.Range(1, footsteps.Length); audioSource = footsteps[n]; audioSource.Play(); footsteps[n] = footsteps[0]; footsteps[0] = audioSource; playingWalking = true; } void FixedUpdate() { float yRot = Input.GetAxis("Mouse X") * Ysensitivity; float xRot = Input.GetAxis("Mouse Y") * Xsensitivity; cameraRot *= Quaternion.Euler(-xRot, 0, 0); characterRot *= Quaternion.Euler(0, yRot, 0); cameraRot = ClampRotationAroundXAxis(cameraRot); this.transform.localRotation = characterRot; cam.transform.localRotation = cameraRot; x = Input.GetAxis("Horizontal") * speed; z = Input.GetAxis("Vertical") * speed; transform.position += this.transform.forward * z + cam.transform.right * x; UpdateCursorLock(); } Quaternion ClampRotationAroundXAxis(Quaternion q) { q.x /= q.w; q.y /= q.w; q.z /= q.w; q.w = 1.0f; float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan(q.x); angleX = Mathf.Clamp(angleX, MinimumX, MaximumX); q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * angleX); return q; } bool IsGrounded() { RaycastHit hitInfo; if (Physics.SphereCast(transform.position, capsule.radius/2f, Vector3.down, out hitInfo, (capsule.height / 2f) - capsule.radius + 0.1f)) { return true; } return false; } void OnCollisionEnter(Collision col) { if (IsGrounded()) { if (anim.GetBool("walking") && !playingWalking) { InvokeRepeating("PlayFootStepAudio", 0, 0.4f); } } } public void SetCursorLock(bool value) { lockCursor = value; if (!lockCursor) { Cursor.lockState = CursorLockMode.None; Cursor.visible = true; } } public void UpdateCursorLock() { if (lockCursor) InternalLockUpdate(); } public void InternalLockUpdate() { if (Input.GetKeyUp(KeyCode.Escape)) cursorIsLocked = false; else if (Input.GetMouseButtonUp(0)) cursorIsLocked = true; if (cursorIsLocked) { Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; } else if (!cursorIsLocked) { Cursor.lockState = CursorLockMode.None; Cursor.visible = true; } } }