120 lines
3.9 KiB
C#
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;
|
|
}
|
|
} |