Adding a USceneComponent as RootComponent cancels collision

Hey, so I’m having a weird issue (at least for me)

When the code looks like this:

KosherWarriorMesh = CreateDefaultSubobject(TEXT("KW Mesh"));

  KosherWarriorMesh->SetStaticMesh(MeshObj.Object);
  KosherWarriorMesh->SetCastShadow(false);

  RootComponent = KosherWarriorMesh;

  CollisionBoundry = CreateDefaultSubobject(TEXT("Collision Boundry"));

  CollisionBoundry->OnComponentBeginOverlap.AddDynamic(this, &AKosherWarrior::OnHit);
  CollisionBoundry->SetupAttachment(RootComponent);

The instance of the BP I create from this class is getting blocked by the walls i put up in the scene… And I can’t go through them… BUT… once I make the code look like the one below I can freely go through walls… The wall is just a basic cube with block all in the collision settings

const ConstructorHelpers::FObjectFinder MeshObj(TEXT("StaticMesh'/Engine/EngineMeshes/Cube.Cube'"));

  RootComponent = CreateDefaultSubobject(TEXT("KW Root"));
  KosherWarriorMesh = CreateDefaultSubobject(TEXT("KW Mesh"));

  KosherWarriorMesh->SetStaticMesh(MeshObj.Object);
  KosherWarriorMesh->SetCastShadow(false);
  KosherWarriorMesh->SetupAttachment(RootComponent);

  CollisionBoundry = CreateDefaultSubobject(TEXT("Collision Boundry"));

  CollisionBoundry->OnComponentBeginOverlap.AddDynamic(this, &AKosherWarrior::OnHit);
  CollisionBoundry->SetupAttachment(RootComponent);

Can anyone please give me a clue on why is that happening?

Thanks!

There is nothing wrong with your setup.

This is how actually the way movement works in unreal.

  • All movement functions (the ones
    provided in the engine and part of
    the movement component) act on only
    the root component.
  • Collisions are calculated only for
    the root component (for optimization
    purposes) which means that if the
    root has no collision it will pass
    through walls.
  • Once the root is moved all other
    sub-objects are teleported in their
    respective positions. They fire their
    overlap events (if any) but since the
    movement is already complete they do
    not affect it.

Now there are several ways to make it work as you want:

  1. Make your root component a simple collider. (usually there is no problem doing this and you can set the collider to only affects movement)
  2. Make the move function you are using check (sweep) your desired collider instead of the root component. (you must still move the root although you are checking a child component which means that you must calculate the position of the root from your hit result)
  3. Check the collider position before you move your pawn and then execute the move with a correction based on your result. (this is essentially 2. but you are making the check beforehand and you don’t actually modify the code of the move, just its input)

I would strongly recommend using the first approach as modifying the movement behavior is on the “more complex” side of things. It is tied with networking and server corrections and also affects physics.

Happy coding :slight_smile:

Hey, thanks for the great reply! I will try it for sure. the only reason I made a uscenecomponent as the root is because I want to be able to modify the mesh inside (size, rotation etc…) when i’m converting it to a BP… if I add a collider component will it take the right size or will i have to scale it in the code?

Your root transformations propagate down to the children components (by default) which means that if you add a collider it will initially take the orientation and the scale of the parent component. This means you can modify your whole construct by manipulating only the root component (which is neat). You can also add intermediate scene components for parents and use them as hinges so you can manipulate all children by just manipulating the scene component.

I would suggest you put your root collider and rotate/scale your whole pawn (collider and mesh) if the collider is logically tied to your mesh (if you want the collider geometry to closely encapsulate your mesh). If you don’t need that you can put a large sphere collider as a root loosely encapsulating your mesh in any orientation. This will also prevent your pawn from rotating into the wall which will otherwise create a whole new set of problems (will the pawn move to allow the rotation or should the rotation be stopped). Then I would adjust the position/rotation/scale of all the components that need to be differently aligned.

This however, is only speculation as I don’t know your whole design. I can give you a tank for example:

  • A tank can use a simple box collider
    as a root to calculate movement, hitting walls, etc.;

  • When shot however, the root collider
    is ignored and more complex collider
    is used for the hit location;

  • The turret direction is adjusted
    every frame depending on where the player
    is aiming even if the whole vehicle is rotating and moving;

  • The barrel on the turret has only the
    collider that reacts to being shot.
    It can pass through walls and
    although it looks unrealistic it
    helps the gameplay as otherwise the
    barrel can get your tank stuck;

Buddy, thanks a lot for all the in-depth answers! I eventually took ur advice and made one sphere component as the root and the mesh is inside it… i also gave up on writing code for making all the components and do it in side the BP now and just implement the logic and events in code… i’m not using BP right i’m a noob :smiley: thanks again!