x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How do I make characters spawned dynamically not stuck on dynamically constructed floor?

I have a character that I spawn from a dynamically created player start onto a dynamically created floor. Right now, the character cannot move across the floor normally. I can see that the movement events are firing, and the character can jump properly. This means that I can do a tiny bunny-hop to move around on the floor. It's almost as if the friction on the floor or character capsule is infinite.

The character can move correctly on the mesh that I spawn dynamically if it is statically placed in a level from the editor. The dynamic generation only currently occurs when the map is determined to be a dynamic map and occurs in the GameMode's PreInitializeComponents method.

I'm fairly confident that I am missing some small setting that will let the movement occur normally, but I am clearly missing it.

I would appreciate any help you could provide into why the character is stuck on the floor to get it moving on the dynamically created floor.

I am using the latest version of the engine, 4.7.5. I also tried this in 4.7.3 before 4.7.5 was released.

For your convenience, the relevant pieces of code are below.

The Player Start Spawn

 void ADungeonBuilder::SpawnStart(UWorld* world, ARoom* room)
 {
     FVector roomExtent = room->Boundary->GetUnscaledBoxExtent();
     //TODO: Make Random in the room
 
     FActorSpawnParameters spawnParameters;
     spawnParameters.Owner = this;
     spawnParameters.Instigator = Instigator;
 
     FVector spawnLocation(-600, -600, -600);
     FRotator spawnRotation(FRotator::ZeroRotator);
 
     PlayerStart = Cast<APlayerStart>(world->SpawnActor<AActor>(APlayerStart::StaticClass(), spawnLocation, spawnRotation, spawnParameters));
         
     PlayerStart->AttachRootComponentToActor(room);
 
     PlaceExitVolume(world, room);
 }

The room tile method. (where all floor tiles are placed in the world)

 void ADungeonBuilder::TileFloor(ARoom* room)
 {
     UStaticMesh* floorMesh = LoadFloorMesh();
     UMaterial* floorMaterial = LoadFloorMaterial();
 
     FVector meshExtent = floorMesh->GetBounds().BoxExtent;
     FVector roomExtent = room->Boundary->GetUnscaledBoxExtent();
 
     //TODO: Handle case where room is smaller than mesh
     uint32 tilesWide = roomExtent.X / meshExtent.X;
     uint32 tilesDeep = roomExtent.Y / meshExtent.Y;
 
     float startX = -roomExtent.X;
     float startY = -roomExtent.Y;
     float startZ = -roomExtent.Z + meshExtent.Z;
 
     float slideX = meshExtent.X * 2;
     float slideY = meshExtent.Y * 2;
 
     for (uint32 deepRank = 0; deepRank < tilesDeep; ++deepRank)
     {
         for (uint32 wideRank = 0; wideRank < tilesWide; ++wideRank)
         {
             FVector nextCenter(startX + slideX*wideRank, 
                                startY + slideY*deepRank, 
                                startZ);
             UStaticMeshComponent* floorComponent = LoadComponent(floorMesh);
 
             floorComponent->SetMaterial(0, floorMaterial);
             floorComponent->SetWorldLocation(nextCenter);
             floorComponent->RegisterComponentWithWorld(GetWorld());
             floorComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);            
             floorComponent->AttachTo(room->GetRootComponent());
             room->Floor.Add(floorComponent);
         }
     }
 }

The floor mesh loader

 UStaticMesh* ADungeonBuilder::LoadFloorMesh()
 {
     TCHAR* floorName = TEXT("/Game/Architecture/Floor_400x400.Floor_400x400");
     UStaticMesh* floorMesh = LoadObject<UStaticMesh>(NULL, floorName, NULL, LOAD_None, NULL);    
     
     return floorMesh;
 }

The Component Loader

 UStaticMeshComponent* ADungeonBuilder::LoadComponent(UStaticMesh* mesh)
 {
     UStaticMeshComponent* floorComponent = ConstructObject<UStaticMeshComponent>(UStaticMeshComponent::StaticClass());
     floorComponent->SetStaticMesh(mesh);
     floorComponent->SetMobility(EComponentMobility::Movable);
     floorComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
     floorComponent->bCanEverAffectNavigation = true;
     floorComponent->bCastDynamicShadow = true;
     
     
     return floorComponent;
 }

The Material Loader

 UMaterial* ADungeonBuilder::LoadFloorMaterial()
 {
     TCHAR* floorMaterialName = TEXT("/Game/Materials/M_CobbleStone_Smooth.M_CobbleStone_Smooth");
     UMaterial* floorMaterial = LoadObject<UMaterial>(NULL, floorMaterialName, NULL, LOAD_None, NULL);
     
     return floorMaterial;
 }


Edit: Included the engine version.

Product Version: Not Selected
Tags:
more ▼

asked Apr 12 '15 at 12:43 AM in C++ Programming

avatar image

cjacket
6 1 3

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

I guess since no one got the chance to answer, I have to answer my own question :(.

It appears that you need to create organize this differently than I was hoping. I got the premise to work by creating a blueprint with the parent of the StaticMeshActor, and spawning that blueprint in the TileFloor method. The ComponentLoader and the MeshLoader are not needed because of this.

I still think that there is probably a way to load the information outside the constructor of an Actor and still have valid collision, but it is not immediately obvious how to set it up. (I haven't had the time to dig into the engine code directly, but may if this path doesn't work the way I'd like.)

more ▼

answered Apr 18 '15 at 03:35 AM

avatar image

cjacket
6 1 3

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question