Esempio n. 1
0
/*
* Spawns the hitbox and processes the actors within it
*/
void AHero::AttackTrace()
{
	//Actors that overlap the box stored in this array
	TArray<struct FOverlapResult> OutOverlaps;
	//Orient the box in the direction of the character
	FQuat Rotation = Instigator->GetTransform().GetRotation();
	FVector Start = Instigator->GetTransform().GetLocation() + Rotation.Rotator().Vector() * 100.0f;

	FCollisionShape CollisionHitShape;
	FCollisionQueryParams CollisionParams;
	//Have the hitbox ignore the player
	CollisionParams.AddIgnoredActor(Instigator);

	//Set what will respond to the collision
	FCollisionObjectQueryParams CollisionObjectTypes;
	CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_PhysicsBody);
	CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn);
	CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_WorldStatic);

	//Create the hitbox and get the actors within
	CollisionHitShape = FCollisionShape::MakeBox(FVector(100.0f, 60.0f, 0.5f));
	GetWorld()->OverlapMulti(OutOverlaps, Start, Rotation, CollisionHitShape, CollisionParams, CollisionObjectTypes);

	//Process all hit actors
	for (int i = 0; i < OutOverlaps.Num(); i++)
	{
		if (OutOverlaps[i].GetActor() && !HitActors.Contains(OutOverlaps[i].GetActor()))
		{
			//Check if hit registered
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("hit"));
			//Now call the function that does something to our unfortunate actor...
			ProcessHitActor(OutOverlaps[i].GetActor());
		}
	}
}
void ABaseCharacter::CheckAttackOverlap(){

	//Overlapping actors for each box spawned will be stored here
	TArray<struct FOverlapResult> OutActorOverlaps;

	//Hit other actors only once
	TArray<AActor*> ProcessedActors;


	//The initial rotation of our box is the same as our character rotation
	FQuat Rotation = GetTransform().GetRotation();
	FVector Start = GetTransform().GetLocation() + Rotation.Rotator().Vector() * 100.0f;

	FCollisionShape CollisionHitShape;
	FCollisionQueryParams CollisionParams;

	//We do not want the character to hit itself, don't store this character in the array, to ignore it's collision
	CollisionParams.AddIgnoredActor(this);

	//Set the channels that will respond to the collision
	FCollisionObjectQueryParams CollisionObjectTypes;
	CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_PhysicsBody);
	CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn);
	//CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_WorldStatic); // uncomment to enable bashing objects

	//Create the box and get the overlapping actors
	CollisionHitShape = FCollisionShape::MakeBox(AttackBox);
	GetWorld()->OverlapMulti(OutActorOverlaps, Start, Rotation, CollisionHitShape, CollisionParams, CollisionObjectTypes);


	AActor* ActorToProcess;
	//Process all hit actors
	for (int i = 0; i < OutActorOverlaps.Num(); ++i)
	{
		ActorToProcess = OutActorOverlaps[i].GetActor();
		//We process each actor only once per Attack execution
		if (ActorToProcess && !ProcessedActors.Contains(ActorToProcess))
		{

			//Add this actor to the array because we are spawning one box per tick and we don't want to hit the same actor twice during the same attack animation
			ProcessedActors.AddUnique(ActorToProcess);

			if ( dynamic_cast<APatrollingEnemyCharacter*>(ActorToProcess) ){
				APatrollingEnemyCharacter* ennemy = (APatrollingEnemyCharacter*)ActorToProcess;
				ennemy->OnHit(this);
			}
		}
	}
}
Esempio n. 3
0
AActor* AMagnetTile::GetMagnetHitActor( FHitResult& hit )
{
	FCollisionQueryParams queryParam;
	queryParam.bFindInitialOverlaps = false;
	queryParam.bReturnFaceIndex = true;
	FCollisionObjectQueryParams objectParam;
	objectParam.AddObjectTypesToQuery( ECollisionChannel::ECC_Pawn );
	objectParam.AddObjectTypesToQuery( ECC_Portal );

	auto pos = TileMesh->GetSocketLocation( "Socket" );

	auto rayStart = pos + GetClampedForwardVector() * 2.0f;
	auto laserVector = GetClampedForwardVector( true );

	GetWorld()->LineTraceSingleByObjectType( hit , rayStart , pos + laserVector , objectParam , queryParam );
	magnetEndPos = hit.ImpactPoint;
	return hit.Actor.Get();
}
void AAmbitionOfNobunagaPlayerController::PlayerTick(float DeltaTime)
{
	Super::PlayerTick(DeltaTime);

	if(Hud)
	{
		CurrentMouseXY = GetMouseScreenPosition();
		TArray<FHitResult> Hits;
		bool res;
		FVector WorldOrigin;
		FVector WorldDirection;
		FCollisionObjectQueryParams CollisionQuery;
		CollisionQuery.AddObjectTypesToQuery(ECC_WorldStatic);
		if (UGameplayStatics::DeprojectScreenToWorld(this, CurrentMouseXY, WorldOrigin, WorldDirection) == true)
		{
			res = GetWorld()->LineTraceMultiByObjectType(Hits, WorldOrigin, WorldOrigin + WorldDirection * HitResultTraceDistance,
			        CollisionQuery);
		}
		// 只trace 地板的actor
		// 地板名可以自定義
		FVector HitPoint(0, 0, 0);
		if (Hits.Num() > 0)
		{
			for (FHitResult Hit : Hits)
			{
				if (Hit.Actor.IsValid() && Hit.Actor->GetFName().GetPlainNameString() == FloorActorName)
				{
					HitPoint = Hit.ImpactPoint;
				}
				// all landscape can click
				if (Hit.Actor.IsValid())
				{
					FString ResStr;
					Hit.Actor->GetClass()->GetName(ResStr);
					if (ResStr == "Landscape")
					{
						HitPoint = Hit.ImpactPoint;
					}
				}
			}
		}
		Hud->OnMouseMove(CurrentMouseXY, HitPoint);
	}
}
Esempio n. 5
0
vector<AGameObject*> APlayerControl::ComponentPickExcept( AGameObject* object, UPrimitiveComponent* up, vector<AGameObject*> except,
  FString queryObjectType, vector<FString> intersectableTypes )
{
  FComponentQueryParams fqp;
  except += object;

  // this will cause the object to pick itself if you don't put it in the except group
  for( AGameObject* o : except )
    if( o )  fqp.AddIgnoredActor( o );

  FCollisionObjectQueryParams objectTypes = FCollisionObjectQueryParams( 
    FCollisionObjectQueryParams::InitType::AllObjects );

  for( FString channelName : intersectableTypes )
  {
    ECollisionChannel channel = CollisionChannels[channelName];
    objectTypes.AddObjectTypesToQuery( channel ); // Channel 3 is the RESOURCES channel.
  }

  TArray<FOverlapResult> overlaps;
  FRotator ro = up->GetComponentRotation();
  FVector ve = up->GetComponentLocation();

  // QUERY on channel 
  ECollisionChannel queryChannel = CollisionChannels[queryObjectType];
  GetWorld()->ComponentOverlapMultiByChannel( overlaps, up, ve, ro, queryChannel, fqp, objectTypes );
  
  map<float, AGameObject*> objects;
  for( int i = 0; i < overlaps.Num(); i++ )
  {
    if( AGameObject* go = Cast<AGameObject>( overlaps[i].GetActor() ) )
    {
      float d = FVector::Dist( object->Pos, go->Pos );
      objects[ d ] = go;
    }
  }

  return MakeVectorS( objects );
}
// Check for bullet collisions
void AMurphysLawCharacter::ComputeBulletCollisions()
{
	// Only look for pawns
	FCollisionObjectQueryParams CollisionObjectQueryParams;
	CollisionObjectQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_PhysicsBody);
	CollisionObjectQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_Destructible);
	CollisionObjectQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_WorldStatic);

	// Remove self from query potential results since we are the first to collide with the ray
	FCollisionQueryParams RayQueryParams;
	RayQueryParams.AddIgnoredActor(this);

	// Ray starting coordinates
	const FVector CollisionRayStart = GetFirstPersonCameraComponent()->GetComponentLocation();
	const FVector CollisionRayInitialDirection = GetFirstPersonCameraComponent()->GetComponentTransform().GetRotation().GetAxisX();

	// Group damage of touched objects together
	const float MaxFragmentDeviationRadian = FMath::DegreesToRadians(GetEquippedWeapon()->GetMaxFragmentDeviationAngle(IsCharacterAiming));

	bool AtLeastOneHit = false;

	// Trace lines to detect pawn
	for (int32 i = 0; i < GetEquippedWeapon()->GetNumberOfEmittedFragments(); ++i)
	{
		// Ray ending coordinates
		const FVector CollisionRayAngledDirection = FMath::VRandCone(CollisionRayInitialDirection, MaxFragmentDeviationRadian);
		const FVector CollisionRayEnd = CollisionRayStart + (CollisionRayAngledDirection * GetEquippedWeapon()->GetMaxTravelDistanceOfBullet());

		FHitResult CollisionResult;
		bool HasHit = GetWorld()->LineTraceSingleByObjectType(CollisionResult, CollisionRayStart, CollisionRayEnd, CollisionObjectQueryParams, RayQueryParams);

		if (HasHit)
		{
			// Simple damage amount considering the distance to the target depending on the bone hit
			float DeliveredDamage = GetDeliveredDamage(CollisionResult);

			FPointDamageEvent CollisionDamageEvent(DeliveredDamage, CollisionResult, CollisionRayAngledDirection, UDamageType::StaticClass());

			// If the actor we hit is a hittable actor and an enemy, we have at least one hit so we'll show the Hit Marker
			if (IsHittableActor(CollisionResult.GetActor()) && !MurphysLawUtils::IsInSameTeam(CollisionResult.GetActor(), this))
			{
				AtLeastOneHit = true;
			}

			if (Role == ROLE_Authority)
			{
				CollisionResult.GetActor()->TakeDamage(DeliveredDamage, CollisionDamageEvent, GetController(), this);
			}
			else
			{
				Server_TransferDamage(CollisionResult.GetActor(), DeliveredDamage, CollisionDamageEvent, GetController(), this);
			}
		}
	}

	// If there was at least one hit, we show the HitMarker
	if (AtLeastOneHit)
	{
		auto MyController = Cast<AMurphysLawPlayerController>(GetController());
		if (MyController != nullptr && MyController->GetHUDInstance() != nullptr)
		{
			MyController->GetHUDInstance()->ShowHitMarker();
		}
	}
}