Skip to content

Latest commit

 

History

History
149 lines (122 loc) · 3.88 KB

Adding icon-sprite to Component.md

File metadata and controls

149 lines (122 loc) · 3.88 KB

2021-04-03_18:13:02

Adding icon/sprite to Component

All Scene Component subclasses has the option to get an icon representation in the Editor Viewport. This makes it possible too see and identify the Component even if it doesn't have an inherent visual representation. The icon is an editor-only feature and all related code should be guarded by a #if WITH_EDITORONLY_DATA.

To request an icon set the bVisualizeComponent member variable to true in the constructor. This member variable is checked in USceneComponent::OnRegister and if true a Billboard Component is created.

MyComponent.h:

#pragma once
#include "Component/SceneComponent.h"

UCLASS()
class MYMODULE_API UMyComponent : public USceneComponent
{
    GENERATED_BODY()
public:
    UMyComponent();
};

MyComponent.cpp:

#include "MyComponent.h"

UMyComponent::UMyComponent()
{
#if  WITH_EDITORONLY_DATA
    bVisualizeComponent = true;
#endif
}

By default the Component will get a white sphere icon. If we want another icon we can change it after the base class has created the default one. This can be done after the call to the Super implementation of OnRegister.

MyComponent.h:

#pragma once
#include "Component/SceneComponent.h"

UCLASS()
class MYMODULE_API UMyComponent : public USceneComponent
{
    GENERATED_BODY()

public:
    UMyComponent();

    //~ Begin ActorComponent Interface.
    virtual void OnRegister() override;
    //~ End ActorComponent Interface.
}

The Sprite Component is in fact a Billboard Component so we need that header file. After Super::OnRegister(); we call SetSprite on the Sprite Component and pass in a texture that we load.

MyComponent.cpp:

#include "MyComponent.h"
#include "Components/BillboardComponent.h"

UMyComponent::UMyComponent()
{
#if  WITH_EDITORONLY_DATA
    bVisualizeComponent = true;
#endif
}

void UMyComponent::OnRegister()
{
    Super::OnRegister();
#if  WITH_EDITORONLY_DATA
    if (SpriteComponent)
    {
        SpriteComponent->SetSprite(LoadObject<UTexture2D>(
            nullptr, TEXT("/Game/EditorResources/Icons/S_MyIcon.S_MyIcon")));
    }
#endif
}

An alternative way is to load the texture once with a static local variable in the constructor and then reuse it for all instances of that Component type.

MyComponent.h:

#pragma once
#include "Component/SceneComponent.h"

UCLASS()
class MYMODULE_API UMyComponent : public USceneComponent
{
    GENERATED_BODY()

public:
    UMyComponent();

    //~ Begin ActorComponent Interface.
    virtual void OnRegister() override;
    //~ End ActorComponent Interface.

private:
#if WITH_EDITORONLY_DATA
    UPROPERTY(Transient)
    UTexture2D* EditorSpriteTexture;
#endif
}

MyComponent.cpp:

UMyComponent::UMyComponent()
{
#if WITH_EDITORONLY_DATA
    bVisualizeComponent = true;
    if (!IsRunningCommandlet())
    {
        static ConstructorHelpers::FObjectFinder<UTexture2D> StaticTexture(
            TEXT("/Game/EditorResources/Icons/S_MyIcon"));
        EditorSpriteTexture = StaticTexture.Object;
    }
#endif
}

void UMyComponent::OnRegister()
{
    Super::OnRegister();
#if  WITH_EDITORONLY_DATA
    if (SpriteComponent)
    {
        SpriteComponent->SetSprite(EditorSpriteTexture);
    }
#endif
}

I don't know why the the first version repeats the asset name in the path while the second version don't. Also don't know why the second version checks IsRunningCommandlet() while the first version don't. The first version is based on AudioComponent. The second version is based on CameraShakeSourceComponent.

[[2021-05-06_21:33:14]] Adding icon-sprite to Actor