MIF_E31230837/Assets/Script/FreeInteract.cs

120 lines
3.9 KiB
C#

using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// Fitur:
/// • Single touch / mouse drag → rotate
/// • Two-finger pinch → zoom in/out
/// • Two-finger drag → pan/geser
/// • Mouse scroll wheel → zoom in/out
/// </summary>
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;
}
}