Closing a door on a Unit

I put my doors in the direct center of the GridPosition they’re on, so if a unit is also on that position when the door is closed they end up halfway through it. My first thought was to prevent interacting with the door with this check in InteractAction.GetValidActionGridPositionList():

if(testGridPosition == unitGridPosition) { continue; }

In the lecture following this one we refactor doors to work with a broader IInteractable interface. Some of those interactables are likely to work better if the unit can use the InteractAction while in the same GridPosition, so that original fix became a problem. I also realized my solution only solved the issue if the current active unit was the one in the door, not if any unit was.

My current way to handle it is to check if there’s a Unit in the way of the door and, if so, animating the door closing then opening while dealing a small amount of damage to the Unit.

    [SerializeField] float _animationLength = 0.9f;
    [SerializeField] int _damage = 5;

    Unit _unitInDoor;
    bool _isCycling;

    static readonly int IS_OPEN_HASH = Animator.StringToHash("IsOpen");

    void Update()
    {
        if(!_isActive) { return; }

        _timer -= Time.deltaTime;

        if(_isCycling && _timer <= _animationLength)
        {
            CompleteBlockedDoorCycle();
        }

        if(_timer <= 0)
        {
            _isActive = false;
            _onInteractionComplete();
        }
    }

    public void Interact(Action onInteractionComplete)
    {
        this._onInteractionComplete = onInteractionComplete;
        _isActive = true;

        _unitInDoor = LevelGrid.Instance.GetUnitAtGridPosition(_gridPosition);

        if(_unitInDoor != null)
        {
            _timer = _animationLength * 2;
            StartBlockedDoorCycle();
            return;
        }

        _timer = _animationLength;

        if(_isOpen)
        {
            CloseDoor();
        }
        else
        {
            OpenDoor();
        }
    }

    void StartBlockedDoorCycle()
    {
        _isCycling = true;
        _animator.SetBool(IS_OPEN_HASH, false);
    }

    void CompleteBlockedDoorCycle()
    {
        _unitInDoor.Damage(_damage);
        _animator.SetBool(IS_OPEN_HASH, true);
        _isCycling = false;
    }
2 Likes

Privacy & Terms