using System; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; public class LobbyPlayer : MonoBehaviour { public PlayerData playerData; //DisplayPlayerWorldUI [SerializeField] private TextMeshPro tmp; [Header("Movement Settings")] private Vector3 nextPosition; private Vector3 previousPosition; public float interpolationSpeed = 10f; private Quaternion nextRotation; [Header("Animation Settings")] [SerializeField] private float positionDiffThreshold = 0.005f; [SerializeField] private float movingSmoothing = 8f; [SerializeField] private float stoppingSmoothing = 25f; [SerializeField] private float stopDeadzone = 0.01f; private Vector3 _smoothedVelocity; private float _lastMoveTime; //Components [SerializeField] private Animator animator; //Properties public Vector3 NextPosition { get => nextPosition; set => nextPosition = value; } public Quaternion NextRotation { get => nextRotation; set => nextRotation = value; } //Components Rigidbody rb; public void SetPlayerData(PlayerData playerData) => this.playerData = playerData; private void Awake() { rb = GetComponent<Rigidbody>(); } void Start() { tmp.text = playerData.username; } void Update() { // Calculate movement difference Vector3 positionDiff = transform.position - previousPosition; float distanceMoved = positionDiff.magnitude; previousPosition = transform.position; // Movement detection with hysteresis bool isMoving = distanceMoved > positionDiffThreshold; if (isMoving) _lastMoveTime = Time.time; // Force stop if no recent movement (handles network latency) bool shouldStop = (Time.time - _lastMoveTime) > 0.1f; // Calculate velocity Vector3 currentVelocity = (isMoving && !shouldStop) ? positionDiff / Time.deltaTime : Vector3.zero; // Convert to local space Vector3 localVelocity = transform.InverseTransformDirection(currentVelocity); // Apply aggressive stopping when needed if (shouldStop) { localVelocity = Vector3.zero; _smoothedVelocity = Vector3.Lerp(_smoothedVelocity, localVelocity, Time.deltaTime * stoppingSmoothing * 2f); } else { // Normal smoothing float smoothing = isMoving ? movingSmoothing : stoppingSmoothing; _smoothedVelocity = Vector3.Lerp(_smoothedVelocity, localVelocity, Time.deltaTime * smoothing); } // Apply deadzone for stopping if (_smoothedVelocity.magnitude < stopDeadzone && !isMoving) { _smoothedVelocity = Vector3.zero; } // Always update animator (but with properly smoothed values) animator.SetFloat("velocityX", _smoothedVelocity.x); animator.SetFloat("velocityY", _smoothedVelocity.z); } void FixedUpdate() { // Stable interpolation with velocity consideration float t = Time.fixedDeltaTime * interpolationSpeed; Vector3 newPos = Vector3.Lerp(rb.position, nextPosition, t); rb.MovePosition(newPos); // Rotation interpolation - use the full yaw rotation Quaternion newRot = Quaternion.Lerp(rb.rotation, nextRotation, t); rb.MoveRotation(newRot); } private void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Player")) { Physics.IgnoreCollision(GetComponent<Collider>(), collision.collider, true); } } }