// Called every frame void ACart::Tick( float DeltaTime ) { Super::Tick( DeltaTime ); auto World = GetWorld(); for (int32 i = 0; i < 4; i++) { FHitResult HitResult(ForceInit); FCollisionQueryParams Params = FCollisionQueryParams(FName(TEXT("Trace")), true, this); Params.bTraceComplex = true; //Params.bTraceAsyncScene = true; Params.bReturnPhysicalMaterial = true; const FName TraceTag("MyTraceTag"); World->DebugDrawTraceTag = TraceTag; Params.TraceTag = TraceTag; bool Hit = World->LineTraceSingleByChannel(HitResult, Arrows[i]->GetComponentLocation(), Arrows[i]->GetComponentLocation() + Arrows[i]->GetForwardVector() * (SpringLength + WheelRadius), ECC_PhysicsBody, Params); if (Hit) { FVector Force = HitResult.ImpactNormal * SpringStrength * BodyMesh->GetMass() * (1 - HitResult.Distance / (SpringLength + WheelRadius)); BodyMesh->AddForceAtLocation(Force, Arrows[i]->GetComponentLocation()); Wheels[i]->SetWorldLocation(HitResult.Location - (Arrows[i]->GetForwardVector() * WheelRadius)); } else { Wheels[i]->SetWorldLocation(Arrows[i]->GetComponentLocation() + Arrows[i]->GetForwardVector() * SpringLength); } } }
bool UWorld::LineTraceSingleByProfile(struct FHitResult& OutHit, const FVector& Start, const FVector& End, FName ProfileName, const struct FCollisionQueryParams& Params) const { ECollisionChannel TraceChannel; FCollisionResponseParams ResponseParam; GetCollisionProfileChannelAndResponseParams(ProfileName, TraceChannel, ResponseParam); return LineTraceSingleByChannel(OutHit, Start, End, TraceChannel, Params, ResponseParam); }
bool UWorld::SweepSingleByChannel(struct FHitResult& OutHit, const FVector& Start, const FVector& End, const FQuat& Rot, ECollisionChannel TraceChannel, const FCollisionShape& CollisionShape, const FCollisionQueryParams& Params /* = FCollisionQueryParams::DefaultQueryParam */, const FCollisionResponseParams& ResponseParam /* = FCollisionResponseParams::DefaultResponseParam */) const { if (CollisionShape.IsNearlyZero()) { return LineTraceSingleByChannel(OutHit, Start, End, TraceChannel, Params, ResponseParam); } else { #if UE_WITH_PHYSICS return GeomSweepSingle(this, CollisionShape, Rot, OutHit, Start, End, TraceChannel, Params, ResponseParam, FCollisionObjectQueryParams::DefaultObjectQueryParam); #else OutHit.TraceStart = Start; OutHit.TraceEnd = End; return false; #endif } }
void AShooterProjectile::OnRep_Exploded() { const auto World = GetWorld(); if (nullptr != World) { //!< ヒットした場所を推測する const auto Forward = GetActorForwardVector(); const auto Location = GetActorLocation(); const auto Start = Location - Forward * 200.0f; const auto End = Location + Forward * 150.0f; FHitResult HitResult; const FCollisionQueryParams Params(TEXT("ExplodeTag"), true, Instigator); if (false == World->LineTraceSingleByChannel(HitResult, Start, End, ECC_GameTraceChannel_WeaponProjectile, Params)) { //!< コリジョンが取れない場合でもそれっぽい値にしておく HitResult.ImpactPoint = Location; HitResult.ImpactNormal = -Forward; } SimulateExplode(HitResult); } }