Unreal Engine provides loading of 3D models stored in Content directory as a format of converted assets. However, In some project, you may need to load 3D models at runtime which cannot be stored at Content directory.
What is glTF?
glTFRuntime plugin
You can use glTF 3D files in Unreal Engine thanks to the glTFRutime plugin.
https://github.com/rdeioris/glTFRuntime
However, most of the documentation focuses on Blueprint usage. If you want to use this plugin in C++, you can use below example.
(This plugin already provides AglTFRuntimeAssetActor class, but this class is derived from AActor to show how to use C++ APIs).
How to use glTF 3D model as a member component of an actor
To use this plugin in my project, I had to use it as a member component of my pre-existing actor class. I modified AglTFRuntimeAssetActor to be USceneComponent derived class so to be added attached member of actor object.
![]() |
Dynamically loaded glTF models in animation |
// glTFRuntimeComponent.h #pragma once #include "CoreMinimal.h" #include "Components/SceneComponent.h" #include "glTFRuntimeAsset.h" #include "glTFRuntimeComponent.generated.h" UCLASS() class MYPROJECT_API UglTFRuntimeComponent : public USceneComponent { GENERATED_BODY() public: // Sets default values for this actor's properties UglTFRuntimeComponent(); void LoadFromFile(const FString& FileName); void LoadFromUrl(const FString& Url); protected: UFUNCTION() void OnLoadCompleted(UglTFRuntimeAsset* InAsset); void BuildMesh(); // Interface function from AActor void SetRootComponent(USceneComponent* Component) { RootComponent = Component; } USceneComponent* GetRootComponent() { return RootComponent; } void AddInstanceComponent(USceneComponent* SceneComponent) { } USceneComponent* RootComponent; ... // From source of glTFRuntime/Plugin's glTFRuntimeAssetActor.h |
// glTFRuntimeComponent.cpp #include "glTFRuntimeComponent.h" #include "Kismet/KismetSystemLibrary.h" #include "Components/InstancedStaticMeshComponent.h" #include "Components/LightComponent.h" #include "Components/SkeletalMeshComponent.h" #include "Engine/StaticMeshSocket.h" #include "glTFRuntimeFunctionLibrary.h" #include "Animation/AnimSequence.h" // Sets default values UglTFRuntimeComponent::UglTFRuntimeComponent() { // Set this actor to call Tick() every frame. PrimaryComponentTick.bCanEverTick = true; AssetRoot = CreateDefaultSubobject<USceneComponent>(TEXT("AssetRoot")); AssetRoot->SetupAttachment(this); RootComponent = AssetRoot; bAllowNodeAnimations = true; bStaticMeshesAsSkeletal = false; bAllowSkeletalAnimations = true; bAllowPoseAnimations = true; bAllowCameras = true; bAllowLights = true; bForceSkinnedMeshToRoot = false; RootNodeIndex = INDEX_NONE; } // Called when the game starts or when spawned void UglTFRuntimeComponent::BeginPlay() { Super::BeginPlay(); } void UglTFRuntimeComponent::LoadFromFile(const FString& FileName) { FglTFRuntimeConfig LoaderConfig; Asset = UglTFRuntimeFunctionLibrary::glTFLoadAssetFromFilename(FileName, false, LoaderConfig); BuildMesh(); } void UglTFRuntimeComponent::LoadFromUrl(const FString& Url) { FglTFRuntimeConfig LoaderConfig; TMap<FString, FString> Headers; FglTFRuntimeHttpResponse Response; Response.BindUFunction(this, TEXT("OnLoadCompleted")); // If you want to load glTF Samples from 'https://github.com/KhronosGroup/glTF-Sample-Models', // Replace model's url as below. // https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master / + /2.0/BoxAnimated/glTF-Binary/BoxAnimated.glb UglTFRuntimeFunctionLibrary::glTFLoadAssetFromUrl(Url, Headers, Response, LoaderConfig); } void UglTFRuntimeComponent::OnLoadCompleted(UglTFRuntimeAsset* InAsset) { if (InAsset == nullptr) { UE_LOG(LogTemp, Log, TEXT("Failed to load url")); return; } Asset = InAsset; BuildMesh(); } ... // From source of glTFRuntime/Plugin's glTFRuntimeAssetActor.cpp |
To show how to use this class, MyActor had member variable of glTFRuntimeComponent.
// MyActor.h #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "glTFRuntimeComponent.h" #include "MyActor.generated.h" UCLASS() class MYPROJECT_API AMyActor : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AMyActor(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; UPROPERTY(EditAnywhere, Category = "MyActor") FString FileName; UPROPERTY(EditAnywhere, Category = "MyActor") FString Url; public: // Called every frame virtual void Tick(float DeltaTime) override; UglTFRuntimeComponent* GltfComponent; }; | cs |
// MyActor.cpp #include "MyActor.h" // Sets default values AMyActor::AMyActor() { // Set this actor to call Tick() every frame. PrimaryActorTick.bCanEverTick = true; GltfComponent = CreateDefaultSubobject<UglTFRuntimeComponent>(TEXT("GltfComponent")); GltfComponent->SetupAttachment(RootComponent); } // Called when the game starts or when spawned void AMyActor::BeginPlay() { Super::BeginPlay(); if (!FileName.IsEmpty()) { FString FullPath = FPaths::ConvertRelativePathToFull(FPaths::ProjectDir() + FileName); GltfComponent->LoadFromFile(FullPath); } else if (!Url.IsEmpty()) { GltfComponent->LoadFromUrl(Url); } } // Called every frame void AMyActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); } | cs |
Here you can add MyActor in a level and set FileName or Url property.
![]() |
MyActors with glTF components |
You can see below reference as an example.
Example project:
https://github.com/odyssey2010/unreal_gltf_runtime_scene
Comments
Post a Comment