496 lines
16 KiB
C#
Raw Permalink Normal View History

2024-02-19 21:00:36 +03:00
using UnityEngine;
using Mirror;
using TMPro;
2024-03-19 17:42:38 +03:00
using Characters;
2024-02-19 21:00:36 +03:00
using Debuffs;
using Koptilnya;
2024-02-19 21:00:36 +03:00
/* Note: animations are called via the controller for both the character and capsule using animator null checks
*/
namespace StarterAssets
{
[RequireComponent(typeof(CharacterController))]
public class PersonController : Pawn
{
[Header("Oscar nasral v kod")]
public GameObject headPosition;
public GameObject floatingInfo;
public TMP_Text nicknameInput;
public AudioSource audioSource;
public AudioClip footStepClip;
private AudioClip _gotEnergyClip;
private Interactions _interactions;
private Vector2 _lerpInputVec, _inputVec;
private float _controllerVelocity, lerp;
private bool _inputJump;
private Vector2 _inputMove;
public float _stepCycle, _stepTiming = 1;
[Header("Player")]
[Tooltip("Move speed of the character in m/s")]
public float MoveSpeed = 2.0f;
[Tooltip("Sprint speed of the character in m/s")]
public float SprintSpeed = 5.335f;
[Tooltip("Acceleration and deceleration")]
public float SpeedChangeRate = 10.0f;
[Space(10)]
[Tooltip("The height the player can jump")]
public float JumpHeight = 1.2f;
[Tooltip("The character uses its own gravity value. The engine default is -9.81f")]
public float Gravity = -15.0f;
[Space(10)]
[Tooltip("Time required to pass before being able to jump again. Set to 0f to instantly jump again")]
public float JumpTimeout = 0.50f;
[Tooltip("Time required to pass before entering the fall state. Useful for walking down stairs")]
public float FallTimeout = 0.15f;
[Header("Player Grounded")]
[Tooltip("If the character is grounded or not. Not part of the CharacterController built in grounded check")]
public bool Grounded = true;
[Tooltip("Useful for rough ground")]
public float GroundedOffset = -0.14f;
[Tooltip("The radius of the grounded check. Should match the radius of the CharacterController")]
public float GroundedRadius = 0.28f;
[Tooltip("What layers the character uses as ground")]
public LayerMask GroundLayers;
public bool LockCameraPosition = false;
private float _cinemachineTargetYaw;
[SyncVar]
public Transform _parent;
private float _speed;
private float _animationBlend;
private float _verticalVelocity;
private float _terminalVelocity = 53.0f;
private float _jumpTimeoutDelta;
private float _fallTimeoutDelta;
// animation IDs
private int _animIDSpeed, _animIDGrounded, _animIDJump, _animIDFreeFall, _animIDMotionSpeed, _animIDX, _animIDY;
public Animator _animator;
private CharacterController _controller;
public GameObject mainCamera;
private const float _threshold = 0.01f;
private bool _hasAnimator = true;
[SyncVar(hook = nameof(OnPlayerSetup))]
public string playerName;
[SyncVar, HideInInspector]
public Color gunColor;
private Vector3 _position;
private float _rotationVelocity;
private Vector2 _mouseLook;
[SyncVar]
public float _cinemachineTargetPitch;
public GameObject CinemachineCameraTarget;
public float RotationSpeed = 1f;
public float BottomClamp = -90.0f;
public float TopClamp = 90.0f;
2024-02-19 21:00:36 +03:00
[Command]
public void CmdSetupPlayer(string _name, float r, float g, float b)
{
gunColor = new Color(r, g, b);
playerName = _name;
}
public void OnPlayerSetup(string _Old, string _New)
{
nicknameInput.text = playerName;
}
public override void OnStartLocalPlayer()
{
CmdSetupPlayer(
PlayerPrefs.GetString("NickName"),
PlayerPrefs.GetFloat("GunColorR"),
PlayerPrefs.GetFloat("GunColorG"),
PlayerPrefs.GetFloat("GunColorB")
);
}
private void Start()
{
RotationSpeed = PlayerPrefs.GetFloat("Sensitivity");
2024-02-19 21:00:36 +03:00
_controller = GetComponent<CharacterController>();
_gotEnergyClip = Resources.Load<AudioClip>("Audio/CharacterSounds/GetEnergy");
Live();
_interactions = GetComponent<Interactions>();
if (isLocalPlayer)
{
floatingInfo.SetActive(false);
}
if (!isLocalPlayer) return;
AssignAnimationIDs();
_jumpTimeoutDelta = JumpTimeout;
_fallTimeoutDelta = FallTimeout;
}
private void Update()
{
if (Alive)
{
CalculateFootstepTriggers();
setParent();
}
if (!isLocalPlayer)
{
if (netIdentity.isActiveAndEnabled && floatingInfo != null && Camera.main)
2024-02-19 21:00:36 +03:00
floatingInfo.transform.LookAt(Camera.main.transform);
return;
}
if (Cursor.lockState == CursorLockMode.None) return;
if (Alive)
{
CalculateEnergy();
GroundedCheck();
JumpAndGravity();
Move();
}
else
{
SpectatorMove();
}
}
private void LateUpdate()
{
if (!isLocalPlayer) return;
if (Cursor.lockState == CursorLockMode.None) return;
CameraRotation();
SetCamToHeadPos();
}
void CameraRotation()
{
if (Cursor.lockState == CursorLockMode.None) return;
_mouseLook = new Vector2(Input.GetAxis("Mouse X"), -Input.GetAxis("Mouse Y"));
_cinemachineTargetPitch += _mouseLook.y * RotationSpeed;
_rotationVelocity = _mouseLook.x * RotationSpeed;
_cinemachineTargetPitch = _cinemachineTargetPitch.ClampAngle(BottomClamp, TopClamp);
transform.Rotate(Vector3.up * _rotationVelocity);
CinemachineCameraTarget.transform.localRotation = Quaternion.Euler(_cinemachineTargetPitch, 0.0f, 0.0f);
// CmdSetCameraPitch(_cinemachineTargetPitch);
}
2024-02-19 21:00:36 +03:00
private void SetCamToHeadPos()
{
CinemachineCameraTarget.transform.position = headPosition.transform.position;
}
private void AssignAnimationIDs()
{
_animIDSpeed = Animator.StringToHash("Speed");
_animIDGrounded = Animator.StringToHash("Grounded");
_animIDJump = Animator.StringToHash("Jump");
_animIDFreeFall = Animator.StringToHash("FreeFall");
_animIDMotionSpeed = Animator.StringToHash("MotionSpeed");
_animIDX = Animator.StringToHash("x");
_animIDY = Animator.StringToHash("y");
}
private void GroundedCheck()
{
Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z);
Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers, QueryTriggerInteraction.Ignore);
if (_hasAnimator)
{
_animator.SetBool(_animIDGrounded, Grounded);
}
}
2024-03-21 18:28:37 +03:00
public float currentEnergy = 100f, shootDepletion = 15f, _flashLightDepletion = 0.4f;
private float _maxEnergy = 300f, _depletionSpeed = 0.5f, _regenerationSpeed = 1f, _jumpDepletion = 5f;
2024-02-19 21:00:36 +03:00
private void CalculateEnergy()
{
if (Input.GetKey(KeyCode.LeftShift) && _inputMove.magnitude != 0)
{
2024-03-16 22:07:25 +03:00
currentEnergy = Mathf.MoveTowards(currentEnergy, 0, _depletionSpeed * Time.deltaTime);
2024-02-19 21:00:36 +03:00
}
else if (currentEnergy <= _maxEnergy)
{
currentEnergy = Mathf.MoveTowards(currentEnergy, _maxEnergy, _regenerationSpeed * Time.deltaTime);
}
if (currentEnergy <= 0)
{
CmdDie();
}
}
public void InstantStaminaReduction(float Reduction)
{
2024-03-21 18:28:37 +03:00
currentEnergy = currentEnergy -= Reduction;
2024-02-19 21:00:36 +03:00
}
public void InstantStaminaRegeneration(float Regeneration)
{
2024-03-21 18:28:37 +03:00
currentEnergy = currentEnergy += Regeneration;
2024-02-19 21:00:36 +03:00
CmdGotEnergy();
}
[Command(requiresAuthority = false)]
void CmdGotEnergy()
{
RpcGotEnergy();
}
[ClientRpc]
void RpcGotEnergy()
{
audioSource.PlayOneShot(_gotEnergyClip);
}
[Command]
void CmdSetCameraPitch(float value)
{
_cinemachineTargetPitch = value;
}
void SetCameraPitch()
{
lerp = Mathf.Lerp(lerp, _cinemachineTargetPitch, Time.deltaTime * 10f);
CinemachineCameraTarget.transform.localRotation = Quaternion.Euler(lerp, 0.0f, 0.0f);
}
private void Move()
{
_inputMove = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
float targetSpeed = Input.GetKey(KeyCode.LeftShift) ? (currentEnergy <= _depletionSpeed ? MoveSpeed : SprintSpeed) : MoveSpeed;
targetSpeed *= _speedMul;
if (_inputMove == Vector2.zero) targetSpeed = 0.0f;
float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude;
float speedOffset = 0.1f;
float inputMagnitude = 1f;
if (currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset)
{
_speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * SpeedChangeRate);
_speed = Mathf.Round(_speed * 1000f) / 1000f;
}
else
{
_speed = targetSpeed;
}
_animationBlend = Mathf.Lerp(_animationBlend, targetSpeed, Time.deltaTime * SpeedChangeRate);
Vector3 inputDirection = new Vector3(_inputMove.x, 0.0f, _inputMove.y).normalized;
if (_inputMove != Vector2.zero)
{
inputDirection = transform.right * _inputMove.x + transform.forward * _inputMove.y;
}
RaycastHit hit;
if (Physics.Raycast(transform.position, -transform.up, out hit, 1f, LayerMask.NameToLayer("Player")))
{
if (hit.collider.tag == "MovingPlatform" && hit.collider.GetComponentInParent<NetworkIdentity>() != null)
{
CmdSetParent(hit.collider.transform.parent);
}
else
{
CmdSetParent(null);
}
}
_controller.Move(inputDirection.normalized * (_speed * Time.deltaTime) + new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime);
if (_hasAnimator)
{
_lerpInputVec = Vector2.Lerp(_lerpInputVec, _inputMove, Time.deltaTime * 10);
_animator.SetFloat(_animIDSpeed, _animationBlend);
_animator.SetFloat(_animIDMotionSpeed, inputMagnitude);
_animator.SetFloat(_animIDX, _lerpInputVec.x);
_animator.SetFloat(_animIDY, _lerpInputVec.y);
}
}
void SpectatorMove()
{
2024-03-17 00:30:59 +03:00
float inputZ = (Input.GetKey(KeyCode.E) ? 1 : 0) - (Input.GetKey(KeyCode.Q) ? 1 : 0) + (Input.GetKey(KeyCode.Space) ? 1 : 0) - (Input.GetKey(KeyCode.LeftShift) ? 1 : 0);
2024-02-19 21:00:36 +03:00
float targetSpeed = MoveSpeed; //Input.GetKey(KeyCode.LeftShift) ? SprintSpeed : MoveSpeed;
_inputMove = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
Vector3 inputDirection = transform.right * _inputMove.x + transform.forward * _inputMove.y + transform.up * inputZ;
transform.position += inputDirection * Time.deltaTime * targetSpeed * 10f;
}
void setParent()
{
transform.parent = _parent;
}
[Command]
void CmdSetParent(Transform transf)
{
_parent = transf;
}
2024-03-20 18:57:25 +03:00
public override void TakeDamage()
2024-02-19 21:00:36 +03:00
{
_animator.SetTrigger("damage");
2024-03-21 18:28:37 +03:00
InstantStaminaReduction(shootDepletion);
2024-02-19 21:00:36 +03:00
// Debug.Log(self.GetComponent<PersonController>().playerName);
// hitVFX.Stop();
// hitVFX.Play();
// self.GetComponent<Interactions>().DropProp();
}
private void JumpAndGravity()
{
if (Grounded)
{
_inputJump = Input.GetKeyDown(KeyCode.Space);
// reset the fall timeout timer
_fallTimeoutDelta = FallTimeout;
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDJump, false);
_animator.SetBool(_animIDFreeFall, false);
}
// stop our velocity dropping infinitely when grounded
if (_verticalVelocity < 0.0f)
{
_verticalVelocity = -2f;
}
// Jump
if (_inputJump && _jumpTimeoutDelta <= 0.0f && currentEnergy >= _jumpDepletion)
{
// the square root of H * -2 * G = how much velocity needed to reach desired height
_verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity);
InstantStaminaReduction(_jumpDepletion);
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDJump, true);
}
}
// jump timeout
if (_jumpTimeoutDelta >= 0.0f)
{
_jumpTimeoutDelta -= Time.deltaTime;
}
}
else
{
// reset the jump timeout timer
_jumpTimeoutDelta = JumpTimeout;
// fall timeout
if (_fallTimeoutDelta >= 0.0f)
{
_fallTimeoutDelta -= Time.deltaTime;
}
else
{
// update animator if using character
if (_hasAnimator)
{
_animator.SetBool(_animIDFreeFall, true);
}
}
// if we are not grounded, do not jump
_inputJump = false;
}
// apply gravity over time if under terminal (multiply by delta time twice to linearly speed up over time)
if (_verticalVelocity < _terminalVelocity)
{
_verticalVelocity += Gravity * Time.deltaTime;
}
}
2024-03-17 00:00:54 +03:00
2024-02-19 21:00:36 +03:00
private void OnDrawGizmosSelected()
{
Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f);
Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f);
if (Grounded) Gizmos.color = transparentGreen;
else Gizmos.color = transparentRed;
// when selected, draw a gizmo in the position of, and matching radius of, the grounded collider
Gizmos.DrawSphere(new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z), GroundedRadius);
}
2024-03-17 00:00:54 +03:00
2024-02-19 21:00:36 +03:00
void CalculateFootstepTriggers()
{
float _controllerVelocity = ((_position - transform.position) / Time.deltaTime).magnitude;
// Debug.Log(_controllerVelocity);
float clampedVelocity = Mathf.Clamp(SprintSpeed / _controllerVelocity + 1, 1, SprintSpeed);
if (Time.time > _stepCycle && Grounded && _controllerVelocity > 0.1)
{
CallFootstepClip();
_stepCycle = Time.time + (clampedVelocity * _stepTiming);
}
_position = transform.position;
}
public void CallFootstepClip()
{
audioSource.pitch = 1f + Random.Range(-0.1f, 0.1f);
audioSource.PlayOneShot(footStepClip);
}
}
}