unity-abgabe2/Assets/FPController/Controls.cs
2021-04-25 16:20:23 +02:00

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);
}
}