Are control rigs exposed at runtime
By default — **no**, Control Rigs in Unreal Engine are **not exposed for runtime manipulation** in packaged games. They’re primarily designed for **editor-time** rigging and animation authoring.
However, here’s the breakdown:
| Context | Access | Notes |
|———-|———|——-|
| **Editor / Sequencer / Animation Blueprint** | ✅ Full access | You can drive bones, curves, and constraints freely. |
| **Runtime (packaged game)** | ⚠️ Limited | You can *execute* a Control Rig via a `UControlRigComponent`, but you **can’t dynamically rebuild or edit the rig graph**. |
| **Runtime modification (C++ or Blueprint)** | ✅ *If prepared* | You can expose parameters and inputs via `RigVM` and call `Execute()` at runtime. But you must pre-compile and bake the rig. |
| **Dynamic creation or editing of Control Rig graphs** | ❌ Not supported | The `RigVMCompiler` and editor-only modules aren’t compiled into shipping builds. |
**Practical workflow if you want runtime control:**
1. Build the Control Rig in the editor.
2. Expose variables (like target transforms or IK goals).
3. Attach a `ControlRigComponent` to your skeletal mesh.
4. Update the variables at runtime from C++ or Blueprint, then call `Execute()` to re-evaluate the rig.
If your goal is **fully procedural movement without pre-baked animations** (like you mentioned before), you’ll likely want a hybrid:
– Use **Control Rig for rig logic**,
– Use **Physics / IK solvers / Pose Drivers** for runtime motion,
– Drive those systems from code instead of playing animation assets.
Would you like an example showing how to update a Control Rig variable at runtime through `UControlRigComponent`?
Yes. Lets make a very simple demo with an ready made object if possible
Perfect. Let’s do a **minimal, pure C++ runtime Control Rig demo** — no animation assets, just logic.
—
### 1. 🧠 **Goal**
Spawn a ready-made **UE mannequin**, attach a **Control Rig**, and update a bone’s rotation in real time using C++ (or Blueprint).
—
### 2. ⚙️ **Code**
Create a new **C++ Actor** class, e.g. `ARuntimeRigDemo`.
“`cpp
// RuntimeRigDemo.h
#pragma once
#include “CoreMinimal.h”
#include “GameFramework/Actor.h”
#include “ControlRigComponent.h”
#include “RuntimeRigDemo.generated.h”
UCLASS()
class ARuntimeRigDemo : public AActor
{
GENERATED_BODY()
public:
ARuntimeRigDemo();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
private:
UPROPERTY()
USkeletalMeshComponent* SkeletalMesh;
UPROPERTY()
UControlRigComponent* ControlRigComp;
float Time;
};
“`
“`cpp
// RuntimeRigDemo.cpp
#include “RuntimeRigDemo.h”
#include “Engine/SkeletalMesh.h”
#include “ControlRig.h”
#include “UObject/ConstructorHelpers.h”
ARuntimeRigDemo::ARuntimeRigDemo()
{
PrimaryActorTick.bCanEverTick = true;
// Spawn mannequin mesh
SkeletalMesh = CreateDefaultSubobject(TEXT(“SkeletalMesh”));
RootComponent = SkeletalMesh;
static ConstructorHelpers::FObjectFinder MeshFinder(
TEXT(“/Game/Characters/Mannequins/Meshes/SKM_Manny.SKM_Manny”));
if (MeshFinder.Succeeded())
SkeletalMesh->SetSkeletalMesh(MeshFinder.Object);
// Create ControlRig component
ControlRigComp = CreateDefaultSubobject(TEXT(“ControlRigComp”));
ControlRigComp->SetupAttachment(SkeletalMesh);
Time = 0.0f;
}
void ARuntimeRigDemo::BeginPlay()
{
Super::BeginPlay();
if (ControlRigComp)
{
// Load the Control Rig asset
static ConstructorHelpers::FObjectFinder RigFinder(
TEXT(“/Game/ControlRigs/CR_Mannequin.CR_Mannequin”));
if (RigFinder.Succeeded())
{
ControlRigComp->SetControlRigClass(RigFinder.Object->GetClass());
ControlRigComp->SetSkeletalMeshComponent(SkeletalMesh);
}
}
}
void ARuntimeRigDemo::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (!ControlRigComp) return;
Time += DeltaTime;
float Angle = FMath::Sin(Time) * 45.f; // oscillate between -45° and +45°
// Assume your ControlRig has a control called “HeadControl”
ControlRigComp->SetControlTransform(
TEXT(“HeadControl”),
FTransform(FRotator(0, Angle, 0))
);
ControlRigComp->Execute();
}
“`
—
### 3. 🧩 **Setup in Unreal**
1. Create a **Control Rig asset**:
– Right-click → Animation → Control Rig → name it `CR_Mannequin`.
– Add a single control (e.g., `HeadControl`) bound to the mannequin’s head bone.
– Save.
2. Place your new **`RuntimeRigDemo`** actor in the level.
3. Play — the head will oscillate at runtime using the `Execute()` loop, no animation assets involved.
—
### 4. 🌀 **Flow Summary**
– Rig graph compiled in editor → shipped rig logic
– Game spawns mesh + `UControlRigComponent`
– Variables fed dynamically → `Execute()` re-runs the rig per tick
—
Would you like me to adapt this to run entirely **in Blueprint** (no C++) for testing first — same behavior but simpler setup?
Trying to find ARuntimeRigDemo buyt connat. Went to create another -says it is already created. Where is it?>
Good — that means Unreal **already generated the C++ class**, but it’s not showing in the *Content Browser* because C++ files don’t live there by default.
Here’s how to find it quickly:
—
### 🔍 **Locate the ARuntimeRigDemo class**
1. In **Visual Studio / Rider / VS Code**, open your game’s **solution** (`YourProjectName.sln`).
2. Expand the folder:
“`
Source → YourProjectName → RuntimeRigDemo.h / RuntimeRigDemo.cpp
“`
3. If you can’t find it there:
– Look under
“`
Source/YourProjectName/Private/
Source/YourProjectName/Public/
“`
– Unreal splits `.cpp` into *Private* and `.h` into *Public* by default.
—
### 🧭 **From Unreal Editor**
– Go to **File → Refresh Visual Studio Project** (or Rider equivalent).
– Then **Tools → Open Visual Studio** → it will open directly to the source folder.
– You can also right-click the *C++ Classes* folder in **Content Browser**, choose **Show in Explorer**, and navigate manually:
“`
/YourProject/Source/YourProject/
“`
—
### ⚙️ **Optional Shortcut**
If Unreal says “already exists” when trying to add a new one:
– The files are **registered** in the `.uproject` build already.
– Just delete the `.h` / `.cpp` from `Source/YourProject/`, recompile, and Unreal will forget it.
– Or open them directly and reuse.
—
Would you like me to show the exact folder path assuming your project is named **“cPluser”** or whatever you’re currently using?