using UnityEngine; [RequireComponent(typeof(Rigidbody))] [RequireComponent(typeof(Collider))] public class DraggableObject : MonoBehaviour { [Header("Přetahování")] public float dragSmoothness = 15f; [Header("Vizuální zpětná vazba")] public Renderer Renderer; public Color normalColor = Color.white; public Color dragColor = new Color(1f, 1f, 0.5f); public float scaleOnDrag = 1.15f; private Rigidbody rb; private Camera mainCamera; private bool isDragging = false; private Vector3 targetPosition; private Vector3 originalScale; private bool hasBeenScored = false; private Plane _dragPlane; private Collider col; void Awake() { rb = GetComponent(); col = GetComponent(); mainCamera = Camera.main; originalScale = transform.localScale; if (Renderer == null) Renderer = GetComponent(); } void Start() { rb.useGravity = false; rb.constraints = RigidbodyConstraints.FreezeRotation; targetPosition = transform.position; } void Update() { HandleInput(); } void FixedUpdate() { if (isDragging) { Vector3 newPos = Vector3.Lerp(rb.position, targetPosition, Time.fixedDeltaTime * dragSmoothness); rb.MovePosition(newPos); } } void HandleInput() { if (Input.touchCount > 0) { Touch touch = Input.GetTouch(0); //Vector3 worldPos = mainCamera.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 10f)); if (touch.phase == TouchPhase.Began) TryStartDrag(touch.position); else if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary) { if (isDragging) UpdateDrag(touch.position); } else if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled) { if (isDragging) EndDrag(); } } else { //Vector3 worldPos = mainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10f)); if (Input.GetMouseButtonDown(0)) TryStartDrag(Input.mousePosition); else if (Input.GetMouseButton(0) && isDragging) UpdateDrag(Input.mousePosition); else if (Input.GetMouseButtonUp(0) && isDragging) EndDrag(); } } void TryStartDrag(Vector3 screenPos) { Debug.Log("Trying to start drag at: " + screenPos); Ray ray = mainCamera.ScreenPointToRay(screenPos); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { if (hit.collider == col) { StartDrag(hit.point); } } } void StartDrag(Vector3 hitPoint) { Debug.Log("Started dragging at: " + hitPoint); isDragging = true; rb.isKinematic = false; rb.linearVelocity = Vector3.zero; _dragPlane = new Plane(-mainCamera.transform.forward, hitPoint); targetPosition = hitPoint; transform.localScale = originalScale * scaleOnDrag; if (Renderer != null) { Renderer.material.color = dragColor; } } void UpdateDrag(Vector3 screenPos) { Ray ray = mainCamera.ScreenPointToRay(screenPos); float distance; if (_dragPlane.Raycast(ray, out distance)) { targetPosition = ray.GetPoint(distance); } } void EndDrag() { Debug.Log("Ended dragging"); isDragging = false; rb.isKinematic = true; transform.localScale = originalScale; if (Renderer != null) { Renderer.material.color = normalColor; } } public void OnScored() { Debug.Log("Object scored"); if (hasBeenScored) return; hasBeenScored = true; isDragging = false; StartCoroutine(SinkIntoHole()); } System.Collections.IEnumerator SinkIntoHole() { float duration = 0.35f; float elapsed = 0f; Vector3 startScale = transform.localScale; while (elapsed < duration) { elapsed += Time.deltaTime; float t = elapsed / duration; transform.localScale = Vector3.Lerp(startScale, Vector3.zero, t); if (Renderer != null) Renderer.material.color = new Color(normalColor.r, normalColor.g, normalColor.b, 1f - t); yield return null; } gameObject.SetActive(false); LevelManager.Instance?.RegisterItem(); } }