void UChildActorComponent::CreateChildActor() { // Kill spawned actor if we have one DestroyChildActor(); // This is no longer needed if (CachedInstanceData) { delete CachedInstanceData; CachedInstanceData = nullptr; } // If we have a class to spawn. if(ChildActorClass != nullptr) { UWorld* World = GetWorld(); if(World != nullptr) { // Before we spawn let's try and prevent cyclic disaster bool bSpawn = true; AActor* Actor = GetOwner(); while (Actor && bSpawn) { if (Actor->GetClass() == ChildActorClass) { bSpawn = false; UE_LOG(LogChildActorComponent, Error, TEXT("Found cycle in child actor component '%s'. Not spawning Actor of class '%s' to break."), *GetPathName(), *ChildActorClass->GetName()); } Actor = Actor->ParentComponentActor.Get(); } if (bSpawn) { FActorSpawnParameters Params; Params.bNoCollisionFail = true; Params.bDeferConstruction = true; // We defer construction so that we set ParentComponentActor prior to component registration so they appear selected Params.bAllowDuringConstructionScript = true; Params.OverrideLevel = GetOwner()->GetLevel(); Params.Name = ChildActorName; if (!HasAllFlags(RF_Transactional)) { Params.ObjectFlags &= ~RF_Transactional; } // Spawn actor of desired class FVector Location = GetComponentLocation(); FRotator Rotation = GetComponentRotation(); ChildActor = World->SpawnActor(ChildActorClass, &Location, &Rotation, Params); // If spawn was successful, if(ChildActor != nullptr) { ChildActorName = ChildActor->GetFName(); // Remember which actor spawned it (for selection in editor etc) ChildActor->ParentComponentActor = GetOwner(); ChildActor->AttachRootComponentTo(this); // Parts that we deferred from SpawnActor ChildActor->FinishSpawning(ComponentToWorld); } } } } }
void UCarditWeapon::Fire() { auto Camera = Cast<ACarditCharacter>(GetOwner())->GetCamera(); auto CameraLocation = Camera->GetComponentLocation(); auto EndLocation = Camera->GetComponentLocation() + (Camera->GetComponentRotation().Vector() * MaxRangeInCm); DrawDebugLine(GetWorld(), CameraLocation, EndLocation, FColor(255, 0, 0), false, 5.f, 0, 2.5f); FHitResult OutHit; if (GetWorld()->LineTraceSingleByChannel( OutHit, CameraLocation, EndLocation, ECC_Visibility ) ) { if (Cast<ACarditCharacter>(OutHit.GetActor())) { GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, "Character hit"); Cast<ACarditGameMode>(UGameplayStatics::GetGameMode(GetWorld()))->DealDamageOntoCharacter(Cast<ACarditCharacter>(OutHit.GetActor()), DamagePerShot); } else { UE_LOG(LogTemp, Warning, TEXT("Non-character hit")); } } else { UE_LOG(LogTemp, Warning, TEXT("Nothing hit")); } }
bool USpotLightComponent::AffectsBounds(const FBoxSphereBounds& Bounds) const { if(!Super::AffectsBounds(Bounds)) { return false; } float ClampedInnerConeAngle = FMath::Clamp(InnerConeAngle,0.0f,89.0f) * (float)PI / 180.0f, ClampedOuterConeAngle = FMath::Clamp(OuterConeAngle * (float)PI / 180.0f,ClampedInnerConeAngle + 0.001f,89.0f * (float)PI / 180.0f + 0.001f); float Sin = FMath::Sin(ClampedOuterConeAngle), Cos = FMath::Cos(ClampedOuterConeAngle); FVector U = GetComponentLocation() - (Bounds.SphereRadius / Sin) * GetDirection(), D = Bounds.Origin - U; float dsqr = D | D, E = GetDirection() | D; if(E > 0.0f && E * E >= dsqr * FMath::Square(Cos)) { D = Bounds.Origin - GetComponentLocation(); dsqr = D | D; E = -(GetDirection() | D); if(E > 0.0f && E * E >= dsqr * FMath::Square(Sin)) return dsqr <= FMath::Square(Bounds.SphereRadius); else return true; } return false; }
bool UMWBotSensorComponent::CheckLOS(const AActor* Actor, bool& OutCanHear) const { if (!Actor/* || bCrazy*/) { return false; } bool canSee = false; float dist = (GetComponentLocation() - Actor->GetActorLocation()).Size(); if (dist < SeeDistance) { FHitResult hit; FCollisionQueryParams params; params.AddIgnoredActor(GetOwner()); GetWorld()->LineTraceSingle(hit, GetComponentLocation(), Actor->GetActorLocation(), ECollisionChannel::ECC_Visibility, params); canSee = hit.bBlockingHit && (Actor == hit.Actor); } OutCanHear = canSee && (dist < HearDistance); return canSee; }
EPathFindingState UGettingEndNode::FindPath(UWorld* world, FPathFindingInformation& pathFindInfo, TArray<FVector>& resultRoute) { if (pathFindInfo.WaypointList.Num() == 0) return EPathFindingState::None; if (index == 0) { pathFindInfo.EndNode = pathFindInfo.WaypointList[0]; minDistance = (pathFindInfo.EndNode->GetComponentLocation() - pathFindInfo.EndLocation).Size(); index++; } while (index < pathFindInfo.WaypointList.Num()) { auto currentNode = pathFindInfo.WaypointList[index]; auto currentDistance = (currentNode->GetComponentLocation() - pathFindInfo.EndLocation).Size(); if (currentDistance < minDistance) { if (!world->LineTraceTestByObjectType(pathFindInfo.EndLocation, currentNode->GetComponentLocation(), FCollisionObjectQueryParams(ECollisionChannel::ECC_WorldStatic))) { pathFindInfo.EndNode = currentNode; minDistance = currentDistance; } } index++; if (pathFindInfo.Timer->GetElapsedTimeFromStart(0) >= pathFindInfo.MaxCaluclationTime) return EPathFindingState::GettingEndNode; } return EPathFindingState::LoadingFromDataMap; }
void UTB_AimComponent::HitLineTrace(FHitResult &OutHit) { if (!EnemyTarget) { UE_LOG(TB_Log, Error, TEXT("HitLineTrace(): EnemyTarget == NULL")); return; } //find the hit locations TArray<FVector> HitLocations; EnemyTarget->GetHitLocations(HitLocations); // shuffle them and do line traces until we get a hit UTB_Library::Shuffle(HitLocations); FCollisionQueryParams Params; InitCollisionQueryParams(Params); FCollisionObjectQueryParams ObjectParams; FVector StartLocation = GetComponentLocation(); for (auto HitLocation : HitLocations) { bool HitSomething = World->LineTraceSingle(OutHit, StartLocation, HitLocation, Params, ObjectParams); if (HitSomething && EnemyTarget->GetUniqueID() == OutHit.Actor->GetUniqueID()) { return; } } UE_LOG(TB_Log, Error, TEXT("HitLineTrace(): Could not find a hitting line trace")); }
void UTankTrack::DriveTrack() { auto ForceApplied = GetForwardVector() * CurrentThrottle * TrackMaxDrivingForce; auto ForceLocation = GetComponentLocation(); auto TankRoot = Cast<UPrimitiveComponent>(GetOwner()->GetRootComponent()); TankRoot->AddForceAtLocation(ForceApplied, ForceLocation); }
void UMWBotWeaponComponent::Fire() { if (!CanFire()) { return; } // cast a line FHitResult hit; FCollisionQueryParams traceParams; traceParams.AddIgnoredActor(GetOwner()); const int32 randSeed = FMath::Rand(); FRandomStream randStream(randSeed); const FVector traceStart = GetComponentLocation(); const FVector aimDir = GetComponentRotation().Vector(); const FVector shotDir = randStream.VRandCone(aimDir, FMath::DegreesToRadians(Spread)); const FVector traceEnd = traceStart + shotDir * 1e5; GetWorld()->LineTraceSingle(hit, traceStart, traceEnd, ECollisionChannel::ECC_Visibility, traceParams); ProcessHit(hit); // temporary draw if (hit.bBlockingHit) { DrawDebugLine(GetWorld(), traceStart, hit.ImpactPoint, FColor::Red, false, -1.f, 0, 10); } else { DrawDebugLine(GetWorld(), traceStart, traceEnd, FColor::Red, false, -1.f, 0, 10); } }
void UMWBotSensorComponent::LookAt(const AActor* Actor, const FVector Point) { //if (bCrazy) //{ // return; //} // Convert aim direction to eye parent's local space FVector aimDirWS = Actor ? Actor->GetActorLocation() : Point; // world space aimDirWS -= GetComponentLocation(); FVector aimDirLS; // local space if (AttachParent) { // If attached to socket, use socket transform if (!AttachSocketName.IsNone()) { aimDirLS = AttachParent->GetSocketTransform(AttachSocketName, ERelativeTransformSpace::RTS_World).InverseTransformVectorNoScale(aimDirWS); } else { aimDirLS = AttachParent->GetComponentTransform().InverseTransformVectorNoScale(aimDirWS); } } else { aimDirLS = aimDirWS; } DesiredRotation = aimDirLS.Rotation(); }
void UFireComponent::OnDoAction_Implementation() { if (CheckCoolTime && IsCoolTimeOver() == false) { return; } if (ActionObject != nullptr) { UWorld* const World = GetWorld(); if (World) { // Set the spawn parameters. FActorSpawnParameters SpawnParams; SpawnParams.Owner = GetOwner(); // Get a random location to spawn at. FVector SpawnLocation = GetComponentLocation(); // Get a random rotation for the spawned item. FRotator SpawnRotation = GetComponentRotation(); ANruActionObject * actor = World->SpawnActor<ANruActionObject>(ActionObject, SpawnLocation, SpawnRotation, SpawnParams); actor->Level = Level; } } if (CheckCoolTime) { CurCoolTime = 0.f; } }
void UCameraComponent::GetCameraView(float DeltaTime, FMinimalViewInfo& DesiredView) { if (bUsePawnControlRotation) { if (APawn* OwningPawn = Cast<APawn>(GetOwner())) { const FRotator PawnViewRotation = OwningPawn->GetViewRotation(); if (!PawnViewRotation.Equals(GetComponentRotation())) { SetWorldRotation(PawnViewRotation); } } } DesiredView.Location = GetComponentLocation(); DesiredView.Rotation = GetComponentRotation(); DesiredView.FOV = FieldOfView; DesiredView.AspectRatio = AspectRatio; DesiredView.bConstrainAspectRatio = bConstrainAspectRatio; DesiredView.ProjectionMode = ProjectionMode; DesiredView.OrthoWidth = OrthoWidth; // See if the CameraActor wants to override the PostProcess settings used. DesiredView.PostProcessBlendWeight = PostProcessBlendWeight; if (PostProcessBlendWeight > 0.0f) { DesiredView.PostProcessSettings = PostProcessSettings; } }
void URadialForceComponent::FireImpulse() { const FVector Origin = GetComponentLocation(); // Find objects within the sphere static FName FireImpulseOverlapName = FName(TEXT("FireImpulseOverlap")); TArray<FOverlapResult> Overlaps; FCollisionQueryParams Params(FireImpulseOverlapName, false); Params.bTraceAsyncScene = true; // want to hurt stuff in async scene // Ignore owner actor if desired if (bIgnoreOwningActor) { Params.AddIgnoredActor(GetOwner()); } GetWorld()->OverlapMultiByObjectType(Overlaps, Origin, FQuat::Identity, CollisionObjectQueryParams, FCollisionShape::MakeSphere(Radius), Params); // A component can have multiple physics presences (e.g. destructible mesh components). // The component should handle the radial force for all of the physics objects it contains // so here we grab all of the unique components to avoid applying impulses more than once. TArray<UPrimitiveComponent*, TInlineAllocator<1>> AffectedComponents; AffectedComponents.Reserve(Overlaps.Num()); for(FOverlapResult& OverlapResult : Overlaps) { if(UPrimitiveComponent* PrimitiveComponent = OverlapResult.Component.Get()) { AffectedComponents.AddUnique(PrimitiveComponent); } } for(UPrimitiveComponent* PrimitiveComponent : AffectedComponents) { if(DestructibleDamage > SMALL_NUMBER) { if(UDestructibleComponent* DestructibleComponent = Cast<UDestructibleComponent>(PrimitiveComponent)) { DestructibleComponent->ApplyRadiusDamage(DestructibleDamage, Origin, Radius, ImpulseStrength, Falloff == RIF_Constant); } } // Apply impulse PrimitiveComponent->AddRadialImpulse(Origin, Radius, ImpulseStrength, Falloff, bImpulseVelChange); // See if this is a target for a movement component, if so apply the impulse to it TInlineComponentArray<UMovementComponent*> MovementComponents; PrimitiveComponent->GetOwner()->GetComponents<UMovementComponent>(MovementComponents); for(const auto& MovementComponent : MovementComponents) { if(MovementComponent->UpdatedComponent == PrimitiveComponent) { MovementComponent->AddRadialImpulse(Origin, Radius, ImpulseStrength, Falloff, bImpulseVelChange); break; } } } }
void URadialForceComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); if(bIsActive) { const FVector Origin = GetComponentLocation(); // Find objects within the sphere static FName AddForceOverlapName = FName(TEXT("AddForceOverlap")); TArray<FOverlapResult> Overlaps; FCollisionQueryParams Params(AddForceOverlapName, false); Params.bTraceAsyncScene = true; // want to hurt stuff in async scene // Ignore owner actor if desired if (bIgnoreOwningActor) { Params.AddIgnoredActor(GetOwner()); } GetWorld()->OverlapMultiByObjectType(Overlaps, Origin, FQuat::Identity, CollisionObjectQueryParams, FCollisionShape::MakeSphere(Radius), Params); // A component can have multiple physics presences (e.g. destructible mesh components). // The component should handle the radial force for all of the physics objects it contains // so here we grab all of the unique components to avoid applying impulses more than once. TArray<UPrimitiveComponent*, TInlineAllocator<1>> AffectedComponents; AffectedComponents.Reserve(Overlaps.Num()); for(FOverlapResult& OverlapResult : Overlaps) { if(UPrimitiveComponent* PrimitiveComponent = OverlapResult.Component.Get()) { AffectedComponents.AddUnique(PrimitiveComponent); } } for(UPrimitiveComponent* PrimitiveComponent : AffectedComponents) { PrimitiveComponent->AddRadialForce(Origin, Radius, ForceStrength, Falloff); // see if this is a target for a movement component AActor* ComponentOwner = PrimitiveComponent->GetOwner(); if(ComponentOwner) { TInlineComponentArray<UMovementComponent*> MovementComponents; ComponentOwner->GetComponents<UMovementComponent>(MovementComponents); for(const auto& MovementComponent : MovementComponents) { if(MovementComponent->UpdatedComponent == PrimitiveComponent) { MovementComponent->AddRadialForce(Origin, Radius, ForceStrength, Falloff); break; } } } } } }
void UTankTrack::SetThrottle(float Throttle) { auto Name = GetName(); UE_LOG(LogTemp, Warning, TEXT("%s throttle: %f"), *Name, Throttle); auto ForceApplied = Throttle * TrackMaxDrivingForce * GetForwardVector(); auto ForceLocation = GetComponentLocation(); auto TankRootComponent = Cast<UPrimitiveComponent>(GetOwner()->GetRootComponent()); TankRootComponent->AddForceAtLocation(ForceApplied, ForceLocation); }
void UTankTrack::DriveTrack() { if (ensure(TankRoot)) { FVector ForceApplied = GetForwardVector() * CurrentThrottle * TrackMaxDrivingForce; FVector ForceLocation = GetComponentLocation(); TankRoot->AddForceAtLocation(ForceApplied, ForceLocation); } }
void USpineBoneDriverComponent::BeforeUpdateWorldTransform(USpineSkeletonComponent* skeleton) { if (skeleton == lastBoundComponent) { if (UseComponentTransform) { skeleton->SetBoneWorldPosition(BoneName, GetComponentLocation()); } else { AActor* owner = GetOwner(); if (owner) skeleton->SetBoneWorldPosition(BoneName, owner->GetActorLocation()); } } }
int32 UTB_AimComponent::CoverModifier(ATB_Character *Target) { UWorld *World = GetWorld(); // Ignore collisions with the aiming character and its weapon FCollisionQueryParams Params; Params.bTraceComplex = true; Params.AddIgnoredActor(Character); if (Weapon) { Params.AddIgnoredActor(Weapon); } if (Target->Weapon) { Params.AddIgnoredActor(Target->Weapon); } // uncomment to draw debug lines /* FName TraceTag("CoverTrace"); World->DebugDrawTraceTag = TraceTag; Params.TraceTag = TraceTag; */ FCollisionObjectQueryParams ObjectParams; FHitResult HitResult; TArray<FVector> HitLocations; Target->GetHitLocations(HitLocations); FVector StartLocation = GetComponentLocation(); int Hidden = 0; for (auto HitLocation : HitLocations) { bool HitSomething = World->LineTraceSingle(HitResult, StartLocation, HitLocation, Params, ObjectParams); if (HitSomething && Target->GetUniqueID() != HitResult.Actor->GetUniqueID()) { Hidden++; } } if (Hidden < HitLocations.Num()) { // reduce cover by half if we can see the enemy at all // a penalty above 60 makes an enemy virtually impossible to hit Hidden -= (Hidden / 3); } return (Hidden * -100) / std::max(HitLocations.Num(), 1); }
bool UMWBotSensorComponent::CheckAOS(const AActor* Actor, float Angle) const { // Calculate dot product of two vector and check the angle between them if (!Actor/* || bCrazy*/) { return false; } const FVector toActor = (Actor->GetActorLocation() - GetComponentLocation()).SafeNormal(); const FVector sightOrt = GetComponentRotation().Vector(); const float dotProd = toActor | sightOrt; const float cosA = FMath::Cos(FMath::DegreesToRadians(Angle)); return dotProd > cosA; }
void UPhysicsConstraintComponent::UpdateConstraintFrames() { FTransform A1Transform = GetBodyTransform(EConstraintFrame::Frame1); A1Transform.RemoveScaling(); FTransform A2Transform = GetBodyTransform(EConstraintFrame::Frame2); A2Transform.RemoveScaling(); // World ref frame const FVector WPos = GetComponentLocation(); const FVector WPri = ComponentToWorld.GetUnitAxis( EAxis::X ); const FVector WOrth = ComponentToWorld.GetUnitAxis( EAxis::Y ); ConstraintInstance.Pos1 = A1Transform.InverseTransformPosition(WPos); ConstraintInstance.PriAxis1 = A1Transform.InverseTransformVectorNoScale(WPri); ConstraintInstance.SecAxis1 = A1Transform.InverseTransformVectorNoScale(WOrth); const FVector RotatedX = ConstraintInstance.AngularRotationOffset.RotateVector(FVector(1,0,0)); const FVector RotatedY = ConstraintInstance.AngularRotationOffset.RotateVector(FVector(0,1,0)); const FVector WPri2 = ComponentToWorld.TransformVectorNoScale(RotatedX); const FVector WOrth2 = ComponentToWorld.TransformVectorNoScale(RotatedY); ConstraintInstance.Pos2 = A2Transform.InverseTransformPosition(WPos); ConstraintInstance.PriAxis2 = A2Transform.InverseTransformVectorNoScale(WPri2); ConstraintInstance.SecAxis2 = A2Transform.InverseTransformVectorNoScale(WOrth2); //Constraint instance is given our reference frame scale and uses it to scale position. //Note that the scale passed in is also used for limits, so we first undo the position scale so that it's consistent. //Note that in the case where there is no body instance, the position is given in world space and there is no scaling. const float RefScale = FMath::Max(GetConstraintScale(), 0.01f); if(GetBodyInstance(EConstraintFrame::Frame1)) { ConstraintInstance.Pos1 /= RefScale; } if (GetBodyInstance(EConstraintFrame::Frame2)) { ConstraintInstance.Pos2 /= RefScale; } }
/** Calc Bounds */ FBoxSphereBounds UFluidSurfaceComponent::CalcBounds( const FTransform& LocalToWorld ) const { FBoxSphereBounds NewBounds; /*if( BodySetup ) { FBox AggGeomBox = BodySetup->AggGeom.CalcAABB( LocalToWorld ); if( AggGeomBox.IsValid ) { NewBounds = FBoxSphereBounds( AggGeomBox ); } } else*/ { FBox NewBox = FBox( FVector( -( ( FluidXSize * FluidGridSpacing ) / 2.0f ), -( ( FluidYSize * FluidGridSpacing ) / 2.0f ), -10.0f ), FVector( ( FluidXSize * FluidGridSpacing ) / 2.0f, ( FluidYSize * FluidGridSpacing ) / 2.0f, 10.0f ) ); NewBounds = FBoxSphereBounds( NewBox ); NewBounds.Origin = GetComponentLocation( ); } return NewBounds; }
void UFlareAsteroidComponent::SetupEffects(bool Icy) { IsIcyAsteroid = Icy; Effects.Empty(); EffectsKernels.Empty(); AFlareAsteroid* Asteroid = Cast<AFlareAsteroid>(GetOwner()); int32 Multiplier = Asteroid ? Asteroid->EffectsMultiplier : 1; // Create random effects for (int32 Index = 0; Index < Multiplier * EffectsCount; Index++) { EffectsKernels.Add(FMath::VRand()); UParticleSystemComponent* PSC = UGameplayStatics::SpawnEmitterAttached( IceEffectTemplate, this, NAME_None, GetComponentLocation(), FRotator::ZeroRotator, EAttachLocation::KeepWorldPosition, false); PSC->SetWorldScale3D(EffectsScale * FVector(1, 1, 1)); Effects.Add(PSC); if (IsIcyAsteroid) { PSC->SetTemplate(IceEffectTemplate); } else { PSC->SetTemplate(DustEffectTemplate); } } }
void UDebugHandUtility::DebugHandOrientation(UAnimHand* AnimHand) { DebugOrientation(AnimHand->Wrist->Orientation, AnimHand->Wrist->Position + GetComponentLocation(), 50); }
/** 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( ); } }
void USpringArmComponent::UpdateDesiredArmLocation(bool bDoTrace, bool bDoLocationLag, bool bDoRotationLag, float DeltaTime) { FRotator DesiredRot = GetComponentRotation(); // If inheriting rotation, check options for which components to inherit if(!bAbsoluteRotation) { if(!bInheritPitch) { DesiredRot.Pitch = RelativeRotation.Pitch; } if (!bInheritYaw) { DesiredRot.Yaw = RelativeRotation.Yaw; } if (!bInheritRoll) { DesiredRot.Roll = RelativeRotation.Roll; } } // Apply 'lag' to rotation if desired if(bDoRotationLag) { DesiredRot = FMath::RInterpTo(PreviousDesiredRot, DesiredRot, DeltaTime, CameraRotationLagSpeed); } PreviousDesiredRot = DesiredRot; // Get the spring arm 'origin', the target we want to look at FVector ArmOrigin = GetComponentLocation() + TargetOffset; // We lag the target, not the actuall camera position, so rotating the camera around does not hav lag FVector DesiredLoc = ArmOrigin; if (bDoLocationLag) { DesiredLoc = FMath::VInterpTo(PreviousDesiredLoc, DesiredLoc, DeltaTime, CameraLagSpeed); } PreviousDesiredLoc = DesiredLoc; // Now offset camera position back along our rotation DesiredLoc -= DesiredRot.Vector() * TargetArmLength; // Add socket offset in local space DesiredLoc += FRotationMatrix(DesiredRot).TransformVector(SocketOffset); // Do a sweep to ensure we are not penetrating the world FVector ResultLoc; if (bDoTrace && (TargetArmLength != 0.0f)) { static FName TraceTagName(TEXT("SpringArm")); FCollisionQueryParams QueryParams(TraceTagName, false, GetOwner()); FHitResult Result; GetWorld()->SweepSingle(Result, ArmOrigin, DesiredLoc, FQuat::Identity, ProbeChannel, FCollisionShape::MakeSphere(ProbeSize), QueryParams); ResultLoc = BlendLocations(DesiredLoc, Result.Location, Result.bBlockingHit, DeltaTime); } else { ResultLoc = DesiredLoc; } // Form a transform for new world transform for camera FTransform WorldCamTM(DesiredRot, ResultLoc); // Convert to relative to component FTransform RelCamTM = WorldCamTM.GetRelativeTransform(ComponentToWorld); // Update socket location/rotation RelativeSocketLocation = RelCamTM.GetLocation(); RelativeSocketRotation = RelCamTM.GetRotation(); UpdateChildTransforms(); }
void UFlareInternalComponent::GetBoundingSphere(FVector& Location, float& SphereRadius) { SphereRadius = Radius * 100; // In cm Location = GetComponentLocation(); }
void UTerrainZoneComponent::ApplyTerrainMesh(TMeshDataPtr MeshDataPtr, bool bPutToCache) { double start = FPlatformTime::Seconds(); TMeshData* MeshData = MeshDataPtr.get(); if (MeshData == nullptr) { return; } if (CachedMeshDataPtr != nullptr && CachedMeshDataPtr->TimeStamp > MeshDataPtr->TimeStamp) { UE_LOG(LogTemp, Warning, TEXT("ASandboxTerrainZone::applyTerrainMesh skip late thread-> %f"), MeshDataPtr->TimeStamp); } if (bPutToCache) { CachedMeshDataPtr = MeshDataPtr; } //########################################## // draw debug points //########################################## /* MeshLodSection& section6 = mesh_data->MeshSectionLodArray[4]; for (auto p : section6.DebugPointList) { DrawDebugPoint(GetWorld(), p, 5, FColor(0, 0, 255, 100), false, 1000000); UE_LOG(LogTemp, Warning, TEXT("DebugPointList ---> %f %f %f "), p.X, p.Y, p.Z); } */ //########################################## //########################################## // mat section test //########################################## /* TMeshLodSection& section0 = MeshData->MeshSectionLodArray[0]; TMaterialSectionMap matSectionMap = section0.MaterialSectionMap; for (auto& Elem : matSectionMap) { short matId = Elem.Key; TMeshMaterialSection matSection = Elem.Value; UE_LOG(LogTemp, Warning, TEXT("material section -> %d - %d -> %d "), matId, matSection.MaterialId, matSection.MaterialMesh.ProcVertexBuffer.Num()); } */ /* TMaterialTransitionSectionMap& matTraSectionMap = section0.MaterialTransitionSectionMap; for (auto& Elem : matTraSectionMap) { short matId = Elem.Key; TMeshMaterialTransitionSection& matSection = Elem.Value; UE_LOG(LogTemp, Warning, TEXT("material transition section -> %d - [%s] -> %d "), matId, *matSection.TransitionName, matSection.MaterialMesh.ProcVertexBuffer.Num()); for (auto p : matSection.MaterialMesh.ProcVertexBuffer) { //DrawDebugPoint(GetWorld(), p.Position, 3, FColor(255, 255, 255, 100), false, 1000000); } } */ //########################################## MainTerrainMesh->SetMobility(EComponentMobility::Movable); MainTerrainMesh->AddLocalRotation(FRotator(0.0f, 0.01, 0.0f)); // workaround MainTerrainMesh->AddLocalRotation(FRotator(0.0f, -0.01, 0.0f)); // workaround MainTerrainMesh->bLodFlag = GetTerrainController()->bEnableLOD; MainTerrainMesh->SetMeshData(MeshDataPtr); MainTerrainMesh->SetMobility(EComponentMobility::Stationary); MainTerrainMesh->SetCastShadow(true); MainTerrainMesh->bCastHiddenShadow = true; MainTerrainMesh->SetVisibility(true); MainTerrainMesh->SetCollisionMeshData(MeshDataPtr); MainTerrainMesh->SetCollisionProfileName(TEXT("BlockAll")); double end = FPlatformTime::Seconds(); double time = (end - start) * 1000; UE_LOG(LogTemp, Warning, TEXT("ASandboxTerrainZone::applyTerrainMesh ---------> %f %f %f --> %f ms"), GetComponentLocation().X, GetComponentLocation().Y, GetComponentLocation().Z, time); }
void UFlareAsteroidComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); float CollisionSize = GetCollisionShape().GetExtent().Size(); EffectsUpdateTimer += DeltaTime; // Get player ship AFlareGame* Game = Cast<AFlareGame>(GetWorld()->GetAuthGameMode()); FCHECK(Game); AFlarePlayerController* PC = Game->GetPC(); FCHECK(PC); AFlareSpacecraft* ShipPawn = PC->GetShipPawn(); // Update if close to player and visible if (ShipPawn && (ShipPawn->GetActorLocation() - GetComponentLocation()).Size() < 500000 && (GetWorld()->TimeSeconds - LastRenderTime) < 0.5) { if (EffectsUpdateTimer > EffectsUpdatePeriod) { // World data FVector AsteroidLocation = GetComponentLocation(); FVector SunDirection = Game->GetPlanetarium()->GetSunDirection(); SunDirection.Normalize(); // Compute new FX locations for (int32 Index = 0; Index < Effects.Num(); Index++) { FVector RandomDirection = FVector::CrossProduct(SunDirection, EffectsKernels[Index]); RandomDirection.Normalize(); FVector StartPoint = AsteroidLocation + RandomDirection * CollisionSize; // Trace params FHitResult HitResult(ForceInit); FCollisionQueryParams TraceParams(FName(TEXT("Asteroid Trace")), false, NULL); TraceParams.bTraceComplex = true; TraceParams.bReturnPhysicalMaterial = false; ECollisionChannel CollisionChannel = ECollisionChannel::ECC_WorldDynamic; // Trace bool FoundHit = GetWorld()->LineTraceSingleByChannel(HitResult, StartPoint, AsteroidLocation, CollisionChannel, TraceParams); if (FoundHit && HitResult.Component == this && Effects[Index]) { FVector EffectLocation = HitResult.Location; if (!Effects[Index]->IsActive()) { Effects[Index]->Activate(); } Effects[Index]->SetWorldLocation(EffectLocation); Effects[Index]->SetWorldRotation(SunDirection.Rotation()); } else { Effects[Index]->Deactivate(); } } EffectsUpdateTimer = 0; } } // Disable all else { for (int32 Index = 0; Index < Effects.Num(); Index++) { Effects[Index]->Deactivate(); } } }
bool UTB_AimComponent::MissLineTrace(FHitResult &OutHit) { if (!EnemyTarget) { UE_LOG(TB_Log, Error, TEXT("MissLineTrace(): EnemyTarget == NULL")); return false; } //Pick a HitLocation at random TArray<FVector> HitLocations; EnemyTarget->GetHitLocations(HitLocations); UTB_Library::Shuffle(HitLocations); FCollisionQueryParams Params; InitCollisionQueryParams(Params); FCollisionObjectQueryParams ObjectParams; FVector StartLocation = GetComponentLocation(); float Offset = 30; for (auto HitLocation : HitLocations) { bool HitSomething = World->LineTraceSingle(OutHit, StartLocation, HitLocation, Params, ObjectParams); if (HitSomething) { if (EnemyTarget->GetUniqueID() != OutHit.Actor->GetUniqueID()) { //we've hit something we didn't aim for \o/ return true; } else { //we need to adjust the trace so it misses the target // Create a new vector for the trace FVector TraceVector = HitLocation - StartLocation; TraceVector.Normalize(); TraceVector *= Weapon->MaxRange; // Rotate it by 0-5 deg in all directions FRotator Offset(FMath::FRandRange(-10, 10), FMath::FRandRange(-10, 10), 0); TraceVector = Offset.RotateVector(TraceVector); HitSomething = World->LineTraceSingle(OutHit, StartLocation, StartLocation + TraceVector, Params, ObjectParams); if (HitSomething && EnemyTarget->GetUniqueID() == OutHit.Actor->GetUniqueID()) { //we're still hitting the target, pray that we'll miss it when we look at the other targetpoints continue; } else { return HitSomething; } } } } UE_LOG(TB_Log, Warning, TEXT("MissLineTrace(): Can't find a way to miss")); return false; }
void UDebugHandUtility::DebugOrientationAtRelative(FRotator Orientation, FVector Relative, FVector Offset, float Scale) { FVector position = GetComponentRotation().RotateVector(Relative + Offset) + GetComponentLocation(); DebugOrientation(Orientation, position, Scale); }
void UChildActorComponent::CreateChildActor() { AActor* MyOwner = GetOwner(); if (MyOwner && !MyOwner->HasAuthority()) { AActor* ChildClassCDO = (ChildActorClass ? ChildActorClass->GetDefaultObject<AActor>() : nullptr); if (ChildClassCDO && ChildClassCDO->GetIsReplicated()) { // If we belong to an actor that is not authoritative and the child class is replicated then we expect that Actor will be replicated across so don't spawn one return; } } // Kill spawned actor if we have one DestroyChildActor(); // If we have a class to spawn. if(ChildActorClass != nullptr) { UWorld* World = GetWorld(); if(World != nullptr) { // Before we spawn let's try and prevent cyclic disaster bool bSpawn = true; AActor* Actor = MyOwner; while (Actor && bSpawn) { if (Actor->GetClass() == ChildActorClass) { bSpawn = false; UE_LOG(LogChildActorComponent, Error, TEXT("Found cycle in child actor component '%s'. Not spawning Actor of class '%s' to break."), *GetPathName(), *ChildActorClass->GetName()); } Actor = Actor->GetParentActor(); } if (bSpawn) { FActorSpawnParameters Params; Params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; Params.bDeferConstruction = true; // We defer construction so that we set ParentComponent prior to component registration so they appear selected Params.bAllowDuringConstructionScript = true; Params.OverrideLevel = (MyOwner ? MyOwner->GetLevel() : nullptr); Params.Name = ChildActorName; Params.Template = ChildActorTemplate; if (!HasAllFlags(RF_Transactional)) { Params.ObjectFlags &= ~RF_Transactional; } // Spawn actor of desired class ConditionalUpdateComponentToWorld(); FVector Location = GetComponentLocation(); FRotator Rotation = GetComponentRotation(); ChildActor = World->SpawnActor(ChildActorClass, &Location, &Rotation, Params); // If spawn was successful, if(ChildActor != nullptr) { ChildActorName = ChildActor->GetFName(); // Remember which component spawned it (for selection in editor etc) FActorParentComponentSetter::Set(ChildActor, this); // Parts that we deferred from SpawnActor const FComponentInstanceDataCache* ComponentInstanceData = (CachedInstanceData ? CachedInstanceData->ComponentInstanceData : nullptr); ChildActor->FinishSpawning(ComponentToWorld, false, ComponentInstanceData); ChildActor->AttachToComponent(this, FAttachmentTransformRules::SnapToTargetNotIncludingScale); SetIsReplicated(ChildActor->GetIsReplicated()); } } } } // This is no longer needed if (CachedInstanceData) { delete CachedInstanceData; CachedInstanceData = nullptr; } }