/** Tick */ void UFluidSurfaceComponent::TickComponent( float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction ) { Super::TickComponent( DeltaTime, TickType, ThisTickFunction ); LastDeltaTime = DeltaTime; float SimStep = 1.f / UpdateRate; static float Time = 0.0f; #if WITH_EDITOR /* Only update if checked */ if( !UpdateComponent ) return; #endif /* If this water hasn't been rendered for a while, stop updating */ if (LastRenderTime > 0 && GetWorld()->TimeSeconds - LastRenderTime > 1) return; Time += DeltaTime; if( Time > SimStep ) { Time = 0.0f; LatestVerts = !LatestVerts; /* Add ripples for actors in the water */ TArray<struct FOverlapResult> OverlappingActors; FCollisionShape CollisionShape; CollisionShape.SetBox( FluidBoundingBox.GetExtent( ) ); /* Find overlapping actors */ GetWorld()->OverlapMultiByChannel(OverlappingActors, GetComponentLocation(), GetComponentQuat(), ECC_WorldDynamic, CollisionShape, FCollisionQueryParams(false)); // @todo: handle better /* Iterate through found overlapping actors */ for( int i = 0; i < OverlappingActors.Num( ); i++ ) { TWeakObjectPtr<AActor> Actor = OverlappingActors[ i ].Actor; /* Dont care about self and modifiers */ if( Actor != NULL && !Actor->IsA( AFluidSurfaceActor::StaticClass( ) ) && !Actor->IsA( AFluidSurfaceModifier::StaticClass( ) ) ) { FVector LocalVel = GetWorldToComponent( ).TransformVector( Actor->GetVelocity( ) ); float HorizVelMag = LocalVel.Size( ); Pling( Actor->GetActorLocation( ), RippleVelocityFactor * HorizVelMag, Actor->GetSimpleCollisionRadius( ) ); } } /* Do test ripple (moving around in a circle) */ if( GIsEditor && TestRipple ) { TestRippleAng += SimStep * MyU2Rad * TestRippleSpeed; FVector WorldRipplePos, LocalRipplePos; float RippleRadius = 0.3f * ( FluidXSize - 1 ) * FluidGridSpacing; if( FluidGridType == EFluidGridType::FGT_Hexagonal ) RippleRadius = FMath::Max( RippleRadius, 0.3f * ( FluidYSize - 1 ) * FluidGridSpacing * ROOT3OVER2 ); else RippleRadius = FMath::Max( RippleRadius, 0.3f * ( FluidYSize - 1 ) * FluidGridSpacing ); LocalRipplePos.X = ( RippleRadius * FMath::Sin( TestRippleAng ) ); LocalRipplePos.Y = ( RippleRadius * FMath::Cos( TestRippleAng ) ); LocalRipplePos.Z = 0.f; WorldRipplePos = ComponentToWorld.TransformPosition( LocalRipplePos ); Pling( WorldRipplePos, TestRippleStrength, TestRippleRadius ); } /* Add modifier effects */ for( int i = 0; i < Modifiers.Num( ); i++ ) { if( Modifiers[ i ] && Modifiers[ i ]->Active ) Modifiers[ i ]->Update( DeltaTime ); } /* Need to send new dynamic data */ MarkRenderDynamicDataDirty( ); } }