using DG.Tweening; using UnityEngine; public class ChasePlayerController : MonoBehaviour { public float moveSpeed = 5f; public float laneDistance = 2.5f; // Distance between lanes public float jumpPower = 0.6f; // Jump height public float jumpDuration = 1.2f; // Total jump time public float laneSwitchSpeed = 10f; private int currentLane = 1; // 0 = Left, 1 = Middle, 2 = Right private Rigidbody rb; private Animator animator; private bool isGrounded = true; private Vector3 targetLanePosition; private Vector2 startTouchPosition; private Vector2 endTouchPosition; private bool swipeDetected = false; private float minSwipeDistance = 50f; // Pixels void Start() { rb = GetComponent(); animator = GetComponent(); targetLanePosition = transform.position; } void Update() { HandleInput(); HandleSwipe(); UpdateLaneTarget(); } void FixedUpdate() { MoveForward(); SmoothLaneSwitch(); } void HandleInput() { if (Input.GetKeyDown(KeyCode.LeftArrow) && currentLane > 0) currentLane--; if (Input.GetKeyDown(KeyCode.RightArrow) && currentLane < 2) currentLane++; if (Input.GetKeyDown(KeyCode.Space) && isGrounded) Jump(); } void HandleSwipe() { if (Input.touchCount == 1) { Touch touch = Input.GetTouch(0); switch (touch.phase) { case TouchPhase.Began: startTouchPosition = touch.position; swipeDetected = true; break; case TouchPhase.Ended: if (!swipeDetected) return; endTouchPosition = touch.position; Vector2 swipe = endTouchPosition - startTouchPosition; if (swipe.magnitude >= minSwipeDistance) { float x = swipe.x; float y = swipe.y; if (Mathf.Abs(x) > Mathf.Abs(y)) { // Horizontal swipe if (x > 0 && currentLane < 2) currentLane++; else if (x < 0 && currentLane > 0) currentLane--; } else { // Vertical swipe if (y > 0 && isGrounded) Jump(); } } swipeDetected = false; break; } } } void UpdateLaneTarget() { float targetX = (currentLane - 1) * laneDistance; targetLanePosition = new Vector3(targetX, rb.position.y, rb.position.z); } void SmoothLaneSwitch() { Vector3 newPosition = Vector3.Lerp(rb.position, targetLanePosition, laneSwitchSpeed * Time.fixedDeltaTime); rb.MovePosition(newPosition); } void MoveForward() { rb.MovePosition(rb.position + Vector3.back * moveSpeed * Time.fixedDeltaTime); } void Jump() { if (!isGrounded) return; isGrounded = false; rb.velocity = Vector3.zero; rb.useGravity = false; // Predict forward displacement float forwardDisplacement = moveSpeed * jumpDuration; Vector3 jumpTarget = rb.position + Vector3.back * forwardDisplacement; rb.DOJump(jumpTarget, jumpPower, 1, jumpDuration) .SetEase(Ease.Linear) .OnStart(() => { if (animator != null) animator.SetTrigger("Jump"); }) .OnComplete(() => { rb.useGravity = true; isGrounded = true; if (animator != null) animator.SetTrigger("Run"); }); } void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Ground")) { isGrounded = true; if (animator != null) animator.SetTrigger("Run"); } } }