Announcement

Collapse
No announcement yet.

Component has local offset when spawn (located at world 0,0,0)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Component has local offset when spawn (located at world 0,0,0)

    Hi!

    I have created a simple actor in c++ with a scene component as root, a box component and a static mesh component.

    Code:
            UPROPERTY(EditDefaultsOnly, Category = "Cell")
    	USceneComponent* RootCmp;
    
    	UPROPERTY(EditDefaultsOnly, Category = "Cell")
    	UBoxComponent* DetectorCmp;
    
    	UPROPERTY(EditDefaultsOnly, Category = "Cell")
    	UStaticMeshComponent* CellMesh;
    The constructor code is:

    Code:
    	RootCmp = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));	
    	SetRootComponent(RootCmp);
    
    	DetectorCmp = CreateDefaultSubobject<UBoxComponent>(TEXT("Detector"));	
    	DetectorCmp->AttachToComponent(RootCmp, FAttachmentTransformRules::KeepRelativeTransform);	
    	
    	CellMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CellMesh"));
    	CellMesh->AttachToComponent(RootCmp, FAttachmentTransformRules::KeepRelativeTransform);
    it's pretty simple but I have an issue... When I spawn my object into the world, the box and static mesh components are located at world 0,0,0 so they have a local offset relative to my root component.

    I have tried to set the relative location at 0,0,0 after AttachToComponent line and I have used SetupAttachment instead of AttachToComponent with no success. What's wrong??

    Thanks!

    #2
    Use SetupAttachment instead of AttachToComponent, if you're doing this in the constructor. Also, use the ObjectInitializer version of the Constructor. Not doing so nearly always causes headaches or random hard-to-track issues. e.g:

    Code:
    AMyClass::AMyClass(const FObjectInitializer& OI)
    : Super(OI)
    {
        	RootCmp = OI.CreateDefaultSubobject<USceneComponent>(this, TEXT("Root"));
    	SetRootComponent(RootCmp);
    }
    Are you sure the Root Component isn't also at world origin?

    Comment


      #3
      Had a similar problem...
      I would spawn a weapon Actor, and StaticMeshComponent's relative location would go crazy. I couldn't get it to reset to 0, and have a gun at socket location. I listened this advice, and it worked like it should.

      Here's the code:
      ExampleWeapon.h
      Code:
      //It is important to use ObjectInitializer version, since RootComponent attachment can get buggy when trying to set it up in the constructor.
          AUrathaWeapon(const FObjectInitializer& OI);
      
          UPROPERTY(EditDefaultsOnly, Category = "Weapon")
          UBoxComponent* WeaponRoot;
      
          UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon")
          UStaticMeshComponent* WeaponMeshComponent;
      ExampleWeapon.cpp
      Code:
      AUrathaWeapon::AUrathaWeapon(const FObjectInitializer& OI) : Super(OI)
      {
           // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
          PrimaryActorTick.bCanEverTick = true;
      
          //This is a recommendable way to create sub object when attachment to RootComponent is buggy (e.g. relative location is screwed).
          WeaponRoot = OI.CreateDefaultSubobject<UBoxComponent>(this, FName("WeaponRoot"));
          SetRootComponent(WeaponRoot);
      
          WeaponMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(FName("WeaponMeshComponent"));
          //Use this instead of AttachToComponent when doing this in the constructor. Interestingly enough, AttachToComponent works as intended in Blueprint.
          WeaponMeshComponent->SetupAttachment(WeaponRoot);
      }
      ExampleCharacter.cpp
      Code:
      if (WeaponBlueprint)
          {
              //UE4 sometimes struggles with passing socket name as TEXT("SocketName"). Using this instead...
              FName SocketName("WeaponSocket");
              FActorSpawnParameters spawnParams;
              spawnParams.Owner = this;
      
              //Spawn weapon at 0,0,0 with 0,0,0 rotation. A precaution...
              Weapon = GetWorld()->SpawnActor<AUrathaWeapon>(WeaponBlueprint, FVector(0.f, 0.f, 0.f), FRotator(0.f, 0.f, 0.f), spawnParams);
              UE_LOG(LogTemp, Warning, TEXT("Weapon spawned!"));
      
              //Attach to player's hand. FINALLY WORKING!
              Weapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, SocketName);
          }
      Last edited by trx88; 03-05-2019, 06:03 PM.

      Comment

      Working...
      X