Exemple #1
0
void AGraph::initializeEdgeMesh(UStaticMeshComponent* edgeMesh,
								const AGVertex* v1,
								const AGVertex* v2)
{
	auto pos1 = v1->GetActorLocation();
	auto pos2 = v2->GetActorLocation();


	auto ray = pos2 - pos1;

	auto n_p1p2 = ray;
	n_p1p2.Z = 0;
	n_p1p2 = n_p1p2.GetSafeNormal();

	//tile is 40*40*1. The distance needs to substract half of the tile size
	auto totalOffsetDistance = 40.0f;
	//change start & end positions from the center of the vertex mesh
	//to the edges of the mesh to the right direction
	auto p1_offset = n_p1p2 * totalOffsetDistance;
	pos1 += p1_offset;
	pos2 += -p1_offset;
	auto newRay = pos2 - pos1;

	auto rotation = FRotationMatrix::MakeFromX(newRay);
	auto scaleX = FVector::Dist(pos1, pos2) * .5f ;
	auto scaleY = 40.0f;
	auto scaleZ = 1.0f;
	FMatrix transformMatrix = FScaleMatrix(FVector(scaleX, scaleY, scaleZ)) *
								rotation *
								FTranslationMatrix(pos1);

	edgeMesh->SetWorldTransform(FTransform(transformMatrix));
	edgeMesh->AddLocalOffset(FVector(scaleX, 0.0f, 0.0f));
}
	//!< FPrimitiveSceneProxy
	virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, class FMeshElementCollector& Collector) const override
	{
		FDynamicMeshBuilder MeshBuilder;

		const auto Num = 20;
		const auto DeltaUV = 1.0f / (Num - 1);
		TArray<FDynamicMeshVertex> Vertices;
		Vertices.Reserve(Num * Num);
		for (auto i = 0; i < Num; ++i)
		{
			for (auto j = 0; j < Num; ++j)
			{
				const auto UV = FVector2D(DeltaUV * j, DeltaUV * i);

				FDynamicMeshVertex Vertex;
				Vertex.Position = GetPosition(UV);
				Vertex.TextureCoordinate = GetUV(UV);
				const auto Edge01 = GetPosition(UV + FVector2D(0.01f, 0.0f)) - Vertex.Position;
				const auto Edge02 = GetPosition(UV - FVector2D(0.0f, 0.01f)) - Vertex.Position;
				Vertex.TangentX = Edge01.GetSafeNormal();
				Vertex.TangentZ = (Edge02 ^ Edge01).GetSafeNormal();
				Vertex.Color = FColor::Green;

				Vertices.Add(Vertex);
			}
		}
		MeshBuilder.AddVertices(Vertices);

		TArray<int32> Indices;
		Indices.Reserve((Num - 1) * (Num - 1) * 6);
		for (auto i = 0; i < Num - 1; ++i)
		{
			for (auto j = 0; j < Num - 1; ++j)
			{
				const auto Index = j + i * Num;
				Indices.Add(Index);
				Indices.Add(Index + Num);
				Indices.Add(Index + 1);

				Indices.Add(Index + 1);
				Indices.Add(Index + Num);
				Indices.Add(Index + Num + 1);
			}
		}
		MeshBuilder.AddTriangles(Indices);

		auto MaterialRenderProxy = UMaterial::GetDefaultMaterial(MD_Surface)->GetRenderProxy(IsSelected());
		if (nullptr != MaterialInterface)
		{
			MaterialRenderProxy = MaterialInterface->GetRenderProxy(false);
		}
		if (Views[0]->Family->EngineShowFlags.Wireframe)
		{
			MaterialRenderProxy = GEngine->WireframeMaterial->GetRenderProxy(IsSelected());
		}
		MeshBuilder.GetMesh(GetLocalToWorld(), MaterialRenderProxy, 0, false, false, 0, Collector);
	}
void UTankMovementComponent::RequestDirectMove(const FVector& MoveVelocity, bool bForceMaxSpeed) 
{
	auto TankForward = GetOwner()->GetActorForwardVector().GetSafeNormal();
	auto AIForwardIntention = MoveVelocity.GetSafeNormal();

	auto ForwardThrow = FVector::DotProduct(TankForward, AIForwardIntention);
	auto RightThrow = FVector::CrossProduct(AIForwardIntention, TankForward);
	IntendMoveForward(ForwardThrow);
	IntendTurnRight(RightThrow.GetSafeNormal().Z);
}
Exemple #4
0
void ALaser::checkLaserCollisions(float dt)
{
	FHitResult hit;
	FCollisionQueryParams queryParam;
	queryParam.bFindInitialOverlaps = false;
	queryParam.bReturnFaceIndex = true;
	FCollisionObjectQueryParams objectParam = objectParam.DefaultObjectQueryParam;
	if ( !canHitBall ) queryParam.AddIgnoredActor( GetWorld()->GetGameState<AProjectTapGameState>()->GetPlayer() );
	auto pos = GetActorLocation();
	auto rayStart = pos + dir * 5.0f;
	auto laserVector = dir * length;
	auto laserEmitter = laserParticle->EmitterInstances[0];
	//ray cast to see if laser hits anything
	GetWorld()->LineTraceSingleByObjectType(hit,rayStart, pos + laserVector, objectParam,queryParam);
	auto hitActor = hit.Actor.Get();

	if (hitActor != nullptr)
	{
		currHitPoint = hit.ImpactPoint;
		if(!laserSparkParticle->bIsActive) laserSparkParticle->ActivateSystem();
		//kills ball if laser hits it
		auto ball = Cast<ABallPawn>(hitActor);

		if (ball != nullptr)
		{
			ball->Kill();
			laserEmitter->SetBeamTargetPoint(hit.ImpactPoint, 0);
			KillSubLaser();
		}
		else
		{
			//if not set laser end point
			laserEmitter->SetBeamTargetPoint(hit.ImpactPoint, 0);

			bool typeFound = false;
			//if hits deflective tile then spawn a new laser object
			auto tile = Cast<ADeflectiveTile>(hitActor);
			bool isFrame = false;
			if (tile != nullptr)
			{
				typeFound = true;
				TArray<USceneComponent*> Children;
				tile->frameCollisionsComponent->GetChildrenComponents(true, Children);
				for(int i = 0; i < Children.Num() && typeFound ; ++i)
				{
//					printonscreen(hit.Component.Get()->GetName());
//					printonscreen(Children[i]->GetName());
					if(hit.Component.Get() == Children[i])
					{
						typeFound = false;
						isFrame = true;
					}
				}
				//cut the laser length to make sure new sub laser start doesn't hit the same object
				if (typeFound && CanSpawnSubLaser()) SpawnSubLaser(hit.ImpactPoint + hit.ImpactNormal * 10.0f, hit.ImpactNormal);
			}


			//if sub laser already exists then keep updating its rotation and position
			auto subLaserExistsHitDeflectiveTile = currentDepth < MAX_DEPTH && nextLaser != nullptr && tile != nullptr;
			if (subLaserExistsHitDeflectiveTile)
			{
				auto incomingVector = hit.ImpactPoint - GetActorLocation();

				//if the incoming vector's angle is too small then kill sublasers to avoid laser flickering
				auto dot = FVector::DotProduct(-incomingVector.GetSafeNormal(), hit.ImpactNormal);

				auto angle = FMath::RadiansToDegrees(FMath::Acos(dot));
				if (angle < 70.0f)
				{
					auto newDir = FMath::GetReflectionVector(incomingVector, hit.ImpactNormal);

					auto start = hit.ImpactPoint + newDir * 2.0f;
					nextLaser->SetActorLocation(hit.ImpactPoint);
					nextLaser->dir = newDir.IsNormalized() ? newDir : newDir.GetSafeNormal();
					nextLaser->laserParticle->EmitterInstances[0]->SetBeamSourcePoint(hit.ImpactPoint, 0);
					nextLaser->laserParticle->EmitterInstances[0]->SetBeamTargetPoint(start + newDir * length, 0);
				}
				else
				{
					KillSubLaser();
				}
			}

			//if the laser hits turret then kills it
			if (!typeFound)
			{
				auto turret = Cast<ATurretPawn>(hitActor);
				if (turret != nullptr)
				{
					typeFound = true;
					turret->Damage(2.0f);
				}
			}

			APortalTile* portal = nullptr;
			if (!typeFound)
			{
				portal = Cast<APortalTile>(hitActor);
				if (CanSpawnSubLaser() && portal != nullptr)
				{
					typeFound = true;
					auto relativePos = hit.ImpactPoint - hit.GetComponent()->GetComponentLocation();
					currHitPoint = relativePos + portal->GetActorLocation();
					SpawnSubLaser(currHitPoint, hit.ImpactNormal);
				}
			}

			auto subLaserExistsHitPortalTile = currentDepth < MAX_DEPTH && nextLaser != nullptr && portal != nullptr;
			if (subLaserExistsHitPortalTile)
			{
				FVector newSourcePos;
				portal->GetLaserPortalTransportedLocation(hit.GetComponent(), nextLaser->dir, newSourcePos);
				nextLaser->SetActorLocation(newSourcePos);
				nextLaser->laserParticle->EmitterInstances[0]->SetBeamSourcePoint(newSourcePos, 0);
				nextLaser->laserParticle->EmitterInstances[0]->SetBeamTargetPoint(newSourcePos + nextLaser->dir * length, 0);
			}

			bool notHitDeflectiveTile = tile == nullptr || isFrame;
			bool notHitPortal = portal == nullptr;
			if (notHitDeflectiveTile && notHitPortal)
			{
				KillSubLaser();
			}
		}
			laserSparkParticle->SetWorldLocation(currHitPoint);
			laserSparkParticle->SetWorldRotation(FVector(currHitPoint -
												 GetActorLocation()).GetSafeNormal().Rotation().Quaternion());
	}
	else
	{
		currHitPoint = laserVector;
		laserEmitter->SetBeamTargetPoint(pos + currHitPoint, 0);
		laserSparkParticle->SetWorldLocation( pos + currHitPoint );
		laserSparkParticle->SetWorldRotation( FVector( (pos + currHitPoint) -
			GetActorLocation() ).GetSafeNormal().Rotation().Quaternion() );
		KillSubLaser();
	}

	//only root laser can have an emitter mesh
	if (currentDepth != 0)
	{
		//update laser emitter rotation
		mesh->SetVisibility(false);
	}
	else
	{
		mesh->SetWorldRotation(dir.Rotation());
	}
}