using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.UI; public class Controls : MonoBehaviour { public float playerSpeed = 0.2f; public float cameraSensitivityMouse = 0.01f; public float cameraSensitivityGamepad = 2f; public float upperAngleClamp = 60; public float lowerAngleClamp = -60; private Vector2 currentMotion = Vector2.zero; private GameObject playerCameraObject; private CharacterController controller; private PlayerInput playerInput; private Vector2 currentLook = Vector2.zero; private bool useGamepad = false; private bool doJump = false; private bool canDoubleJump = true; private float timeJump = -1f; private bool doDash = false; private float timeDash = -1f; private Vector3 hookPos; private bool isHooked = false; private float timeJumpPad = -1f; public int hp = 100; public Text hpText; public GameObject projectile; void Start() { controller = this.GetComponent(); playerInput = this.GetComponent(); playerCameraObject = this.transform.Find("Camera").gameObject; Cursor.lockState = CursorLockMode.Locked; } void FixedUpdate() { //Movement Vector3 forward = this.transform.TransformDirection(Vector3.forward); Vector3 strafe = this.transform.TransformDirection(Vector3.right); float vertical = 0f; if (!this.controller.isGrounded && !this.isHooked){ vertical += Physics.gravity.y * Time.fixedDeltaTime; } if (this.doJump){ this.doJump = false; this.canDoubleJump = false; this.timeJump = 0f; this.isHooked = false; } if (this.controller.isGrounded){ this.canDoubleJump = true; } if (this.timeJump >= 0f){ if (this.timeJump >= 0.5f) { this.timeJump = -1f; }else{ var jumpProgress = this.timeJump / 0.5f; vertical += (sinApply(jumpProgress) * 1.4f); this.timeJump += Time.fixedDeltaTime; } } if (this.timeJumpPad >= 0f){ if (this.timeJumpPad >= 0.8f){ this.timeJumpPad = -1f; }else{ var progress = this.timeJumpPad / 0.8f; vertical += sinApply(progress) * 4f; this.timeJumpPad += Time.fixedDeltaTime; } } var movement = (((strafe * this.currentMotion.x) + (forward * this.currentMotion.y)) * this.playerSpeed) + (Vector3.up * vertical); if (this.doDash){ this.isHooked = false; this.doDash = false; this.timeDash = 0f; } if (this.timeDash >= 0f){ if (this.timeDash >= 0.3f){ this.timeDash = -1f; }else{ var progress = this.timeDash / 0.3f; movement += (forward * progress); this.timeDash += Time.fixedDeltaTime; } } if (this.isHooked){ // Apply force in the direction of the hook pos var dirVec = this.hookPos - this.transform.position; if (dirVec.magnitude >= 1.5f){ movement += Vector3.Normalize(dirVec)* 1.1f; }else{ this.isHooked = false; } } this.controller.Move(movement); // Look if gamepad if (this.useGamepad){ ApplyLookVector(this.currentLook,cameraSensitivityGamepad); } } private void hook(){ Ray ray = new Ray(this.playerCameraObject.transform.position, playerCameraObject.transform.TransformDirection(Vector3.forward)); RaycastHit hit; if (Physics.Raycast(ray, out hit, 100f)){ hookPos = hit.point; isHooked = true; } } public void OnHook(InputValue value){ hook(); } public void Damaged(){ this.hpText.text = this.hp.ToString(); if (this.hp <= 0){ // Player died // TODO: death message Debug.Log("dead"); } } /// /// Retuns a value from 0 to 1 of how much of the force should be applyed at the current progress of the action /// /// /// private float sinApply(float progress){ return (float)(Math.Sin(progress * Math.PI) / Math.PI); } /// /// Called by PlayerInput when Move value change. /// /// public void OnMove(InputValue value) { this.currentMotion = value.Get(); } public void OnAttack(InputValue value){ var instantiatedProjectile = Instantiate(projectile, this.playerCameraObject.transform.position, Quaternion.identity); var rig = instantiatedProjectile.GetComponent(); rig.velocity = this.playerCameraObject.transform.forward * 35f; Physics.IgnoreCollision(instantiatedProjectile.GetComponent(), this.GetComponent()); } public void OnJump(InputValue value) { if (this.controller.isGrounded){ this.doJump = true; this.canDoubleJump = true; }else if (this.canDoubleJump){ this.doJump = true; } } /// /// Called by PlayerInput when Look value change. /// /// public void OnLook(InputValue value) { var camMovement = value.Get(); if (this.useGamepad){ this.currentLook = camMovement; }else{ ApplyLookVector(camMovement,cameraSensitivityMouse); } } public void OnDash(InputValue value){ this.doDash = true; } /// /// Called by PlayerInput when the user starts using mouse or gamepad. /// public void OnControlsChanged(){ this.useGamepad = playerInput.currentControlScheme == "Gamepad"; } public void JumpPad(){ this.timeJumpPad = 0f; } void ApplyLookVector(Vector2 vector,float sensitivity){ // Left right looking this.transform.Rotate(Vector3.up * vector.x * sensitivity); // Up down looking Vector3 rot = playerCameraObject.transform.rotation.eulerAngles + new Vector3(-vector.y * sensitivity, 0f, 0f); rot.x = ClampAngle(rot.x, this.lowerAngleClamp, this.upperAngleClamp); playerCameraObject.transform.eulerAngles = rot; } /// /// Clamps an angle. /// /// /// e.g. -45 /// e.g. 45 /// Clamped angle from 0 to 360 float ClampAngle(float angle, float from, float to) { if (angle < 0f) angle = 360 + angle; if (angle > 180f) return Mathf.Max(angle, 360 + from); return Mathf.Min(angle, to); } }