Playing sound when something is moving in Unreal?

I’ve been trying to work out how to add sound to a mover (when it moves obviously) for a while now and I’m only coming up with terrible hacks (like adding a trigger for the wall to slide into which triggers a sound file). That works for a slider disappearing of the map (to an inaccessible location), but not for a door that rotates open as the trigger is present in the world and could be set off by anything. I know I could add tags so only the door triggers it, like the key and lock in the video, but is just feels like more hacks on hacks…

Is there a blueprint (so I can set a different sound for each actor) or C++ I can use to simply play a sound once whilst a static mesh (the door) is moving?

Thanks,
Matthew

I’m not sure if this is the best implementation, but it seems to work. I added a USoundBase* Sound in mover.h so I can select the sound specifically for each mover (like sliding stone or creaking doors), and some variables to start the play and not restart it until the movement has stopped.

I’m interested to hear if there is a better or built in method?

void UMover::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
	
	FRotator CurrentRotation = GetOwner()->GetActorRotation();
	FRotator TargetRotation = OriginalRotation;
	FVector CurrentLocation = GetOwner()->GetActorLocation();
	FVector TargetLocation = OriginalLocation;
	if (ShouldMove == true)
	{
		TargetRotation = RotateOffset + OriginalRotation;
		TargetLocation = MoveOffset + OriginalLocation;
	}
	float Speed = MoveOffset.Length() / MoveTime;
	float RotSpeed = 45; // degrees per second. I can't convert rotaion into degrees (per second) so I'll just set a speed and don't worry about frame rate independence.
// check if the rotaitons are almost equal or the locations are almost equal (so it works for a slidiong wall or rotating door
	if ((!CurrentRotation.Equals(OriginalRotation, 5) && !CurrentRotation.Equals(RotateOffset + OriginalRotation, 5))
		|| (!CurrentLocation.Equals(OriginalLocation, 5) && !CurrentLocation.Equals(MoveOffset + OriginalLocation, 5))) 
	{
		PlaySound(true);
	}
	else PlayingSound = false;

	FRotator NewRotation = FMath::RInterpConstantTo(CurrentRotation, TargetRotation, DeltaTime, RotSpeed);
	FVector NewLocation = FMath::VInterpConstantTo(CurrentLocation, TargetLocation, DeltaTime, Speed);
	GetOwner()->SetActorRotation(NewRotation);
	GetOwner()->SetActorLocation(NewLocation);
}

void UMover::PlaySound(bool PlayNow)
{
	if (Sound && PlayNow == true && !PlayingSound )
	{
		UGameplayStatics::PlaySoundAtLocation(this, Sound, GetOwner()->GetActorLocation());
		PlayingSound  = true;
	}
}

Thanks,
Matthew

I would suggest using an audio component instead so you don’t need to manually keep track of its state and you can just use its member functions instead (IsPlaying())

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms