示例#1
1
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);
                }
            }
        }
    }
}
示例#2
0
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"));
}
示例#7
0
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();
}
示例#10
0
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;
	}
}
示例#11
0
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);
}
示例#15
0
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());
		}
	}
}
示例#17
0
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);
}
示例#18
0
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);
		}
	}
}
示例#22
0
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();
		}
	}
}
示例#28
0
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;
}
示例#29
0
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;
	}
}