BP_InteractableActor — which owns the collision, the outline
highlight, the “Press E” prompt, and an Interact event your player pawn fires at
whatever it is looking at. You want a readable note to be one more interactable in that
system. You do not want Inkwell’s own trace, its own prompt, or its own key bindings.
That works, and it is the intended path. The production pieces of Inkwell —
Ink Page Display (UInkPageDisplayComponent),
Ink Page Stack, the Ink Page actor, the
Ink Page widget, and the
Ink Page Reader (UInkPageReaderComponent) — contain no input
handling and no focus tracing whatsoever. They are services your interaction system
calls: your interact verb calls Begin Reading / End Reading on the reader, your
page-turn input calls Next Page / Previous Page, your flip input calls Flip
Page. That is the whole integration surface.
BlueprintCallable or BlueprintPure — on a component you add from the Components panel,
or on the Ink Page widget you drag in from the UMG palette.The walkthrough
Add an Ink Page Display to your interactable
BP_InteractableActor and choose Create Child
Blueprint Class, then name it BP_ReadableNote.- In the Components panel, click Add and search for Ink Page Display.
(It is in the Inkwell class group; the C++ class is
UInkPageDisplayComponent.) - Select the new component and set Document (category Inkwell | Page) to your Ink Page Document asset.
- Leave Page Index at 0.

An Ink Page Display component in the Details panel.
Decide where the page is drawn: your mesh, or Inkwell's sheet
- Use your own mesh
- Let Inkwell make the sheet
- Inkwell replaces the material in Material Slot with a dynamic instance of
the page ink material, and pushes the baked ink plus the document’s paper
settings into it. Whatever material was in that slot is gone, for that slot. (The
exceptions are the document paper modes Custom Material — your material, with
the
MF_InkwellPageInkfunction in it, replaces the slot — and Mesh’s Own Material, which replaces nothing and drives the ink into the material the mesh already wears. See Paper.) - The mesh needs clean 0–1 UVs across the page face — or a Page Face mapping that says which UV rectangle the face actually occupies. Without either, an atlas-mapped prop mesh garbles the text.
- Inkwell never resizes your mesh. The page’s aspect ratio comes from the document’s Page Size Pixels; if your mesh face is not that shape, the writing is stretched to fit it. Match the mesh to the document’s aspect — Get Effective Page Size Cm on the component gives you the exact centimeters — or accept the distortion.
- Procedural Paper does nothing while the actor supplies a mesh. It is a fallback, never a takeover: it can never replace a prop you provided.
Point your own focus logic at the page
- The spawned sheet answers only Visibility. If your focus trace runs on a custom trace channel, either trace against the actor’s own collision instead, or set a response on the sheet yourself: Get Procedural Paper Mesh on the display → Set Collision Response To Channel (your channel, Block) after Begin Play.
- Ink Page Stack sheets answer only their own Sheet Trace Channel (default Visibility). Set every stack’s Sheet Trace Channel to match your trace channel, or the stack never registers under your crosshair — with no warning anywhere.
Open the reading view from your Interact event
- Drive an Ink Page Reader (page floats up in the world)
- Show it on screen (UMG)
UInkPageReaderComponent) contains no
input handling whatsoever. It is a pure “float this page up to the camera and put it
back afterwards” service that you call. It is a production component — only its
optional flip-key convenience touches input, and that is a checkbox.On the player pawn, once:- Components → Add → Ink Page Reader. Do not add an Ink Page Interactor.
- The defaults are tuned: Fit Page To View (true) computes the hold distance from the page’s real size and the camera FOV, so a poster and a sticky note both fill View Fill Fraction (0.75) of the screen, clamped between Min View Distance (18 cm) and Max View Distance (90 cm). Untick it to use the flat View Distance (45 cm) instead. Keep Clear Of Obstructions (true) traces so the held page is never buried in a desk or podium.
- If you will bind the flip to your own input, untick Bind Flip Key — on by default, it binds Flip Key (F) directly on the pawn, without consuming, so a two-sided page can be turned over out of the box.
BP_ReadableNote, override your base class’s interact event:- From the interacting pawn (your event’s instigator pin) → Get Component by Class, Component Class = Ink Page Reader.
- → Is Reading → Branch.
- True → End Reading, so the same key closes the page.
- False → Begin Reading Actor, Page Actor = Self.
Turn pages — and flip them — from your own input
- your “next page” input → the pawn’s Ink Page Reader → Next Page
- your “previous page” input → the pawn’s Ink Page Reader → Previous Page
- your “flip” input → Flip Page (only if you turned Bind Flip Key off)
- your “next page” input → reader → Is Reading → Branch (False → do nothing).
- True → reader → Get Current Page, which returns the Ink Page Display being read.
- → Is On Last Page → Branch.
- True → reader → End Reading — “one more press closes the note”.
- False → reader → Next Page.
Close, and give control back
The shipped Enhanced Input actions
If your pawn’s input is Enhanced Input,/Inkwell/Examples/Input/ saves you four assets:
IA_Interact, IA_NextPage, IA_PreviousPage, and IA_PutBack — plain digital
button actions with no logic in them — plus IMC_InkwellDefault, a ready-made Input
Mapping Context binding them to E, Right, Left, and Q, with mouse wheel
variants of the two page turns. Use them as-is, add
the four actions to your own mapping context under your own keys, or ignore them and use
your own actions; they are names, nothing more.
To wire them straight to the reader:
- On your pawn’s Begin Play: Get Controller → Cast To Player Controller →
Enhanced Input Local Player Subsystem → Add Mapping Context, Mapping Context =
IMC_InkwellDefault(or your own IMC carrying the four actions). - In the pawn’s Event Graph, add the four Enhanced Input events and, from the pawn’s Ink Page Reader:
What not to bring across
The bundled interaction pieces exist so an empty project is readable out of the box and so the showroom is a complete worked reference. In a project that has its own interaction system they are duplicates, and they will fight you. The Ink Page Interactor’s trace. It line-traces from the player’s view every Focus Check Interval (0.1 s) out to Interaction Distance (300 cm) on Trace Channel (Visibility), and raises its own On Focus Changed. Running it alongside your own focus system gives you two sources of truth for “what am I looking at”, two prompts to keep in sync, and a second definition of interaction range. Its key bindings. With Enable Default Input on — the default — the interactor binds keys directly on the owning pawn: Interact Key (E) to interact, Put Back Key (Q) to close, Previous Page Key (Left) or mouse wheel down for the previous page, Next Page Key (Right) or mouse wheel up for the next. Those bindings sit underneath your input system and will double-fire your own interact key. The demo pawn, game mode, prompt widget, and exhibit component.AInkwellReaderCharacter, AInkwellReaderGameMode, WBP_InkwellReadPrompt, and the
Inkwell Exhibit component are the showroom’s furniture — read them as the worked example
they are (Example content walks through each), and leave them there.
Your system’s concept, and Inkwell’s equivalent
When it does not work
My trace never finds the page
My trace never finds the page
- Your trace channel and the sheet disagree. The spawned procedural sheet blocks only the Visibility channel; an Ink Page Stack’s sheets answer only their Sheet Trace Channel. Trace Visibility, set the stack’s channel to yours, or add a response to the spawned sheet via Get Procedural Paper Mesh → Set Collision Response To Channel.
- You traced for the component’s class. Trace for the actor, then Get Component by Class — the display component has no collision of its own.
- The actor’s own collision swallowed the hit in front of the page mesh, and your code only checked the hit component. Check the hit actor for the component.
The page is blank
The page is blank
LogInkwell — the misconfiguration
cases below log Warnings naming the actor:- No document assigned. A display with no Document deliberately draws a blank sheet — the fully transparent “no ink” texture over the paper — rather than leaving whatever was in the material slot before. Blank paper means “no document”, not “broken”.
- The text layer is hidden, empty, or at zero opacity. A page is a stack of layers, and hidden layers are skipped by the bake exactly as they are in the editor preview. Open the document and check the eye toggles and layer opacities in the Layers panel.
- The document’s Paper Mode is “Mesh’s Own Material” and the mesh’s material has no
MF_InkwellPageInk. In that mode the ink is driven into the material the mesh already wears; a material without the function shows no ink and raises no error — that is the contract. Add the function to the material, or use another paper mode. - The page ink material is missing. If Page Ink Material in Project Settings → Plugins → Inkwell cannot be loaded, Inkwell falls back to whatever material the mesh already had, where the ink parameters do nothing. The Output Log carries one warning per session naming the setting.
- You are on a dedicated server or in a null-RHI build. Baking a page paints a Slate widget into a render target; with no Slate renderer there is no bake. Pages are a client-side visual.
The text is stretched, squashed, or garbled
The text is stretched, squashed, or garbled
- The mesh face is a different shape than the page. Inkwell never resizes a mesh you supplied. Scale the mesh to the document’s aspect — Get Effective Page Size Cm on the display component gives you the exact centimeters — or let Procedural Paper make the sheet, which is the right shape by construction.
- The mesh’s page face does not span 0–1 UVs. Set the component’s Page Face: Auto Fit measures the UV rectangle the face actually occupies, Custom Region takes the rectangle you type, and Rotation Quarter Turns rights an unwrap that runs sideways.
- You scaled the actor non-uniformly. X and Y at different scales distorts the page like any other texture. Use Page Scale instead: it scales both dimensions together precisely so this cannot happen.
No paper appears at all
No paper appears at all
- The actor already has a mesh component — including an empty one inherited from your interactable base class, with no static mesh assigned. The page is being drawn onto that invisible mesh. Assign a mesh to it, or point Target Mesh at a mesh that actually renders.
- Target Mesh points at something that is not a mesh component. The pick is ignored, and the component falls back to searching the actor.
- The actor has no root component, so there is nothing for the sheet to attach to.
This logs its own Warning on
LogInkwell. - Procedural Paper is off on a mesh-less actor, which is the “draw nothing” setting.
- You used an Ink Page Stack. A stack always builds its own pile of sheets, one per page, so the inherited Procedural Paper toggle is grayed out and does nothing.
LogInkwell naming the actor.Editing the document does not change what is in the level
Editing the document does not change what is in the level
- Preview In Editor is off on that component. That is the switch for level-viewport baking; turn it back on.
- You are in PIE, or in a packaged build. Displays do not watch their document. After changing a document at runtime, call Refresh on each component, widget, or actor currently showing it: the mutation invalidates the cached bake, but the material already applied keeps the texture it was handed. See Runtime documents.
- You edited the Blueprint’s component default while a placed instance overrides it. Standard Blueprint behavior — check the placed actor’s own Details panel.
- The bake failed during editor startup. A map opened by a startup script can register before the Slate renderer is usable. Inkwell retries with backoff and logs a warning if it gives up; touching the actor or reopening the map fixes it.