147 lines
4.3 KiB
C#
147 lines
4.3 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class DraggableObject : MonoBehaviour
|
|
{
|
|
[HideInInspector] public float mass = 1f;
|
|
[HideInInspector] public bool isHeavy = false;
|
|
[HideInInspector] public Transform priorityTarget = null;
|
|
|
|
public Vector3 startPosition { get; private set; }
|
|
public Quaternion startRotation { get; private set; }
|
|
|
|
private Vector3 _mousePosition;
|
|
private Vector3 _mouseCameraPos;
|
|
private Vector3 _initialPosition;
|
|
private Rigidbody _rb;
|
|
private Camera _camera;
|
|
private Transform _scaleTarget;
|
|
private float _lerpPosition;
|
|
[HideInInspector] public bool isDragging;
|
|
|
|
[SerializeField] private float _minY = 0.2f;
|
|
[SerializeField] private float _maxDistanceFromStart = 30f;
|
|
|
|
private void Awake()
|
|
{
|
|
_rb = GetComponent<Rigidbody>();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
_camera = Camera.main;
|
|
_rb.isKinematic = true;
|
|
startPosition = transform.position;
|
|
startRotation = transform.rotation;
|
|
}
|
|
|
|
private Vector3 GetMousePos()
|
|
{
|
|
return _camera != null ? _camera.WorldToScreenPoint(transform.position) : Vector3.zero;
|
|
}
|
|
|
|
private Transform GetNearestTargetToCursor()
|
|
{
|
|
if (priorityTarget != null && priorityTarget.gameObject.activeInHierarchy)
|
|
return priorityTarget;
|
|
|
|
var targets = new List<GameObject>();
|
|
targets.AddRange(GameObject.FindGameObjectsWithTag("ScaleTarget"));
|
|
targets.AddRange(GameObject.FindGameObjectsWithTag("MainScale"));
|
|
|
|
Transform nearest = null;
|
|
float minDist = float.MaxValue;
|
|
foreach (var t in targets)
|
|
{
|
|
Vector3 screenPos = _camera.WorldToScreenPoint(t.transform.position);
|
|
float d = Vector2.Distance(
|
|
new Vector2(Input.mousePosition.x, Input.mousePosition.y),
|
|
new Vector2(screenPos.x, screenPos.y));
|
|
if (d < minDist) { minDist = d; nearest = t.transform; }
|
|
}
|
|
return nearest;
|
|
}
|
|
|
|
private void OnMouseDown()
|
|
{
|
|
_rb.isKinematic = false;
|
|
_rb.useGravity = false;
|
|
_rb.velocity = Vector3.zero;
|
|
_scaleTarget = GetNearestTargetToCursor();
|
|
_initialPosition = transform.position;
|
|
_mousePosition = Input.mousePosition - GetMousePos();
|
|
isDragging = true;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!isDragging || _camera == null) return;
|
|
|
|
_rb.angularVelocity = Vector3.zero;
|
|
_mouseCameraPos = _camera.ScreenToWorldPoint(Input.mousePosition - _mousePosition);
|
|
|
|
float targetZ = _scaleTarget != null ? _scaleTarget.position.z : _initialPosition.z;
|
|
_lerpPosition = _scaleTarget != null
|
|
? Mathf.InverseLerp(_initialPosition.x, _scaleTarget.position.x, _mouseCameraPos.x)
|
|
: 0f;
|
|
|
|
transform.position = new Vector3(
|
|
_mouseCameraPos.x,
|
|
Mathf.Max(_mouseCameraPos.y, _minY),
|
|
Mathf.Lerp(_initialPosition.z, targetZ, _lerpPosition)
|
|
);
|
|
|
|
if (Input.GetMouseButtonUp(0))
|
|
{
|
|
isDragging = false;
|
|
_rb.useGravity = true;
|
|
_rb.isKinematic = false;
|
|
}
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (isDragging) return;
|
|
if (Vector3.Distance(transform.position, startPosition) > _maxDistanceFromStart)
|
|
ResetToStart();
|
|
}
|
|
|
|
public void ResetToStart()
|
|
{
|
|
_rb.velocity = Vector3.zero;
|
|
_rb.angularVelocity = Vector3.zero;
|
|
_rb.isKinematic = true;
|
|
transform.position = startPosition;
|
|
transform.rotation = startRotation;
|
|
isDragging = false;
|
|
}
|
|
|
|
private void OnTriggerEnter(Collider other)
|
|
{
|
|
if (isDragging) return;
|
|
if (!other.CompareTag("ScalePan")) return;
|
|
StartCoroutine(SnapToPan(other.transform));
|
|
}
|
|
|
|
private IEnumerator SnapToPan(Transform pan)
|
|
{
|
|
_rb.isKinematic = true;
|
|
_rb.useGravity = false;
|
|
|
|
Vector3 targetPos = pan.position + Vector3.up * 0.1f;
|
|
float t = 0f;
|
|
Vector3 startPos = transform.position;
|
|
|
|
while (t < 1f)
|
|
{
|
|
t += Time.deltaTime * 5f;
|
|
transform.position = Vector3.Lerp(startPos, targetPos, t);
|
|
yield return null;
|
|
}
|
|
|
|
_rb.isKinematic = false;
|
|
_rb.useGravity = true;
|
|
}
|
|
}
|