No announcement yet.

RootComponent is ignored, sort of, in 4.7?

  • Filter
  • Time
  • Show
Clear All
new posts

    RootComponent is ignored, sort of, in 4.7?


    I decided to upgrade to 4.7 now, before I get too far along with my project in 4.6. I created a "Basic Code" project and started bringing over code from my old 4.5 and 4.6 projects. I immediately ran into a strange problem.

    I added a new C++ class based on "Pawn." I ported over the old code while making the changes necessary for 4.7. Everything built and ran without error, but I didn't see my pawn's mesh. I could see the camera and the camera boom components in the editor, but not the actual mesh component of the pawn. It didn't show up when I hit "Play," either. So after hours (seriously, hours) of poking around in the editor trying to figure out why it was invisible, I found that if I:

    1) Select the pawn in the World Outliner (I can't click on it in the editor because it's invisible)
    2) Open the details
    3) Select the mesh component in the little tree view, which is apparently somehow generated based on the code (new in 4.7?)
    4) Go to the "Static Mesh" box
    5) Select my mesh in the drop-down list

    Finally, the mesh appears as it should. This is a problem for several reasons:

    1) I shouldn't have to do this because I already load a mesh in the code (in the constructor of my pawn class)
    2) I don't want to have to do this for every mesh in the game -- there are hundreds
    3) I can apparently select any mesh I want in the drop-down and it overrides what I've done in the code (so why did I bother to do anything in the code?)

    Is this the intended behavior in 4.7? Is there any way to not have to do this for every actor that I create in code?
    Level 17 The Ladon Device

    It's not intended. If you post your class declaration and constructor implementation, maybe we can find the issue.


      Thank you, kamrann.

      #pragma once
      #include "GameFramework/Pawn.h"
      #include "PlayerPawn.generated.h"
      class UE47_TEST_PROJECT_API APlayerPawn : public APawn
          APlayerPawn(const FObjectInitializer&);
          // Called when the game starts or when spawned
          virtual void BeginPlay();
          // Called every frame
          virtual void Tick(float);
          // Called to bind functionality to input
          virtual void SetupPlayerInputComponent(class UInputComponent*);
          // I've experimented with both having and not having the following line, seems to make no difference:
          // UPROPERTY(Category = Mesh, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
          class UStaticMeshComponent* ship_body_mesh_component;
          class UCameraComponent* camera_component;
          class USpringArmComponent* camera_boom_component;
      PlayerPawn constructor:
      APlayerPawn::APlayerPawn(const FObjectInitializer& init) :
          // Get mesh and set RootComponent
          static ConstructorHelpers::FObjectFinder<UStaticMesh> ship_body_mesh(TEXT("/Game/Meshes/ship_body.ship_body"));
          ship_body_mesh_component = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ship_body_mesh_component"));
          RootComponent = ship_body_mesh_component;
          // Create camera boom
          camera_boom_component = CreateDefaultSubobject<USpringArmComponent>(TEXT("camera_boom_component"));
          camera_boom_component->bAbsoluteRotation = true;
          camera_boom_component->TargetArmLength = 600.0f;
          camera_boom_component->RelativeRotation = FRotator(-90.0f, 0.0f, 0.0f);
          camera_boom_component->bDoCollisionTest = false;
          // Create camera
          camera_component = CreateDefaultSubobject<UCameraComponent>(TEXT("camera_component"));
          camera_component->AttachTo(camera_boom_component, USpringArmComponent::SocketName);
          camera_component->bUsePawnControlRotation = false;
      Level 17 The Ladon Device


        I should probably also mention that I tried specifying the ship_body_mesh with the long syntax ("StaticMesh'/Game/Meshes/ship_body.ship_body'"), as well, and the behavior was the same.
        Level 17 The Ladon Device


          Okay, so there are two different things here which it's important to distinguish.

          UStaticMeshComponent, a type of actor component which you have created in your constructor.
          UStaticMesh, an actual mesh asset.

          UStaticMeshComponent has a property of type UStaticMesh*, called StaticMesh. When you create the component, the StaticMesh property will be null. So after calling CreateDefaultSubobject, you need to assign the static mesh asset you loaded to the property.
          ship_body_mesh_component->StaticMesh = ship_body_mesh.Object;
          Edit: In hindsight I think you probably knew this but just forgot the assignment.

          That said, I don't think it's generally good practice to hard code asset names into your C++ code. Much easier to just create a blueprint class based on your C++ class, edit your blueprint defaults and set the mesh property of your component to the asset you want. Then you can just drop/spawn the blueprint into your level as many times as you like. This way, any time you want to switch the mesh or relocate it, you can do so in the editor without needing to recompile.
          Last edited by kamrann; 03-12-2015, 03:59 PM.


            Thanks a ton. I did know (at some point) that setting the "StaticMesh" property was required, because it's right there in all the example code. No idea how that line disappeared in the port.
            Level 17 The Ladon Device