Files
GeoSusGame/Assets/Scripts/hod_veci_do_diry/DraggableObject.cs
2026-04-26 14:41:06 +02:00

165 lines
4.7 KiB
C#

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<Rigidbody>();
col = GetComponent<Collider>();
mainCamera = Camera.main;
originalScale = transform.localScale;
if (Renderer == null)
Renderer = GetComponent<Renderer>();
}
void Start()
{
rb.useGravity = true;
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();
}
}