first commit
This commit is contained in:
146
Assets/Scripts/ScaleTest/DraggableObject.cs
Normal file
146
Assets/Scripts/ScaleTest/DraggableObject.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user