NanoPark/Assets/Scripts/PlayerController.cs
2022-07-16 11:38:06 +05:30

361 lines
11 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Mirror;
using UnityEngine;
using UnityEngine.Audio;
public class PlayerController : NetworkBehaviour
{
public Rigidbody2D rigidbody;
public SpriteRenderer sprite;
public bool invertSprite;
public Animator animator;
public LayerMask groundLayerMask;
// public float drownedDepth;
public bool isGrounded = true;
public bool isSwimming = false;
public Transform groundChecker;
public Vector2 gravity;
public float buoyantForce;
public float buoyantSpd;
public float moveSpeed = 1;
public float jumpForce = 10;
public float jumpDuration = 0.2f;
public AudioClip jumpSFX;
float jumpT = 0;
public bool listenToInput = true;
public bool inDoor = false;
public bool insideDoor = false;
bool enteringDoor = false;
public Vector3 neighboursDetectorSize;
void Start()
{
jumpT = jumpDuration;
if (!isServer)
{
rigidbody.simulated = false;
}
}
[SyncVar]
bool _grounded = false;
bool jumpReleased = true;
[HideInInspector]
public bool inWater;
[SyncVar]
public bool InteractionKeyPressed;
[SyncVar]
public bool JumpKeyPressed;
[SyncVar]
public float HorizontalAxis;
public float moveInput = 0;
[Command]
void CmdUpdateInput(float _horizontal, bool jump, bool interact)
{
HorizontalAxis = _horizontal;
JumpKeyPressed = jump;
InteractionKeyPressed = interact;
}
void ListenInput()
{
HorizontalAxis = 0;
if (Input.GetKey(InputManager.data().leftInput)) { HorizontalAxis = -1; } else if (Input.GetKey(InputManager.data().rightInput)) { HorizontalAxis = 1; }
JumpKeyPressed = Input.GetKey(InputManager.data().jumpInput);
InteractionKeyPressed = Input.GetKey(InputManager.data().interactingKey);
}
void FixedUpdate()
{
if (isLocalPlayer)
{ // <-- First Listen to inputs no matter in server or not, but if the lcoal player
ListenInput();
}
Movement();//SImulate everywhere
if (isServer)
{ //Simulate physics on server
RpcUpdatePosition(transform.position, HorizontalAxis, rigidbody.velocity, NetworkTime.time);
}
else
{
if (isLocalPlayer)
{ //I aint the server, but the local player. I move!
CmdUpdateInput(HorizontalAxis, JumpKeyPressed, InteractionKeyPressed);
}
}
}
[ClientRpc]
void RpcUpdatePosition(Vector3 position, float horizontalAxis, Vector3 velocity, double time)
{
double latency = NetworkTime.time - time;
int framesSkipped = Mathf.FloorToInt((float)(latency * 50));
Debug.Log($"Missed {framesSkipped} frames due to network");
if (Vector3.Distance(transform.position, position) > 0.15f)
{
transform.position = position;
rigidbody.velocity = velocity;
}
// if(isLocalPlayer){
// //Client prediction
// if(Vector3.Distance(transform.position, position) > 0.5f){
// transform.position = position;
// rigidbody.velocity= velocity;
// }
// }else{
// //Just update the position
// transform.position = Vector3.Lerp(transform.position, position, 0.1f);
// rigidbody.velocity=velocity;
// }
}
void Movement()
{
isGrounded = getGrounded();
if (_grounded != isGrounded)
{
if (isGrounded)
{
OnLand();
}
else
{
OnFly();
}
_grounded = isGrounded;
}
if (isSwimming)
{
rigidbody.velocity = new Vector2(rigidbody.velocity.x, Mathf.Lerp(rigidbody.velocity.y, buoyantForce, buoyantSpd));
if ((JumpKeyPressed))
{
rigidbody.velocity = new Vector2(rigidbody.velocity.x, jumpForce / 12f);
}
}
else
{
gravity = new Vector2(gravity.x, 0);
}
//Gravity Application
rigidbody.AddForce(gravity);
//Update In-Air value on animation
animator.SetBool("inAir", !isGrounded);
animator.SetBool("isOnWater", inWater);
// if (GameManager.isPaused) { HorizontalAxis = 0; }
//Move according to input
//Exit the door
if (enteringDoor && !InteractionKeyPressed)
{
enteringDoor = false;
}
if (insideDoor && !enteringDoor && InteractionKeyPressed)
{
Debug.Log("Exiting door");
transform.position = SceneData.netSceneData.door.transform.position;
insideDoor = false;
enteringDoor = true;
if (GetComponent<NetPlayer>() != null) { GetComponent<NetPlayer>().CallChangeInsideDoor(insideDoor); }
}
if (listenToInput)
{
if (isGrounded)
{
moveInput = HorizontalAxis;
}
else
{
//Change moveInput while in-air | IF there is an input
// if (Input.GetKey(InputManager.data().leftInput) || Input.GetKey(InputManager.data().rightInput))
if (HorizontalAxis != 0)
{
moveInput = Mathf.Lerp(moveInput, HorizontalAxis, 0.2f);
}
}
//Enter the door
if (inDoor && InteractionKeyPressed && !enteringDoor)
{
if (SceneData.netSceneData.doorExit != null)
{
Debug.Log("Entering door");
transform.DetachChildren();
transform.position = SceneData.netSceneData.doorExit.position;
insideDoor = true;
enteringDoor = true;
if (GetComponent<NetPlayer>() != null) { GetComponent<NetPlayer>().CallChangeInsideDoor(insideDoor); }
}
}
}
if (isSwimming || inWater) { moveInput = moveInput / 2f; }
//Update moving value on Animation
animator.SetBool("moving", (moveInput != 0));
animator.SetBool("isSwimming", isSwimming);
//Flip Image to face moving Direction
if (moveInput < 0)
{
sprite.flipX = (invertSprite) ? false : true;
}
else if (moveInput > 0)
{
sprite.flipX = (invertSprite) ? true : false;
}
//Apply moving input to player
// if (GetComponent<NetPlayer>() != null)
// {
// if (GetComponent<NetPlayer>().parentFrnd != null)
// {
// rigidbody.velocity = GetComponent<NetPlayer>().parentFrnd.GetComponent<Rigidbody2D>().velocity;
// }
// }
rigidbody.transform.Translate(new Vector2(moveSpeed * moveInput, 0));
if (moveInput == 0)
{
rigidbody.constraints = RigidbodyConstraints2D.FreezePositionX | RigidbodyConstraints2D.FreezeRotation;
}
else
{
rigidbody.constraints = RigidbodyConstraints2D.FreezeRotation;
}
bool _canJump = canJump();
if ((JumpKeyPressed) && _canJump)
{
jumpT = 0;
jumpReleased = false;
rigidbody.velocity = new Vector2(rigidbody.velocity.x, 0);
if (jumpSFX != null) AudioSingleton.getSFXSource().PlayOneShot(jumpSFX);
}
//Blocks continous jump button
if (!JumpKeyPressed) { jumpReleased = true; }
//Apply Jump to player
if (jumpT < jumpDuration)
{
jumpT += Time.deltaTime;
float progress = (jumpDuration - jumpT) / jumpDuration;
//|| jumpT < jumpDuration/2f
if ((JumpKeyPressed) || b) { rigidbody.AddForce(new Vector2(0, jumpForce * progress)); }
}
else { b = false; }
_isSwimming = inWater;
}
bool b;
bool _isSwimming;
public bool waterBoost;
public bool canJump()
{
return jumpT >= jumpDuration && isGrounded && listenToInput && jumpReleased && !isSwimming && transform.childCount <= 0;//&& !GameManager.isPaused
}
public bool canBotJump()
{
return isGrounded || isSwimming || inWater;
}
//External Player Control Exposure
public void Jump()
{
jumpT = 0;
rigidbody.velocity = new Vector2(rigidbody.velocity.x, 0);
b = true;
AudioSingleton.getSFXSource().PlayOneShot(jumpSFX);
}
public void move(float input)
{
input = Mathf.Clamp(input, -1, 1);
moveInput = input;
}
void OnLand()
{
// Debug.Log("Landed Like a boss!");
}
void OnFly()
{
// Debug.Log("Hey look im flying");
}
public float groundCheckerDist = 0.1f;
public float groundCheckerHeighMultipler = 1f;
public bool getGrounded()
{
//return (Physics2D.Linecast(transform.position, groundChecker.position, groundLayerMask));
Collider2D col = GetComponentInChildren<Collider2D>();
return (Physics2D.BoxCast(col.bounds.center, new Vector2(col.bounds.size.x - (col.bounds.size.x / 5f), col.bounds.size.y * groundCheckerHeighMultipler), 0, Vector2.down, groundCheckerDist, groundLayerMask));
}
void OnDrawGizmos()
{
Collider2D col = GetComponentInChildren<Collider2D>();
Gizmos.DrawWireCube(transform.position, neighboursDetectorSize);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(col.bounds.center - new Vector3(0, groundCheckerDist), new Vector2(col.bounds.size.x - (col.bounds.size.x / 5f), col.bounds.size.y * groundCheckerHeighMultipler));
}
// public bool getInWater(){Collider2D col = GetComponentInChildren<Collider2D>();
// return (Physics2D.BoxCast(col.bounds.center, new Vector2(col.bounds.size.x - (col.bounds.size.x / 5f), col.bounds.size.y), 0, Vector2.down, 0.1f, waterLayerMask));
// }
}
public static class AudioSingleton
{
private static AudioSource music;
private static AudioSource sfx;
public static AudioMixer mixer = Resources.Load("MasterMixer") as AudioMixer;
public static AudioSource getMusicSource()
{
if (music == null)
{
GameObject go = new GameObject("Music Audio Source");
go.AddComponent<AudioSource>();
music = go.GetComponent<AudioSource>();
music.outputAudioMixerGroup = mixer.FindMatchingGroups("Music")[0];
}
return music;
}
public static AudioSource getSFXSource()
{
//AudioMixer mixer = Resources.Load("MasterMixer") as AudioMixer;
if (sfx == null)
{
GameObject go = new GameObject("SFX Audio Source");
go.AddComponent<AudioSource>();
sfx = go.GetComponent<AudioSource>();
Debug.Log("sfx : " + (sfx == null).ToString() + ", mixer: " + (mixer == null).ToString());
sfx.outputAudioMixerGroup = mixer.FindMatchingGroups("SFX")[0];
}
return sfx;
}
}