How to setup a scene capture to render into a MID?

I tried

    ScopeCam = NewObject<USceneCaptureComponent2D>();
	ScopeCam->FOVAngle = 90.f;
	ScopeCam->AttachTo(SkeletalMeshComponent, FName("ScopeFeed"), EAttachLocation::SnapToTarget);
	RenderTarget = NewObject<UTextureRenderTarget2D>();
	RenderTarget->InitAutoFormat(1024, 1024);
	RenderTarget->AddressX = TA_Wrap;
	RenderTarget->AddressY = TA_Wrap;
	UMaterialInstanceDynamic* ScopeMat = UMaterialInstanceDynamic::Create(AssetScopeMat_Default, this);
	ScopeCam->TextureTarget = RenderTarget;
	ScopeCam->bCaptureEveryFrame = true;
	ScopeCam->UpdateContent();
    ScopeMat->SetTextureParameterValue(FName("ScopeFeed"), RenderTarget);
	SkeletalMeshComponent->SetMaterial(ScopeMatIndex, ScopeMat);

All I get from this is gray. Any help is much appreciated.

Did you ever figure this out?

Also looking for an answer to this.

Your code is pretty solid in terms of functionality, here is how I would approach it though.

UCLASS()
class AMyActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AMyActor(const FObjectInitializer& ObjectInitializer);

	// Called when the game starts
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Test)
	USceneCaptureComponent2D* ScopeCam;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Test)
	UTextureRenderTarget2D* RenderTarget;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Test)
	UMaterialInterface* ScopeMat;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Test)
	int32 ScopeMatIndex;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Test)
	FName ScopeMatRTParamName;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Test)
	USkeletalMeshComponent* SkeletalMeshComponent;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Test)
	FName ScopeAttachSocketName;

	
	
};

C++ Body

AMyActor::AMyActor(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	// Set this actor to be ticked every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	SkeletalMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("SkeletalMesh_0"));

	ScopeCam = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("ScopeCam_0"));
	ScopeCam->FOVAngle = 90.f;
	
	RenderTarget = CreateDefaultSubobject<UTextureRenderTarget2D>(TEXT("RenderTarget_0"));
	RenderTarget->InitAutoFormat(1024, 1024);
	RenderTarget->AddressX = TA_Wrap;
	RenderTarget->AddressY = TA_Wrap;
	// ...

	RootComponent = SkeletalMeshComponent;
}


// Called when the game starts
void AMyActor::BeginPlay()
{
	Super::BeginPlay();

	ScopeCam->AttachTo(SkeletalMeshComponent, ScopeAttachSocketName, EAttachLocation::SnapToTarget);
	ScopeCam->TextureTarget = RenderTarget;
	ScopeCam->bCaptureEveryFrame = true;
	ScopeCam->UpdateContent();

	if (ScopeMat != nullptr && SkeletalMeshComponent != nullptr)
	{
		UMaterialInstanceDynamic* MID = SkeletalMeshComponent->CreateAndSetMaterialInstanceDynamicFromMaterial(ScopeMatIndex, ScopeMat);
		MID->SetTextureParameterValue(ScopeMatRTParamName, RenderTarget);
	}
	// ...
}

This code definitely works. If you are still getting a checkerboard gray material, make sure your material has “Use with Skeletal Meshes” enabled.

Thanks for this Allar, I did have something similar to this, but it ends up crashing when I attempt to SetTextureParameterValue. The RenderMaterial and MID are both valid when attempting to set this. I have included the code segment, material and exception I receive.

		MID = UMaterialInstanceDynamic::Create(RenderMaterial, this);
		MID->SetTextureParameterValue(FName("CameraRender"), RenderTarget);

Unknown exception - code 00000001 (first/second chance not available)

Assertion failed: Value->TextureReference.TextureReferenceRHI [File:D:\BuildFarm\buildmachine_++depot+UE4-Releases+4.7\Engine\Source\Runtime\Engine\Private\Materials\MaterialUniformExpressions.cpp] [Line: 333]

Looks like the RenderTarget texture is invalid.

For anyone looking for a solution in the future… this is what I ended up with.

// Sets default values for this actor's properties
ASRSecurityCamera::ASRSecurityCamera(const FObjectInitializer& ObjectInitializer)
	:Super(ObjectInitializer)
{
 	// Set this actor to be ticked every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CameraID = 0;
	CameraMaxYaw = 70.0f;
	CameraPitch = -30.0f;
	CameraViewDistance = 100.0f;

	CameraMesh = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("CameraMesh"));
	CameraView = ObjectInitializer.CreateDefaultSubobject<USceneCaptureComponent2D>(this, TEXT("CameraView"));
	RootComponent = CameraView;
	CameraMesh->AttachParent = CameraView;
	


	// ...
}

// Called when the game starts
void ASRSecurityCamera::BeginPlay()
{
	Super::BeginPlay();

	RenderTarget = NewObject<UTextureRenderTarget2D>();
	RenderTarget->InitAutoFormat(1024, 1024);
	RenderTarget->AddressX = TA_Wrap;
	RenderTarget->AddressY = TA_Wrap;

	CameraView->TextureTarget = RenderTarget;
	CameraView->bCaptureEveryFrame = true;
	CameraView->UpdateContent();

	if (RenderMaterial != nullptr)
	{
		MID = UMaterialInstanceDynamic::Create(RenderMaterial, this);
		
	}

	// ...

}


// Called every frame
void ASRSecurityCamera::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );
	if (RenderTarget->TextureReference.IsInitialized())
	{
		MID->SetTextureParameterValue(FName("CameraRender"), RenderTarget);
	}
	// ...
}

I’m guessing that the ScopeMat, ScopeMatIndex and ScopeMatRTParamName are set in the Blueprint? Also, if I just create the RenderTarget as above, it doesn’t pass the if (RenderTarget != nullptr) condition. How should it be initialized? (I’m new to UE :P)

Where do you see the RenderTarger != nullptr check? All I see on the answer below this one is the RenderMaterial != nullptr check.

But shouldn’t RenderTarget be different from nullptr?