Вы должны сделать это Physics.Raycast
только один раз ... это довольно дорого! Также проверка для Input.GetMouseButtonDown
является избыточной. И сохраните результат Camera.main
, что также довольно дорого (на самом деле, под капотом используется нечто похожее на GameObjevt.FindWithTag("MainCamera")
)
Также обратите внимание: GetMouseButtonDown(0)
возвращает true только один раз вкадр, когда кнопка нажата в первый раз. Позже для перемещения вы, скорее всего, захотите использовать GetMouseButton(0)
, то есть true
, пока кнопка остается нажатой.
И, наконец, если вы хотите плавное движение к точной позиции ударавместо позиции попадания объектов вы можете использовать hit.point
вместо hit.transform.position
Флаг unselected
отчасти избыточен: вы можете напрямую использовать if(selected)
и позже сбросить его на selected = null
Так что-то вроде
[SerializeField] private Camera _camera;
private void Awake ()
{
if(!_camera) _camera = Camera.main;
}
private void Update()
{
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit) && hit.gameObject.CompareTag("Cylinder"))
{
// First click -> select object
if(Input.GetMouseButtonDown(0) && !selected)
{
selected = hit.transform.gameObject;
}
// button stays pressed > move object
else if (selected && Input.GetMouseButton(0))
{
selected.transform.position = hit.point;
}
// Second click release object
else if(selected && Input.GetMouseButtonDown(0))
{
selected = null;
}
}
// ToDo: What if the Raycast doesn't hit? Then you can't release object?
}