using UnityEngine; using UnityEngine.EventSystems; /// /// Fitur: /// • Single touch / mouse drag → rotate /// • Two-finger pinch → zoom in/out /// • Two-finger drag → pan/geser /// • Mouse scroll wheel → zoom in/out /// public class FreeInteract : MonoBehaviour { [Header("Interaction Settings")] public float rotateSpeed = 0.3f; public float pinchSensitivity = 0.005f; public float panSensitivity = 0.01f; public float scrollSensitivity = 0.3f; public Vector2 scaleRange = new Vector2(0.4f, 3.0f); private Vector3 originalScale; private float scaleMultiplier = 1f; private float lastPinchDist = 0f; private bool pinchInitialized = false; private bool isDragging = false; void Start() { originalScale = transform.localScale; if (originalScale == Vector3.zero) originalScale = Vector3.one; } void Update() { // Abaikan kalau klik/tap kena UI if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject()) return; HandleTouch(); HandleMouse(); } void HandleTouch() { int touchCount = Input.touchCount; if (touchCount == 1) { pinchInitialized = false; Touch t = Input.GetTouch(0); if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject(t.fingerId)) return; if (t.phase == TouchPhase.Moved) RotateObject(t.deltaPosition.x, t.deltaPosition.y); } else if (touchCount >= 2) { Touch t1 = Input.GetTouch(0); Touch t2 = Input.GetTouch(1); // Pinch zoom float currentDist = Vector2.Distance(t1.position, t2.position); if (!pinchInitialized || t1.phase == TouchPhase.Began || t2.phase == TouchPhase.Began) { lastPinchDist = currentDist; pinchInitialized = true; } else { float delta = currentDist - lastPinchDist; ApplyScaleDelta(delta * pinchSensitivity); lastPinchDist = currentDist; } // Two-finger pan (hanya kalau arah sama) if (t1.phase == TouchPhase.Moved || t2.phase == TouchPhase.Moved) { Vector2 avgDelta = (t1.deltaPosition + t2.deltaPosition) * 0.5f; if (Vector2.Dot(t1.deltaPosition.normalized, t2.deltaPosition.normalized) > 0.5f) { Vector3 worldDelta = Camera.main.transform.TransformDirection( new Vector3(avgDelta.x, avgDelta.y, 0f) * panSensitivity ); transform.position += worldDelta; } } } } void HandleMouse() { if (Input.GetMouseButtonDown(0)) isDragging = true; if (Input.GetMouseButtonUp(0)) isDragging = false; if (isDragging && Input.GetMouseButton(0)) { float dx = Input.GetAxis("Mouse X"); float dy = Input.GetAxis("Mouse Y"); RotateObject(dx * 10f, dy * 10f); // *10 karena Mouse X satuan berbeda dari pixel } float scroll = Input.GetAxis("Mouse ScrollWheel"); if (Mathf.Abs(scroll) > 0.001f) ApplyScaleDelta(scroll * scrollSensitivity); } void RotateObject(float deltaX, float deltaY) { float rotY = -deltaX * rotateSpeed; float rotX = deltaY * rotateSpeed; transform.Rotate(Camera.main.transform.up, rotY, Space.World); transform.Rotate(Camera.main.transform.right, rotX, Space.World); } void ApplyScaleDelta(float delta) { scaleMultiplier = Mathf.Clamp(scaleMultiplier + delta, scaleRange.x, scaleRange.y); transform.localScale = originalScale * scaleMultiplier; } }