As the following pic shows in BP, how to add and remove a Box Collision Component in C++:
In The Declaration class definition file (.h)
UBoxComponent* CollisionMesh = nullptr;
In The constructor class definition file (.cpp) :
CollisionMesh = CreateDefaultSubobject<UBoxComponent>(FName("Collision Mesh"));
If you need to put it at the top hierarchy:
SetRootComponent(CollisionMesh);
If you need add other child component like particle system :
Blast = CreateDefaultSubobject<UParticleSystemComponent>(FName("BlastExplosion"));
Blast->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform); // since 4.12 isn't AttachTo(1arg) anymore, but AttachToComponent(2args)
CreateDefaultSubobject works only in constructor. Everywhere else use NewObject.
That’s very helpful, your suggestion is very carefual. Thx so much! Have a nice day!
A little problem:I found that add box woks only in constructor, otherwise it doesn’t work.
Try this one :
UBoxComponent* MyNewBox = NewObject<UBoxComponent>(this);
Even I use NewObject(this); ,
but it also doesn’t work. Following is my code, is there any thing wrong?
void ATopDownTestGameMode::BeginPlay()
{
Super::BeginPlay();
FString BPPath("/Game/TopDownCPP/Blueprints/TopDownCharacter_2.TopDownCharacter_2_C");
UClass* UC = LoadClass<ACharacter>(NULL, *BPPath);
if (UC)
{
for (int i = 0; i < 3; i++)
{
ATopDownTestCharacter* Character = GetWorld()->SpawnActor<ATopDownTestCharacter>(UC, FVector(-282.f, i * 100, 500.f), FRotator(0.f, 0.f, 0.f));
ATopDownTestPlayerController* Controller = GetWorld()->SpawnActor<ATopDownTestPlayerController>(ATopDownTestPlayerController::StaticClass(), Character->GetActorLocation(), Character->GetActorRotation());
Controller->Possess(Character);
RoleArray.Add(Character);
ControllerArray.Add(Controller);
Character->CollisionMesh = NewObject<UBoxComponent>(Character);
Character->CollisionMesh->SetBoxExtent(FVector(32.f, 32.f, 96.f));
Character->CollisionMesh->bDynamicObstacle = true;
Character->CollisionMesh->AttachToComponent(Character->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
}
}
}
I’ve tried your code and everything works, Every new Character have a BoxComponent_X
TopDownTestGameMode.h
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "GameFramework/GameMode.h"
#include "TopDownTestGameMode.generated.h"
UCLASS(minimalapi)
class ATopDownTestGameMode : public AGameMode
{
GENERATED_BODY()
public:
ATopDownTestGameMode();
TArray<class ATopDownTestCharacter*> RoleArray;
TArray<class ATopDownTestPlayerController*> ControllerArray;
private:
virtual void BeginPlay() override;
};
TopDownTestGameMode.cpp :
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "TopDownTest.h"
#include "TopDownTestGameMode.h"
#include "TopDownTestPlayerController.h"
#include "TopDownTestCharacter.h"
ATopDownTestGameMode::ATopDownTestGameMode()
{
// use our custom PlayerController class
PlayerControllerClass = ATopDownTestPlayerController::StaticClass();
// set default pawn class to our Blueprinted character
static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/TopDownCPP/Blueprints/TopDownCharacter"));
if (PlayerPawnBPClass.Class != NULL)
{
DefaultPawnClass = PlayerPawnBPClass.Class;
}
}
void ATopDownTestGameMode::BeginPlay()
{
Super::BeginPlay();
UE_LOG(LogTemp, Warning, TEXT("BeginPlay report for Duty !!!"));
FString BPPath("/Game/TopDownCPP/Blueprints/TopDownCharacter.TopDownCharacter_C");
UClass* UC = LoadClass<ACharacter>(NULL, *BPPath);
if (UC)
{
for (int i = 0; i < 3; i++)
{
ATopDownTestCharacter* Character = GetWorld()->SpawnActor<ATopDownTestCharacter>(UC, FVector(-282.f, i * 100, 500.f), FRotator(0.f, 0.f, 0.f));
ATopDownTestPlayerController* Controller = GetWorld()->SpawnActor<ATopDownTestPlayerController>(ATopDownTestPlayerController::StaticClass(), Character->GetActorLocation(), Character->GetActorRotation());
Controller->Possess(Character);
RoleArray.Add(Character);
ControllerArray.Add(Controller);
Character->CollisionMesh = NewObject<UBoxComponent>(Character);
Character->CollisionMesh->SetBoxExtent(FVector(32.f, 32.f, 96.f));
Character->CollisionMesh->bDynamicObstacle = true;
Character->CollisionMesh->AttachToComponent(Character->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
}
}
}
TopDownTestCharacter.h :
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "GameFramework/Character.h"
#include "TopDownTestCharacter.generated.h"
UCLASS(Blueprintable)
class ATopDownTestCharacter : public ACharacter
{
GENERATED_BODY()
public:
ATopDownTestCharacter();
// Called every frame.
virtual void Tick(float DeltaSeconds) override;
/** Returns TopDownCameraComponent subobject **/
FORCEINLINE class UCameraComponent* GetTopDownCameraComponent() const { return TopDownCameraComponent; }
/** Returns CameraBoom subobject **/
FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
private:
/** Top down camera */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* TopDownCameraComponent;
/** Camera boom positioning the camera above the character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* CameraBoom;
/** A decal that projects to the cursor location. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UDecalComponent* CursorToWorld;
public:
class UBoxComponent* CollisionMesh;
};
Oh, I see. It’s my problem, sorry for that.
by the way, I found a problem:
if create box collision in constructor, the property Dynamic Obstacle would works, as following pic shows:
but if create box collision in other function, Dynamic Obstacle doesn’t work:
Don’t forget to add the Box collider header :
#include "Components/BoxComponent.h"
Otherwise, it won’t compile and won’t show up with Intellisense.