My solution with only one boolean

Hello there!

I just want to show my solution using only one bolean and playing the sound only when the door “hits” the door frame (and locks or unlocks).

The boolean is defined in the header file as:

private:
    // Indicates if the lock door sound for closing has already been played
    bool bHasBeenClosed = true;

Then, the implementation goes like this:

// Called every frame
void UOpenDoor::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    if(TotalMassOfActors() >= PressurePlateMassThresshold){
        OpenDoor(DeltaTime);
        DoorLastOpened = GetWorld()->GetTimeSeconds();
    } else{
        if((GetWorld()->GetTimeSeconds() - DoorLastOpened) > DoorCloseDelay){
            CloseDoor(DeltaTime);
        }
    }
}

void UOpenDoor::OpenDoor(float DeltaTime){
    //Check if door is closed to play lock sound
    if(FMath::IsNearlyEqual(CurrentYaw, InitialYaw, 0.2f)){
        if(AudioComponent && !AudioComponent->IsPlaying()){
            AudioComponent->Play();
            bHasBeenClosed = false; //Resets the flag to enable the sound when the door closes again
        }
    }

    // Round to TargetYaw when it is very near to that value to avoid infinite aproximation
    if(CurrentYaw != TargetYaw){
        if(FMath::IsNearlyEqual(CurrentYaw, TargetYaw, 0.1f)){
            CurrentYaw = TargetYaw;
        } else{
            CurrentYaw = FMath::Lerp(CurrentYaw, TargetYaw, DeltaTime * .5f);
        }

        FRotator DoorRotation = GetOwner()->GetActorRotation();
        DoorRotation.Yaw = CurrentYaw;
        GetOwner()->SetActorRotation(DoorRotation);
    }
}

void UOpenDoor::CloseDoor(float DeltaTime){
    // Check if door are closing to play lock sound
    if(FMath::IsNearlyEqual(CurrentYaw, InitialYaw, 0.2f)){
        // If the door has already played the lock sound, we dont repeat again and again, thats the reason for bHasBeenClosed
        if((AudioComponent) && (!AudioComponent->IsPlaying()) && (!bHasBeenClosed)){
            AudioComponent->Play();
            bHasBeenClosed = true;
        }
    }

    // Round to InitialYaw when it is very near to that value to avoid infinite aproximation
    if(CurrentYaw != InitialYaw){
        if(FMath::IsNearlyEqual(CurrentYaw, InitialYaw, 0.1f)){
            CurrentYaw = InitialYaw;
        } else{
            CurrentYaw = FMath::Lerp(CurrentYaw, InitialYaw, DeltaTime * 2.f);
        }

        FRotator DoorRotation = GetOwner()->GetActorRotation();
        DoorRotation.Yaw = CurrentYaw;
        GetOwner()->SetActorRotation(DoorRotation);
    }
}

I hope this can be useful for someone.
:smiley:

2 Likes

This is extremely useful :100:

1 Like

Thank You <3 this one is really helpful.

1 Like

Privacy & Terms