@Kiger

Как не использовать OnTriggerStay в моей ситуации?

сначала я написал вот такой код для поднятие одного оружия и выброс другого:
private void OnTriggerStay2D(Collider2D collision)
    {
        if(collision.TryGetComponent<Weapon>(out Weapon weapon) && Input.GetKeyDown(KeyCode.F))
        {
            pickUp(weapon, weapon.transform.position);
        }
    }

    private void pickUp(Weapon weapon, Vector3 weaponPosition)
    {
        if (_Weapon != null)
        {
            _Weapon.transform.parent = null;
        }

        _Weapon = weapon;
        _Weapon.transform.parent = transform;
        _Weapon.transform.position = _PointPossitionWeapon.position;
    }

но заметил что работает он через раз
чуть позже узнал что OnTriggerStay не срабатывает каждый кадр, но как мне его заменить?
  • Вопрос задан
  • 83 просмотра
Решения вопроса 1
K0TlK
@K0TlK
Буллю людей.
Отделяй обработку инпута и тогда таких проблем не будет.
Weapon

public class Weapon : MonoBehaviour
{
    public void Hide()
    {
        gameObject.SetActive(false);
    }
}


PlayerInput

Отслеживает нажатие нужной кнопки в вызывает нужный ивент
public class PlayerInput : MonoBehaviour
{
    public event Action InteractionButtonPressed = delegate {  };

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            InteractionButtonPressed();
        }
    }
}


PickUpArea

Область подбора. При входе в триггер добавляет айтем в список, при выходе удаляет. Если вызывать PickUp - вернет ближайший из айтемов
public class PickUpArea : MonoBehaviour
{
    private readonly List<Weapon> _closeWeapons = new();

    public bool HasItemsAround => _closeWeapons.Count > 0;
        
    public void PickUp(PlayableCharacter character)
    {
        var closestWeapon = GetClosestWeapon();
        _closeWeapons.Remove(closestWeapon);
        character.Give(closestWeapon);
    }

    private Weapon GetClosestWeapon()
    {
        Weapon closest = null;
        var minDistance = float.MaxValue;

        foreach (var weapon in _closeWeapons)
        {
            var distance = (transform.position - weapon.transform.position).sqrMagnitude;
                
            if (distance < minDistance)
            {
                closest = weapon;
                minDistance = distance;
            }
        }
            
        return closest;
    }

    private void OnTriggerEnter2D(Collider2D col)
    {
        if (col.TryGetComponent(out Weapon weapon))
        {
            _closeWeapons.Add(weapon);
        }
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.TryGetComponent(out Weapon weapon))
        {
            _closeWeapons.Remove(weapon);
        }
    }
}


PlayableCharacter

Персонаж, которым управляет игрок. Когда нажмется нужная кнопка в инпуте, он попытается поднять айтем, если он есть поблизости.

public class PlayableCharacter : MonoBehaviour
{
    [SerializeField] private PlayerInput _input;
    [SerializeField] private PickUpArea _pickUpArea;
    [SerializeField] private List<Weapon> _weapons = new();

    private void Start()
    {
        _input.InteractionButtonPressed += TryPickUp;
    }

    private void OnDestroy()
    {
        _input.InteractionButtonPressed -= TryPickUp;
    }

    public void Give(Weapon weapon)
    {
        weapon.Hide();
        _weapons.Add(weapon);
    }

    private void TryPickUp()
    {
        if (_pickUpArea.HasItemsAround)
        {
            _pickUpArea.PickUp(this);
        }
    }
}

Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Amir228
@Amir228
Ты можешь использовать класс в Physics или Physics2D, и такие методы как например BoxCast или SphereCast.
Документация
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы