275 lines
7.7 KiB
C#
275 lines
7.7 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Data;
|
|
using Interaction;
|
|
using TMPro.Examples;
|
|
using Unity.VisualScripting;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.Serialization;
|
|
using Utility;
|
|
|
|
public class Character : MonoBehaviour
|
|
{
|
|
[SerializeField] private Animator _animator;
|
|
|
|
[FormerlySerializedAs("moveSpeed")] [Header("Movement")]
|
|
public float _movementAcceleration = 2f;
|
|
public float groundDrag = 1f;
|
|
|
|
private Vector3 moveDirection;
|
|
private Rigidbody rb;
|
|
|
|
[FormerlySerializedAs("speed")] public float _maxVelocity = 2f;
|
|
|
|
[Header("Turning")]
|
|
public float turningRate = 30f;
|
|
public Quaternion _targetRotation = Quaternion.identity;
|
|
|
|
[Header("Jumping")]
|
|
public float jumpForce;
|
|
public float jumpCooldown;
|
|
private bool _readyToJump = true;
|
|
|
|
[Header("Groud Check")]
|
|
[SerializeField]private float _groundedTolerance = 0.2f;
|
|
[SerializeField]private LayerMask _groundLayerMask;
|
|
private bool _grounded;
|
|
|
|
[Header("Hold item")]
|
|
[SerializeField] private Transform _hand;
|
|
[FormerlySerializedAs("_carriedItem")] [SerializeField] private GameObject _carriedItemModel;
|
|
[SerializeField] private PickupInteractible _carriedInteractible;
|
|
[FormerlySerializedAs("_throwAsideForce")] [SerializeField, Tooltip("Die Kraft mit der der Gegenstand fallen gelassen wird.")]
|
|
private float _dropItemForce = 3.0f;
|
|
|
|
[SerializeField]
|
|
private GottfriedData _data;
|
|
|
|
[SerializeField]
|
|
private AudioSource _audioSource;
|
|
|
|
private static readonly int RunSpeed = Animator.StringToHash("RunSpeed");
|
|
private static readonly int IsFalling = Animator.StringToHash("IsFalling");
|
|
private static readonly int IsJumping = Animator.StringToHash("IsJumping");
|
|
|
|
public bool CarriesItem => _carriedInteractible;
|
|
|
|
public PickupInteractible CarriedItem => _carriedInteractible;
|
|
|
|
public GottfriedData Data => _data;
|
|
|
|
// Start is called before the first frame update
|
|
void Start()
|
|
{
|
|
rb = gameObject.GetComponent<Rigidbody>();
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
_grounded = Physics.Raycast(transform.position + new Vector3(0, _groundedTolerance / 2.0f, 0), Vector3.down, _groundedTolerance, _groundLayerMask);
|
|
|
|
SpeedControl();
|
|
|
|
transform.rotation = Quaternion.RotateTowards(transform.rotation, _targetRotation, turningRate * Time.deltaTime);
|
|
|
|
if (_grounded)
|
|
{
|
|
rb.drag = groundDrag;
|
|
}
|
|
else
|
|
{
|
|
rb.drag = 0.3f;
|
|
}
|
|
|
|
UpdateAnimator();
|
|
}
|
|
|
|
private void UpdateAnimator()
|
|
{
|
|
//if (_grounded)
|
|
{
|
|
Vector3 velocity = rb.velocity;
|
|
velocity.y = 0.0f;
|
|
|
|
_animator.SetFloat(RunSpeed, velocity.magnitude);
|
|
}
|
|
//else
|
|
{
|
|
//_animator.SetFloat(RunSpeed, 0);
|
|
}
|
|
|
|
_animator.SetBool(IsFalling, !_grounded);
|
|
}
|
|
|
|
public void PickupItem(PickupInteractible itemToPickup)
|
|
{
|
|
if (_carriedInteractible)
|
|
{
|
|
_carriedInteractible.gameObject.SetActive(true);
|
|
_carriedInteractible.transform.parent = null;
|
|
|
|
_carriedInteractible.transform.position = _carriedItemModel.transform.position;
|
|
_carriedInteractible.transform.rotation = _carriedItemModel.transform.rotation;
|
|
|
|
Rigidbody rigidbody = _carriedInteractible.GetComponent<Rigidbody>();
|
|
|
|
rigidbody.AddForce(Random.insideUnitSphere * _dropItemForce, ForceMode.Impulse);
|
|
|
|
Destroy(_carriedItemModel);
|
|
|
|
_carriedItemModel = null;
|
|
_carriedInteractible = null;
|
|
}
|
|
|
|
if (itemToPickup)
|
|
{
|
|
GameObject model = Instantiate(itemToPickup.Model, _hand);
|
|
|
|
itemToPickup.transform.parent = model.transform;
|
|
itemToPickup.gameObject.SetActive(false);
|
|
|
|
_carriedItemModel = model;
|
|
_carriedInteractible = itemToPickup;
|
|
}
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
MovePlayer();
|
|
}
|
|
|
|
public void DoMove(InputAction.CallbackContext context)
|
|
{
|
|
Vector2 movement = context.ReadValue<Vector2>();
|
|
|
|
moveDirection = new Vector3(movement.x, 0, movement.y);
|
|
|
|
if(moveDirection.x != 0f || moveDirection.z != 0f)
|
|
{
|
|
_targetRotation = Quaternion.LookRotation(moveDirection);
|
|
//Quaternion.Euler(new Vector3(0f, Mathf.Atan2(moveDirection.x, moveDirection.z) * Mathf.Rad2Deg, 0f));
|
|
}
|
|
}
|
|
|
|
public void DoJump(InputAction.CallbackContext context)
|
|
{
|
|
if (!context.performed || !_readyToJump || !_grounded)
|
|
return;
|
|
|
|
Jump();
|
|
|
|
Invoke(nameof(ResetJump), jumpCooldown);
|
|
}
|
|
|
|
public void DoDropItem(InputAction.CallbackContext context)
|
|
{
|
|
if (!context.performed)
|
|
return;
|
|
|
|
PickupItem(null);
|
|
}
|
|
|
|
private void MovePlayer()
|
|
{
|
|
rb.AddForce(moveDirection.normalized * _movementAcceleration, ForceMode.Acceleration);
|
|
}
|
|
|
|
private void SpeedControl()
|
|
{
|
|
Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
|
|
|
|
if (flatVel.magnitude > _maxVelocity)
|
|
{
|
|
Vector3 limitedVel = flatVel.normalized * _maxVelocity;
|
|
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
|
|
}
|
|
}
|
|
|
|
private void Jump()
|
|
{
|
|
_animator.SetTrigger(IsJumping);
|
|
|
|
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
|
|
|
|
rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
|
|
}
|
|
|
|
private void ResetJump()
|
|
{
|
|
_readyToJump = true;
|
|
}
|
|
|
|
public void GiveItemTo(Developer developer)
|
|
{
|
|
Debug.Log($"Gebe {_carriedInteractible.Name} an {developer.Name}");
|
|
|
|
PickupInteractible item = _carriedInteractible;
|
|
|
|
if (item == null)
|
|
return;
|
|
|
|
switch (item.ItemType)
|
|
{
|
|
case ItemType.Coffee:
|
|
developer.GiveDrink(0.45, WantedConsumable.Coffee);
|
|
_audioSource.PlayOneShot(_data.DrinkCoffe);
|
|
break;
|
|
case ItemType.Mate:
|
|
developer.GiveDrink(0.35, WantedConsumable.Mate);
|
|
_audioSource.PlayOneShot(_data.DrinkMate);
|
|
break;
|
|
case ItemType.Pizza:
|
|
developer.GiveFood(0.4, WantedConsumable.Pizza);
|
|
_audioSource.PlayOneShot(_data.EatPizza);
|
|
break;
|
|
default:
|
|
SayItsImpossible();
|
|
return;
|
|
}
|
|
|
|
item.UsesLeft--;
|
|
|
|
if (item.UsesLeft <= 0)
|
|
{
|
|
PickupItem(null);
|
|
|
|
Destroy(item.gameObject);
|
|
}
|
|
}
|
|
|
|
public void SayItsImpossible()
|
|
{
|
|
_audioSource.PlayOneShot(_data.VoiceSayItsImpossible.GetRandomElement());
|
|
}
|
|
|
|
[SerializeField]
|
|
private bool _canHurt = true;
|
|
|
|
public void Hurt()
|
|
{
|
|
if (_canHurt)
|
|
StartCoroutine(HurtRoutine());
|
|
}
|
|
|
|
private IEnumerator HurtRoutine()
|
|
{
|
|
_canHurt = false;
|
|
|
|
_audioSource.PlayOneShot(_data.Hurt);
|
|
PickupItem(null);
|
|
|
|
yield return new WaitForSeconds(1);
|
|
|
|
_canHurt = true;
|
|
}
|
|
|
|
public void PlayStepSound()
|
|
{
|
|
_audioSource.PlayOneShot(_data.StepSounds.GetRandomElement());
|
|
}
|
|
}
|