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(); } // 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.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(); 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()); } }