int32 USoundNodeRandom::ChooseNodeIndex(FActiveSound& ActiveSound) { int32 NodeIndex = 0; float WeightSum = 0.0f; #if WITH_EDITOR bool bIsPIESound = (GEditor != nullptr) && ((GEditor->bIsSimulatingInEditor || GEditor->PlayWorld != nullptr) && ActiveSound.GetWorldID() > 0); if (bIsPIESound) { // Find the first available index - needed if there is only one while (PIEHiddenNodes.Contains(NodeIndex)) { NodeIndex++; } } #endif //WITH_EDITOR // only calculate the weights that have not been used and use that set for the random choice for (int32 i = 0; i < Weights.Num(); ++i) { #if WITH_EDITOR if (!bIsPIESound || !PIEHiddenNodes.Contains(i)) #endif //WITH_EDITOR { if (!bRandomizeWithoutReplacement || !HasBeenUsed[i]) { WeightSum += Weights[i]; } } } float Choice = FMath::FRand() * WeightSum; WeightSum = 0.0f; for (int32 i = 0; i < ChildNodes.Num() && i < Weights.Num(); ++i) { #if WITH_EDITOR if (!bIsPIESound || !PIEHiddenNodes.Contains(i)) #endif //WITH_EDITOR { if (bRandomizeWithoutReplacement && HasBeenUsed[i]) { continue; } WeightSum += Weights[i]; if (Choice < WeightSum) { NodeIndex = i; HasBeenUsed[i] = true; NumRandomUsed++; break; } } } return NodeIndex; }
void USoundNodeRandom::ParseNodes( FAudioDevice* AudioDevice, const UPTRINT NodeWaveInstanceHash, FActiveSound& ActiveSound, const FSoundParseParameters& ParseParams, TArray<FWaveInstance*>& WaveInstances ) { RETRIEVE_SOUNDNODE_PAYLOAD(sizeof(int32)); DECLARE_SOUNDNODE_ELEMENT(int32, NodeIndex); // Pick a random child node and save the index. if (*RequiresInitialization) { NodeIndex = ChooseNodeIndex(ActiveSound); *RequiresInitialization = 0; } #if WITH_EDITOR bool bIsPIESound = (GEditor != nullptr) && ((GEditor->bIsSimulatingInEditor || GEditor->PlayWorld != nullptr) && ActiveSound.GetWorldID() > 0); #endif //WITH_EDITOR // check to see if we have used up our random sounds if (bRandomizeWithoutReplacement && (HasBeenUsed.Num() > 0) && (NumRandomUsed >= HasBeenUsed.Num() #if WITH_EDITOR || (bIsPIESound && NumRandomUsed >= (HasBeenUsed.Num() - PIEHiddenNodes.Num())) #endif //WITH_EDITOR )) { // reset all of the children nodes for (int32 i = 0; i < HasBeenUsed.Num(); ++i) { if (HasBeenUsed.Num() > NodeIndex) { HasBeenUsed[i] = false; } } // set the node that has JUST played to be true so we don't repeat it HasBeenUsed[NodeIndex] = true; NumRandomUsed = 1; } if (NodeIndex < ChildNodes.Num() && ChildNodes[NodeIndex]) { ChildNodes[NodeIndex]->ParseNodes(AudioDevice, GetNodeWaveInstanceHash(NodeWaveInstanceHash, ChildNodes[NodeIndex], NodeIndex), ActiveSound, ParseParams, WaveInstances); } }