241 lines
7.1 KiB
C#
241 lines
7.1 KiB
C#
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<CharacterController>();
|
|
playerInput = this.GetComponent<PlayerInput>();
|
|
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");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retuns a value from 0 to 1 of how much of the force should be applyed at the current progress of the action
|
|
/// </summary>
|
|
/// <param name="progress"></param>
|
|
/// <returns></returns>
|
|
private float sinApply(float progress){
|
|
return (float)(Math.Sin(progress * Math.PI) / Math.PI);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by PlayerInput when Move value change.
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
public void OnMove(InputValue value)
|
|
{
|
|
this.currentMotion = value.Get<Vector2>();
|
|
}
|
|
|
|
public void OnAttack(InputValue value){
|
|
var instantiatedProjectile = Instantiate(projectile, this.playerCameraObject.transform.position, Quaternion.identity);
|
|
var rig = instantiatedProjectile.GetComponent<Rigidbody>();
|
|
rig.velocity = this.playerCameraObject.transform.forward * 35f;
|
|
Physics.IgnoreCollision(instantiatedProjectile.GetComponent<SphereCollider>(), this.GetComponent<Collider>());
|
|
}
|
|
|
|
public void OnJump(InputValue value)
|
|
{
|
|
if (this.controller.isGrounded){
|
|
this.doJump = true;
|
|
this.canDoubleJump = true;
|
|
}else if (this.canDoubleJump){
|
|
this.doJump = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by PlayerInput when Look value change.
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
public void OnLook(InputValue value)
|
|
{
|
|
var camMovement = value.Get<Vector2>();
|
|
|
|
if (this.useGamepad){
|
|
this.currentLook = camMovement;
|
|
}else{
|
|
ApplyLookVector(camMovement,cameraSensitivityMouse);
|
|
}
|
|
}
|
|
|
|
public void OnDash(InputValue value){
|
|
this.doDash = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by PlayerInput when the user starts using mouse or gamepad.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clamps an angle.
|
|
/// </summary>
|
|
/// <param name="angle"></param>
|
|
/// <param name="from">e.g. -45</param>
|
|
/// <param name="to">e.g. 45</param>
|
|
/// <returns>Clamped angle from 0 to 360</returns>
|
|
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);
|
|
}
|
|
|
|
|
|
}
|
|
|