PFPaintForge User Guide
العربية
RUNTIME MATERIAL PAINTING FOR UNITY

Paint color.
Copy material properties.

PaintForge lets players paint objects and characters at runtime, sample visible colors, copy reflection and HDR emission, fill or clear targets, and copy complete textured appearances.

3Paint backends
HDREmission
MeshStatic & skinned
RuntimePlayer controlled

What is included

Runtime

Painting, sampling, material copying, player, camera, controls, and user-interface components.

Prefabs

Ready-to-use PaintForge player and paint system objects.

Demo

A showcase for color, reflection, emission, and texture copying.

Shaders & Materials

Compatible painting shaders and example materials.

Demo sceneOpen Assets/PaintForge/Samples/Demo/Scenes/PaintForgeShowcase.unity to test all features.

Before installation

Unity and rendering

Designed for Unity 6 with the Universal Render Pipeline. Add the sample Volume when you need visible HDR bloom.

Input System

The player and rebindable controls use Unity's Input System package and UnityEngine.InputSystem.

Models

UV painting needs readable geometry, a valid UV0 channel, and an accurate MeshCollider. Vertex painting needs enough vertices.

Materials

Use the supplied compatible materials for painted color, reflection, emission, and texture-copy output.

Add PaintForge to a scene

1

Test the demo

Play the showcase and verify the controls.

2

Add the player

Drag the PaintForge player prefab into your scene.

3

Add the system

Add the paint system prefab and assign the gameplay camera.

4

Prepare targets

Add PaintForgeUVPaintable and a suitable collider.

Default controls

InputActionUsage
W A S DMoveMove relative to the camera.
ShiftSprintHold while moving.
TabColor LabOpen or close the painting UI.
LMBPaintPaint the target under the cursor.
RMB + DragBrush sizeChange brush radius.
SpaceLive sampleHold and move to sample color, reflection, and emission.
ICopy appearanceCopy and immediately apply a complete appearance.
FFillFill the hovered paintable target.
CClearClear the hovered target.
6 / 7 / 8Brush modeSharp / Soft / Blend.
F1HelpShow the in-game guide.
F2SettingsChange controls and player settings.
Space vs ISpace updates the active brush while held; paint or fill afterward. I applies the complete copied appearance immediately.

Make an object paintable

UV Render Texture is recommended for detailed props and walls. Skinned characters are supported. Vertex Color quality depends on mesh vertex density.

Unity cubesPrimitive cubes have very few vertices. Use UV Render Texture or a subdivided mesh for detailed strokes.

Copy color and material properties

01

Color

Hold Space over a source to load its visible color into the brush.

02

Reflection

The sampled surface response is used by the next stroke or fill.

03

HDR Emission

Emission strength and HDR color are sampled together to preserve glow.

04

Full Texture

Aim at a textured source and press I to copy its complete supported appearance.

Choose a paint backend

BackendBest forNeeds
UVRenderTextureDetailed objects, walls, close views.Valid UV0, MeshCollider, compatible material.
VertexColorCharacters and dense meshes.Enough vertices and compatible shader.
MaterialTintSimple whole-object color changes.Supported Renderer color property.

1024 is a practical starting resolution for UV painting. Use less for distant/mobile targets and more only for important close-up objects.

Player, camera, and customization

Controller

Configure walking, sprinting, acceleration, air control, rotation, jump, and gravity in the Inspector.

Camera

Assign the player target and configure orbit, zoom, sensitivity, and distance.

Paintable player

Add and configure PaintForgeUVPaintable on the player visual to receive paint and copied properties.

Control settings

Edit defaults on PaintForgePlayerControls. Players can customize supported controls with F2.

Saved settingsIn-game choices override Inspector defaults. Use Clear Saved User Overrides before testing changed defaults.

Component settings

PaintForgeUVPaintSystem
Paint CameraCamera used to raycast from the pointer.
Ray DistanceMaximum target detection distance.
Brush ModeSharp, Soft, or Blend.
Active ColorCurrent brush color.
Stroke IntervalTime between held-paint stamps; lower values are smoother but more expensive.
Character PaintablePlayer fallback used by supported fill/copy actions.
PaintForgeUVPaintable
BackendUVRenderTexture, VertexColor, or MaterialTint.
Allow Style CopyAllows complete appearance copying to this target.
Paint Mode EnabledAllows brush strokes.
Texture Copy Mode EnabledAllows copied texture appearances.
Texture Copy PriorityPrioritizes full appearance copy when modes overlap.
ResolutionRuntime paint texture size; 1024 is the default practical balance.
Clear ColorValue restored by Clear.
Paint Composite MaterialCompatible material used to display paint and surface channels.
PaintForgeUVPaintUI

Paint System connects the interface to the active system. Open On Start controls initial visibility. Wheel Size sets the generated color-wheel size.

Third Person Controller

Camera Transform, Walk/Sprint Speed, Acceleration, Air Control, Rotation Smooth Time, Allow Jump, Jump Height, Gravity, Grounded Vertical Velocity, keyboard/sprint/jump input toggles.

Third Person Camera

Target and Target Name; Distance, Height, Look Height and smoothing; orbit sensitivity and pitch limits; minimum/maximum zoom; collision mask, radius, and buffer.

PaintForgePlayerControls

Default movement, interface, painting, brush, and orbit keys plus look sensitivity, zoom sensitivity, and Invert Y. Runtime user choices are saved and take priority.

Runtime API reference

All core types are in the PaintForge namespace.

PaintForgeUVPaintSystem properties

MemberTypeDescription
BrushSizefloatCurrent normalized brush size.
ActiveColorColorCurrent brush color.
BrushModePaintForgeBrushModeSharp, Soft, or Blend.
BrushOpacityfloatCurrent stroke opacity.
BrushHardnessfloatCurrent edge hardness.
EmissionStrengthfloatActive emission amount.

PaintForgeUVPaintSystem methods

SetColor(Color color)

Changes the active brush color.

SetBrushMode(PaintForgeBrushMode mode)

Selects Sharp, Soft, or Blend.

SetBrushSize(float value)

Sets normalized brush size and clamps it to 0–1.

SetSurfaceResponse(float reflection, float emission)

Changes the surface values carried by new strokes.

StampHovered(Vector2 screenPosition)

Paints at the supplied screen coordinate.

FillHovered(Vector2 screenPosition)

Fills the paintable under the supplied coordinate.

ClearHovered(Vector2 screenPosition)

Clears the paintable under the pointer.

SampleColorHovered(Vector2 screenPosition)

Samples visible color.

CopyColorAndSurfaceHovered(Vector2 screenPosition)

Samples color, reflection, and emission into the brush.

CopyStyleHovered(Vector2 screenPosition)

Copies the supported complete appearance.

TryGetPaintHit(...)

Returns true and outputs the target and RaycastHit when a valid paintable is found.

PaintForgeUVPaintable properties and methods

PaintTexture

The current UV paint RenderTexture.

Backend

The configured PaintForgeBackend.

PaintModeEnabled

Whether brush painting is enabled.

TextureCopyModeEnabled

Whether texture copy is enabled.

SetSurfaceResponse(metallic, smoothness, reflection, emission)

Sets base surface response values.

SetStrokeEmissionColor(Color color)

Sets the HDR emission color for future strokes.

CopyStyleFrom(Renderer source, bool copyTexture, bool prioritizeTexture = false, bool copySurfaceSettings = false)

Copies supported properties from a renderer.

SetFlatCopiedAppearance(Color color, float reflection, float emission, Color emissionColor)

Applies a flat copied appearance without a source texture.

Stamp(Vector2 uv, Color color, ...)

Low-level UV stroke including opacity, hardness, surface data, world point/radius, and optional stamp texture.

StampVertex(Vector3 worldPoint, Color color, ...)

Low-level world-space stroke for VertexColor targets.

Fill(Color color, float reflection = 0, float emission = 0)

Fills the complete target.

Clear()

Restores the target's clear state.

C# · Control PaintForge from gameplay
using PaintForge;
using UnityEngine;
using UnityEngine.InputSystem;

public class PaintAbility : MonoBehaviour
{
    [SerializeField] PaintForgeUVPaintSystem paintSystem;

    public void SelectRedGlow()
    {
        paintSystem.SetColor(Color.red);
        paintSystem.SetBrushMode(PaintForgeBrushMode.Soft);
        paintSystem.SetBrushSize(0.25f);
        paintSystem.SetSurfaceResponse(0.15f, 2.0f);
    }

    public void FillAtCursor()
    {
        paintSystem.FillHovered(Mouse.current.position.ReadValue());
    }
}

Input API

PaintForgeInputSettings.GetKey(action)

Returns the saved key or Inspector/default fallback.

SetKey(action, key)

Saves a new key in PlayerPrefs.

IsPressed(action)

True while the action key is held.

WasPressedThisFrame(action)

True only on the press frame.

LookSensitivity / ZoomSensitivity / InvertY

Saved user camera properties.

ResetDefaults()

Deletes all saved PaintForge control overrides.

DisplayName(action)

Returns a user-facing action name.

RegisterInspectorDefaults(...)

Registers prefab defaults used when no user override exists.

C# · Rebind Fill
using PaintForge;
using UnityEngine.InputSystem;

PaintForgeInputSettings.SetKey(PaintForgeAction.Fill, Key.G);
PaintForgeInputSettings.LookSensitivity = 1.25f;
// Restore package/Inspector defaults:
PaintForgeInputSettings.ResetDefaults();

Lightweight color painting

The optional Offline system provides simple whole-renderer color painting with palette, sampling, fill, undo, and clear operations.

ActiveColor / BrushSize

Current simple-paint values.

SelectPalette(int index)

Selects a configured palette entry.

SetActiveColor(Color color)

Sets the simple paint color.

SetBrushSize(float size)

Clamps size between 0.05 and 1.

PaintAtScreenPosition(Vector2 position)

Paints the OfflinePaintable under a screen point.

FillHovered(Vector2 position)

Fills the hovered simple target.

SampleHovered(Vector2 position)

Samples its current color.

Undo()

Reverts the last simple paint operation.

ClearAllPaint()

Resets every tracked OfflinePaintable.

OfflinePaintable.SetPaintColor(Color)

Changes one target.

OfflinePaintable.ResetPaint()

Restores its default color.

Common questions

F does not fill

Open Color Lab with Tab, verify the target has PaintForgeUVPaintable and a collider, and check the F2 key assignment.

Paint is stretched or appears on another face

Use a MeshCollider instead of a BoxCollider and check UV0 for overlap or stretching.

A texture sample is black or incorrect

Confirm the cursor hits the intended renderer and the MeshCollider returns the correct texture coordinate.

Painted emission looks weak

Use a compatible PaintForge shader and enable Bloom in the URP Volume.

An object becomes black in Play Mode

Check its Base Material, Tint, and shader. Remove PaintForgeUVPaintable from architecture that is not intended to be painted.

No valid paintable MeshCollider

The cursor hit a non-paintable collider. Add PaintForgeUVPaintable and a matching MeshCollider if that object should receive paint.

PAINTFORGE

Ready to paint.

Start with the included showcase, then reuse the configured prefabs in your project.

Back to top ↑
Copied