Downloading Image and Setting as Material through C++

Hi guys,

I have been trying to display an image on a plane via C++ for the last few days but haven’t figured it out. I feel like I am close but am not very experienced with Unreal engine; I was hoping someone could shed some light/point me in the right direction. Essentially, I am trying to download an image via a specified link and then display that image on a plane (as a material). Currently, I am manually setting the material of the plane, but want to automate it so I can just supply a link to an image and it sets the plane to show that image.

Currently, I have an Actor that has a Root component. I create a UStaticMeshComponent and attach it to the root. Next I use the FObjectFinder to find the plane. I then set that as the StaticMesh. This is in the constructor:

	Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
	RootComponent = Root;

	Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
	Mesh->AttachTo(Root);

	
	static ConstructorHelpers::FObjectFinder<UStaticMesh> PlaneMeshAsset(TEXT("StaticMesh'/Engine/BasicShapes/Plane.Plane'"));

	Mesh->SetStaticMesh(PlaneMeshAsset.Object);

	static ConstructorHelpers::FObjectFinder<UMaterial> Material(TEXT("Material'/Game/adv_Mat.adv_Mat'"));

	TheMaterial_Dyn = UMaterialInstanceDynamic::Create((UMaterial*)Material.Object,Mesh);

After this, I simply set the Mesh’s material using the SetMaterial function in the BeginPlay() function.

Mesh->SetMaterial(0, TheMaterial_Dyn);

Now I am trying to modify this code so I can download an Image and display it on the plane. To do this I am first using a UAsyncTaskDownloadImage to download an image. On success, it calls the function to set the texture. From my understanding, the UAsyncTaskDownloadImage OnSucess will return a UTexture2DDynamic. This is where I am stuck. I am not sure how to take this image downloaded from UAsyncTaskDownloadImage and set it as the material on the plane.

	FString mURL = TEXT("http://news.mit.edu/sites/mit.edu.newsoffice/files/styles/news_article_image_top_slideshow/public/images/2019/MIT-Morphing-Wing-01_1.jpg");

	UAsyncTaskDownloadImage* mDownloadTask = NewObject<UAsyncTaskDownloadImage>();
	mDownloadTask->OnSuccess.AddDynamic(this, &AComputerVisionTest::OnGetTexture2D);
	mDownloadTask->Start(mURL);

	Mesh->SetMaterial(0, TheMaterial_Dyn);


void AComputerVisionTest::OnGetTexture2D(UTexture2DDynamic* _texture)
{
//
	TheMaterial_Dyn->SetTextureParameterValue(FName("T2DParam"), _texture);

}

Frankly, I’m not sure if I’m doing this the right way or if there is a better way to do it. Currently, it works when I do it manually (i.e. set the material manually) but I am now trying to do it automatically where it downloads the image. Any help/guidance would be greatly appreciated!

Thanks!

Hey,

I guess you won’t need the solution after three years but your post was a super starting point. So here’s my solution hope it helps others in the future.

void ATileBase::BeginPlay()
{
	Super::BeginPlay();

	imagePlane = Cast<UStaticMeshComponent>(GetDefaultSubobjectByName(TEXT("imagePlane")));


	FString mURL = TEXT("https://www.cooperhewitt.org/wp-content/uploads/2019/10/2016-54-146_01.jpg");

	mDownloadTask = NewObject<UAsyncTaskDownloadImage>();
	mDownloadTask->OnSuccess.AddDynamic(this, &ATileBase::OnGetTexture2D);
	mDownloadTask->Start(mURL);

}

void ATileBase::OnGetTexture2D(UTexture2DDynamic* _texture) {

	auto material = imagePlane->GetMaterial(0);
	UMaterialInstanceDynamic* DynMaterial = imagePlane->CreateDynamicMaterialInstance(0, material, TEXT("2dPlaneMaterial"));
	DynMaterial->SetTextureParameterValue("Image", _texture);
	imagePlane->SetMaterial(0, DynMaterial);

}

I’m using the plane2d material on my plane which has a parameter which you need address to set the image. In my case it’s just “Image”
So that’s what you need to call if you want to change the materials texture.

Hello,
I don’t know if you will see it after 8 months, but SetTextureParameterValue() function doesnt take variable type UTexture2DDynamic, it takes UTexture. How did you achieved this have you set custom SetTextureParameterValue() function for this purpose? Thanks!(lol I forgot the header I feel stupid)

How do I setup includes for that? I’m getting a linker error (LNK2019) when I try to use NewObject()