#c# #unity3d
Вопрос:
Я хочу уничтожить игровой объект, когда он нажимает на триггер, но с вводом. Ошибок нет, но в unity это не работает
using UnityEngine;
public class DestroyTile : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Tile"))
{
if(Input.GetKeyDown(KeyCode.Space))
{
Destroy(other.gameObject);
}
}
}
}
что я должен сделать, чтобы это сработало??
Ответ №1:
Очень маловероятно, что вам удастся нажать клавишу точно в том же кадре, в котором произойдет столкновение 😉
В качестве быстрого решения скорее используйте OnTriggerStay
OnTriggerStay вызывается один раз за обновление физики для каждого другого коллайдера, который касается триггера.
public class DestroyTile : MonoBehaviour
{
// Called once every FixedUpdate for each trigger you are touching
private void OnTriggerStay(Collider other)
{
if (other.CompareTag("Tile"))
{
if(Input.GetKeyDown(KeyCode.Space))
{
Destroy(other.gameObject);
}
}
}
}
С вышеуказанным способом есть только одна последняя проблема: OnTriggerStay
на самом деле вызывается не каждый кадр, а скорее каждый FixedUpdate
, поэтому вы можете пропустить нажатие клавиши, если это произошло в кадре, где FixedUpdate
не вызывается. Поэтому в целом получение пользовательского ввода в рамках FixedUpdate
(или других непрерывных методов, основанных на физике) ненадежно и всегда должно выполняться Update
.
Поэтому вместо этого вы могли бы/должны сделать что-то вроде, например
public class DestroyTile : MonoBehaviour
{
private readonly HashSet<GameObject> _currentlyTouching = new HashSet<GameObject>();
private void OnTriggerEnter(Collider other)
{
if (!other.CompareTag("Tile") return;
// For some reason we still have the other object stored
if(_currentlyTouching .Contains(other.gameObject)) return;
// Store the other object
_currentlyTouching.Add(other.gameObject);
}
private void OnTriggerExit(Collider other)
{
// We don't have this other object stored
if(!_currentlyTouching.Contains(other.gameObject) return;
// remove this other object
_currentlyTouching.Remove(other.gameObject);
}
private void Update()
{
// Are we touching anything?
// This check is cheaper than Input.GetKeyDown
if(_currentlyTouching.Count <= 0) return;
if(!Input.GetKeyDown(KeyCode.Space)) return;
// destroy (all) the touched object(s)
foreach(var obj in _currentlyTouching)
{
Destroy(obj);
}
// Don't forget to also clear the HashSet in that case
_currentlyTouching.Clear();
}
}
Таким образом, вы разделяете пользовательский ввод Update
(каждый кадр) и отслеживаете только вход и выход коллайдеров с помощью системы на основе Physcis.