Paint in 2D


DOCUMENTATION

Thank you for using Paint in 2D ❤️

If you haven't already, please consider writing a review. They really help me out!



How do I upgrade?

First, make sure you back up your project files.

Next, install the latest version.

If for some reason the latest update breaks your project (e.g. errors in the console), then try deleting the root folder for this asset, and reinstalling it.

If it still doesn't work then let me know what the errors are so I can fix it, and revert your project to the previously backed up version so you can still continue working.



Getting Started


Step 1

Select your sprite GameObject, and find the SpriteRenderer component in the Inspector tab.

Then, open its context menu (the ⋮ button), and select the Make Paintable (Paint in 2D) option.

This will add the CwPaintableSprite and CwPaintableSpriteTexture components to it.



Step 2

Make a new GameObject, and add the CwHitScreen2D and CwPaintDecal2D components.

When combined, these components allow you to paint to all paintable sprites in your scene.

NOTE  When you add the CwHitScreen2D component, it will automatically add the CwPointerMouse, CwPointerTouch, and CwPointerPen components. These send data to the CwHitScreen2D component to give it mouse, touch, and pen support respectively.

Feel free to adjust the CwPaintDecal2D component's settings like Texture, Color, etc.



Step 3 - Done!

You can now hit the â–¶ Play button, and enjoy painting your sprite.

You can also make a build for mobile and paint with your fingers.

You can now go through all the tutorial demo scenes in the Plugins/CW/PaintIn2D/Examples folder. These take you step by step through every feature of this asset, and the description text shows you exactly what is being shown.




What Examples Are Included?

This is a list of the in-game example scenes and a description of what it shows.

Make Paintable

This shows you how to configure a sprite for painting. First, select your Sprite GameObject, and in the inspector open the Sprite Renderer component's context menu (the ⋮ button), and select the \"Make Paintable (Paint in 2D)\" option. Next, add a 2D collider to it, like the PolygonCollider2D. Once done, it should look like the \"Paintable Book\" GameObject in this scene.

Texture Painting

This shows you how to paint sprites. First, make a new GameObject, and add the CwHitScreen2D component. This will automatically add the CwPointerMouse, CwPointerTouch, and CwPointerPen components, which add painting support for mouse, touch, and tablet pens. Next, you can add the CwPaintDecal2D component, and set its Texture and Color settings as desired. The \"Paint Texture\" GameObject is an example of what this might look like.

Modifiers

This shows you how the CwPaintDecal2D component's Modifier system can be used to make the painted texture look more interesting. Simply click the \"Add Modifier\" button, and choose what you would like to modify. In this scene the \"Paint Texture\" GameObject has modifiers that randomize the angle, color, and radius of the painted texture.

Tools

This shows you how to quickly make a selection of painting tools that can be chosen using the UI. This is done by adding many painting GameObjects to the Tools GameObject. Each tool has the CwDemoButtonBuilder component, and once configured you can press the BuildAll button, where it add buttons to your UI that allows you to choose between them.

Atlas

This shows you what happens when you try to paint a sprite that's part of an atlas (if you have the Sprite Packer setting enabled). You can see that it works, but the painting resolution is reduced. This is because a texture atlas is usually high resolution, but the painting resolution is usually lower. While you can adjust the CwPaintableSpriteTexture component's Size setting to account for this - It's recommend that you remove your paintable sprites from atlases. This is because each paintable sprite has its own unique paint state, so they're not batched together, and therefore you get no benefit from putting these specific paintable sprites in an atlas.

Atlas Overlay

This shows you how high resolution painting can still be achieved with texture atlases. This is done by adding a secondary sprite on top of your atlas which is configured for painting. This allows the underlying sprite to be high resolution and part of an atlas, and the actual overlay paint sprite to be entirely separate and at a different resolution. Keep in mind the overlay sprite must not be in an atlas. Also keep in mind you must set the CwPaintableSpriteTexture.Color setting to be transparent (0 alpha/opacity). Also keep in mind you must adjust the sprite's Additional Settings / OrderInLayer or Z position so it renders on top of the base sprite.

Local Mask

This shows you how the CwPaintableSpriteTexture component's Advanced/LocalMask setting can be used to restrict painting to specific areas of your sprite. Keep in mind the mask texture must be the same size as the base sprite.

Change Counter

This shows you how the CwChangeCounter component can be used to count how many pixels of a sprite are different relative to the original sprite. This is shown in the UI using the CwChangeCounterFill and CwChangeCounterText and CwChangeCounterEvent components.

Color Counter

This shows you how the CwColorCounter component can be used to count how many pixels of a sprite match specific colors. Each color is defined using the CwColor component, which you can see are children of the Colors GameObject. The color counts are shown in the UI using the CwColorCounterFill and CwColorCounterText and CwColorCounterEvent components.

Collision Painting

This shows you how the CwHitCollisions2D and CwPaintDecal2D components can be used to apply paint at the contact point between the current sprite and another.

Continuous Collision Painting

This shows you how multiple CwHitCollisions2D components can be used at the same time. This is done by placing the CwPaintDecal2D components in child GameObject, and dragging and dropping them into the CwHitCollisions2D component's Advanced/Root setting. You can also disable the OnlyUseFirstContact setting to make it continuously apply paint as it collides.

Undo Redo

This shows you how the CwPaintableSpriteTexture component's UndoRedo setting can be enabled. You can then make UI images with the CwButtonUndoAll and CwButtonRedoAll component to turn them into buttons.

Clear

This shows you how paint can be reset by adding the CwButtonClearAll component to your UI images to turn them into buttons.

Save Load

This shows you how paint can be automatically saved and loaded by setting the CwPaintableSpriteTexture component's SaveLoad setting to Automatic, and setting a name for this sprite's save data. The sprite's paint will then be automatically saved/loaded when you start/stop the scene or run the app.

Decal Sticker

This shows you how to paint decals like stickers. This is done by changing the CwHitScreen2D component's Frequency setting can be set to Once On Release, and enabling the CwPointerMouse component's Preview setting.

Paint Texture

This shows you how the CwPaintDecal2D component's Advanced / TileTexture setting can be used to paint a seamless texture with the decal shape. The TileTransform setting can also be used to control the tiling and rotation of the tiled texture.

Dotted Lines

This shows you how the CwHitScreen2D component's Frequency setting can be set to PixelInterval or ScaledPixelInterval (DPI independent). This then allows you to set the Interval setting, which allows you to draw a dotted line as your mouse/finger drags across the screen.

Straight Lines

This shows you how instead of the CwHitScreen2D component, the CwHitScreenLine2D can be used. This allows you to draw lines between the start and end positions of a finger swipe. This component's Frequency setting can be used to control how many points are in the line relative to its length. This component's Advanced/ConnectHits and Advanced/ClipConnected settings can be enabled to make a solid line.

Eraser

This shows you how a sprite's texture can be erased/restored to its original state. To erase it, the paint tool's CwPaintDecal2D component's BlendMode setting can be set to ReplaceOriginal. This will paint the sprite back to its original state.

Erase Alpha & Restore Alpha

This shows you how a sprite's alpha can be erased and restored. To erase it, the paint tool's CwPaintDecal2D component's BlendMode setting can be set to Subtractive, with a Channels setting of 0,0,0,1, so it only subtracts the alpha/opacity. To restore it, the ReplaceOriginal blending mode can be used, with the same 0,0,0,1 Channels setting.

Reveal From Invisible

This shows you how to initialize a sprite as transparent, and then paint the alpha back to restore it. This is done by changing the paintable sprite texture component's Color setting to have 0 alpha/opacity. This means when activated, the sprite will become invisible. The alpha can then be restored with your painting tool's CwPaintDecal2D component's BlendMode setting set to ReplaceOriginal, and the Channels set to 0,0,0,1, so it only replaces the alpha.

Stencil Mask

This shows you how the CwMaskSprite component can be added to a sprite, causing it to block all paint that hits the solid parts. Keep in mind only the closest mask will be used when painting. Keep in mind the CwDragToMove component used in this scene requires there to be a collider on your sprite.

Mirror Symmetry

This shows you how the CwCloneMirror component can be added to the scene, and it will cause all paint to be mirrored across the axis you can see in the Scene view. Keep in mind you must rotate it Y = 90 degrees initially. You can then adjust the X rotation.

Mirror Symmetry Flip

This shows you how the CwCloneMirror component's Flip setting can be enabled. This is useful if you want to mirror text, and other sprites that require the original orientation to be retained.

Color Picker

This shows you how the CwTapToReadColor component can be added to a sprite, allowing you to read its colors, and sending that color out via event. Keep in mind your sprite must have a 2D collider, and your camera must have the Physics2DRaycaster component. Keep in mind your sprite must have its Advanced/ReadWrite setting enabled, must have its Compression setting disabled, and it must not be in an atlas.

Particle Painting

This shows you how a particle system can be made to paint sprites on collision. First, on the particle system you must set Collision = true, then you must set Mode = 2D, and then you must set SendCollisionMessages = true. You can then add the CwHitParticles2D and CwPaintDecal2D components alongside, which will then paint the scene each time a particle hits something.

Paint Under

This shows you how the CwHitNearby and CwPaintDecal2D components can be combined to emit paint from a GameObject. If the CwHitNearby component's PaintIn is set to Update, then it will continuously paint. You can see a preview of what the paint shape looks like in the Scene tab.

Paint Under Tap

This shows you how to make a sprite paint a decal when you tap on it. This is done using the CwHitNearby and CwPaintDecal2D components, and setting the CwHitNearby component's PaintIn setting to ManuallyOnly. You can then add the CwTapEvent, and connect its event to the CwHitNearby component's ManuallyHitNow event, which will trigger it to paint each time you tap. Keep in mind the CwTapEvent and CwDragToMove components used in this scene require there to be a collider on your sprite.

Blur painting

This shows you how the CwPaintDecal2D component's BlendMode can be set to Blur. This causes all painted pixel to blur with their surrounding pixels. The Kernel setting can be used to control the range of the blur.

Flow Painting

This shows you how the CwPaintDecal2D component's BlendMode can be set to Flow. This allows you to set a tangent-space normal map texture in the Texture setting, which causes the painted pixels to flow in specific directions to create interesting effects.

Clone Stamp

This shows you how to create a clone stamp effect. This is done by adding an orthographic camera to your scene, and setting its TargetTexture to a RenderTexture asset in your project. The camera will then update the texture with what it sees in the scene, and you can drag and drop this texture into your CwPaintDecal2D component's Texture, which allows you to then paint it on your sprites.

Gradually Fade

This shows you how the CwGraduallyFade component can be used to slowly fade a sprite back to its original state, erasing all paint.

Gradually Appear

This shows you how to make paint gradually appear. This is done by creating two CwPaintableSpriteTexture components - one for the future, and one for the present. The future one is what is painted, and its Advanced/IsDummy setting must be enabled, so it doesn't get applied to your sprite. Your current texture must have its Group set to DUMMY, so that it doesn't get painted. The CwGraduallyFade component is then used to fade the current texture to the future one using BlendMode = Replace, and the future texture set in the BlendPaintableTexture setting.







Assets

Here's a list of all my other assets, please check them out!

You can also view this list on my Asset Store page.

Lean Touch

Lean Touch

Rapidly develop your game with consistent input across desktop & mobile using Lean Touch. This lightweight asset comes with many modular components, allowing you to customize them to your exact project needs!


Lean Touch+

Lean Touch+

Lean Touch+ is an extension to the popular Lean Touch asset, adding many more example scenes.


Lean Localization

Lean Localization

Lean Localization is a localization library that's designed to be as simple to use as possible for both designers, and programmers.


Lean Pool

Lean Pool

Quickly optimize the performance of your games using Lean Pool. Within minutes you can use this lightweight asset to preload, recycle, and limit the spawning of your prefabs.


Lean Transition

Lean Transition

Quickly polish your games using Lean Transition. This asset allows you to easily tween or animate almost anything in your game, making it transition smoothly.


Lean GUI

Lean GUI

Lean GUI is a colllection of components that extend Unity's GUI system, allowing you to rapidly enhance the user experience (UX) of your game's UI.


Lean GUI Shapes

Lean GUI Shapes

Lean GUI Shapes allows you to quickly add lines, rounded boxes, polygons, and much more to your GUI!


Lean Texture

Lean Texture

Lean Texture allows you quickly modify textures in your project with a range of filters, pack them together into channels, and much more!


Lean Texture+

Lean Texture+

Lean Texture+ is an extension to Lean Texture, adding many new types of texture modification tools!


CW Spaceships - Build & Destroy

CW Spaceships

Build your dream spaceship, and then have fun destroying it!


CW Orbit - Modular Backgrounds

CW Orbit

Take your space game to the next level with this collection of 8K background planets. Just drag and drop them in, and enjoy orbiting around them.


CW Nebula - Modular Backgrounds

CW Nebula

Add stunning nebula backgrounds to your 3D space games with ease.


CW Gas Giant - Modular Backgrounds

CW Gas Giant

Add stunning gas giant backgrounds to your 3D space games with ease.


CW Galaxy - Modular Backgrounds

CW Galaxy

Add stunning galaxy backgrounds to your 3D space games with ease.


CW Silhouette - Modular Backgrounds

CW Silhouette

Add stunning silhouette backgrounds to your 3D space games with ease.


CW Cosmos - Modular Backgrounds

CW Cosmos

Add stunning nebula and galaxy backgrounds to your 3D space games with ease.


Paint in 3D

Paint in 3D

Paint all your objects using Paint in 3D - both in game, and in editor. All features are optimized with GPU accelerated texture painting, so you can enjoy consistent performance, even if you paint your objects one million times!


FLOW

FLOW

FLOW allows you to add large scale interactive fluids to your scene - all highly optimized using GPU acceleration.


Destructible 2D

Destructible 2D

Unlock the full potential of your 2D games using Destructible 2D, this asset allows you to quickly convert all your boring solid sprites into fully destructible ones!


Space Graphics Toolkit

Space Graphics Toolkit

Quickly make the space scene of your dreams using Space Graphics Toolkit. This huge collection of space effects can be customized and combined in any way you like, allowing you to quickly make realistic or fantasy worlds. Each feature has been heavily optimized to run on almost any device and platform.


Space Graphics Planets

Space Graphics Planets

Enhance your space scenes using this large pack of high detail volumetric planets. These planets are finished using the powerful planet features from Space Graphics Toolkit (not required).


Volumetric Audio

Volumetric Audio

Unity sounds only emanate from a single point source. This is great for explosions and footsteps, but quite often you need something more advanced. Volumetric Audio is an easy to use package that allows you to define boxes, spheres, capsules, paths, or meshes that sounds can emanate from.






Versions

1.1.1

Added CwPaintDecal2D.MultiplyOpacity method.
Added CwPaintDecal2D.IncrementRadius method.
Added CwPaintDecal2D.IncrementScale method.



1.1.0

Updated CW/Common code to latest version.



1.0.2

Added Advanced/Intercept setting to CwHitScreen2D.
Added Advanced/AutoStoreState setting to CwPaintableMeshTexture component.
Undo/Redo states are now only created if you actually paint something (when a hit command is sent to a texture).



1.0.1

Fixed CwHitScreen2D component error when expanding Advanced menu.



1.0.0

Initial release.







Components

CwActionOnEnable

This component invokes the Action event when this component is enabled.


UnityEvent
Action

The event that will be invoked.




CwBlendMode

This defines the blending mode used by a painting operation.


int
Index

This is the index of the currently selected blending mode.



Color
Color

When using the ReplaceCustom blending mode, this allows you to specify the replacement color.



Texture
Texture

When using the ReplaceCustom blending mode, this allows you to specify the replacement texture.



float
Kernel

When using the Blur or Flow blending modes, this allows you to set the maximum pixel distance of samples.



Vector4
Channels

This allows you to control which channels will be modified by this blending mode.

1,1,1,1 = All channels will be modified.

1,0,0,0 = Only red will be modified.




CwButtonClearAll

This component allows you to perform the Clear action. This can be done by attaching it to a clickable object, or manually from the ClearAll method.


bool
ClearStates

When clearing a texture, should its undo states be cleared too?




CwButtonRedoAll

This component allows you to perform the Redo All action. This can be done by attaching it to a clickable object, or manually from the RedoAll method.


void
RedoAll

If you want to manually trigger RedoAll, then call this function.




CwButtonUndoAll

This component allows you to perform the Undo All action. This can be done by attaching it to a clickable object, or manually from the RedoAll method.


void
UndoAll

If you want to manually trigger UndoAll, then call this function.




CwChangeCounter CwPaintableTextureMonitorMask

This component will check all pixels in the specified paintable texture, compare them to the reference state defined in this component, and tell you how many of them differ by more than the threshold value.


static LinkedList<CwChangeCounter>
Instances

This stores all active and enabled instances.



float
Threshold

The RGBA values must be within this range of a color for it to be counted.



Texture
Texture

The texture we want to compare change to.

None/null = white.

NOTE  All pixels in this texture will be tinted by the current Color.


Color
Color

The color we want to compare change to.

NOTE  All pixels in the Texture will be tinted by this.


int
Count

The previously counted amount of pixels with a RGBA value difference above the threshold.



float
Ratio

The Count / Total value.



static long
GetTotal
ICollection<CwChangeCounter> counters = null

The Total of the specified counters.



static long
GetCount
ICollection<CwChangeCounter> counters = null

The Count of the specified counters.



static float
GetRatio
ICollection<CwChangeCounter> counters = null

The Ratio of the specified counters.




CwChangeCounterEvent

This component allows you to perform an event when the specified CwChangeCounter instances are painted a specific amount.


List<CwChangeCounter>
Counters

This allows you to specify the counters that will be used.

None = All active and enabled counters in the scene.



Vector2
Range

This paint ratio must be inside this range to be considered inside.



bool
Inside

This tells you if the paint ratio is within the current Range.



UnityEvent
OnInside

This event will be called on the first frame Inside becomes true.



UnityEvent
OnOutside

This event will be called on the first frame Inside becomes false.



float
Ratio

This tells you the current paint ratio of the specified Color, where 0 is no paint, and 1 is fully painted.




CwChangeCounterFill

This component fills the attached UI Image based on the total amount of pixels that have been painted in the specified CwChangeCounterFill components.


List<CwChangeCounter>
Counters

This allows you to specify the counters that will be used.

Zero = All active and enabled counters in the scene.



bool
Inverse

Inverse the fill?




CwChangeCounterText

This component will output the total pixels for the specified team to a UI Text component.


List<CwChangeCounter>
Counters

This allows you to specify the counters that will be used.

Zero = All active and enabled counters in the scene.



bool
Inverse

Inverse the Count and Percent values?



int
DecimalPlaces

This allows you to set the amount of decimal places when using the percentage output.



string
Format

This allows you to set the format of the team text. You can use the following tokens:

{TOTAL} = Total amount of pixels that can be painted.

{COUNT} = Total amount of pixel that have been painted.

{PERCENT} = Percentage of pixels that have been painted.



StringEvent
OnString

The color count will be output via this event.




CwChannelCounter CwPaintableTextureMonitorMask

This component will total up all RGBA channels in the specified CwPaintableTexture that exceed the threshold value.


static LinkedList<CwChannelCounter>
Instances

This stores all active and enabled instances.



float
Threshold

The RGBA value must be higher than this for it to be counted.



int
CountR

The previously counted amount of pixels with a red channel value above the threshold.



int
CountG

The previously counted amount of pixels with a green channel value above the threshold.



int
CountB

The previously counted amount of pixels with a blue channel value above the threshold.



int
CountA

The previously counted amount of pixels with a alpha channel value above the threshold.



float
RatioR

The CountR/Total value, allowing you to easily see how much % of the red channel is above the threshold.



float
RatioG

The CountG/Total value, allowing you to easily see how much % of the green channel is above the threshold.



float
RatioB

The CountB/Total value, allowing you to easily see how much % of the blue channel is above the threshold.



float
RatioA

The CountA/Total value, allowing you to easily see how much % of the alpha channel is above the threshold.



Vector4
RatioRGBA

The RatioR/G/B/A values packed into a Vector4.



static long
GetTotal
ICollection<CwChannelCounter> counters = null

The Total of the specified counters.



static long
GetCountR
ICollection<CwChannelCounter> counters = null

The CountR of the specified counters.



static long
GetCountG
ICollection<CwChannelCounter> counters = null

The CountG of the specified counters.



static long
GetCountB
ICollection<CwChannelCounter> counters = null

The CountB of the specified counters.



static long
GetCountA
ICollection<CwChannelCounter> counters = null

The CountA of the specified counters.



static float
GetRatioR
ICollection<CwChannelCounter> counters = null

The CountR / Total of the specified counters.



static float
GetRatioG
ICollection<CwChannelCounter> counters = null

The CountG / Total of the specified counters.



static float
GetRatioB
ICollection<CwChannelCounter> counters = null

The CountB / Total of the specified counters.



static float
GetRatioA
ICollection<CwChannelCounter> counters = null

The CountA / Total of the specified counters.



static Vector4
GetRatioRGBA
ICollection<CwChannelCounter> counters = null

The GetCountR/G/B/A / GetTotal of the specified counters stored in a Vector4.




CwChannelCounterEvent

This component allows you to perform an event when the specified CwChannelCounter instances are painted a specific amount.


List<CwChannelCounter>
Counters

This allows you to specify the counters that will be used.

None = All active and enabled counters in the scene.



ChannelType
Channel

This allows you to choose which channel will be output to the UI Text.



Vector2
Range

This paint ratio must be inside this range to be considered inside.



bool
Inside

This tells you if the paint ratio is within the current Range.



UnityEvent
OnInside

This event will be called on the first frame Inside becomes true.



UnityEvent
OnOutside

This event will be called on the first frame Inside becomes false.



float
Ratio

This tells you the current paint ratio of the specified Channel, where 0 is no paint, and 1 is fully painted.




CwChannelCounterFill

This component fills the attached UI Image based on the total amount of opaque pixels that have been painted in all active and enabled CwChannelCounter components in the scene.


List<CwChannelCounter>
Counters

This allows you to specify the counters that will be used.

Zero = All active and enabled counters in the scene.



ChannelType
Channel

This allows you to choose which channel will be output to the UI Image.



bool
Inverse

Inverse the fill?




CwChannelCounterText

This component allows you to output the totals of all the specified pixel counters to a UI Text component.


List<CwChannelCounter>
Counters

This allows you to specify the counters that will be used.

Zero = All active and enabled counters in the scene.



ChannelType
Channel

This allows you to choose which channel will be output to the UI Text.



bool
Inverse

Inverse the Count and Percent values?



int
DecimalPlaces

This allows you to set the amount of decimal places when using the percentage output.



string
Format

This allows you to set the format of the team text. You can use the following tokens:

{TOTAL} = Total amount of pixels that can be painted.

{COUNT} = Total amount of pixel that have been painted.

{PERCENT} = Percentage of pixels that have been painted.



StringEvent
OnString

The color count will be output via this event.




CwClone

This is the base class for all components that repeat paint commands (e.g. mirroring).


static LinkedList<CwClone>
Instances

This stores all active and enabled instances in the open scenes.




CwCloneMirror CwClone

This component grabs paint hits and connected hits, mirrors the data, then re-broadcasts it.


bool
Flip

When a decal is mirrored it will appear backwards, should it be flipped back around?




CwColor

This component allows you to define a color that can later be counted from the CwColorCounter component.

NOTE  You should put this component its own GameObject, so you can give it a unique name.

Color
Color

The color associated with this component and GameObject name.



static LinkedList<CwColor>
Instances

This stores all active and enabled instances in the open scenes.



int
Total

This tells you how many pixels this color could be painted on.



int
Solid

This tells you how many pixels this color has been painted on.



float
Ratio

This is Solid/Total, allowing you to quickly see the percentage of paintable pixels that have been painted by this color.




CwColorCounter CwPaintableTextureMonitorMask

This component will search the specified paintable texture for pixel colors matching an active and enabled CwColor.


static LinkedList<CwColorCounter>
Instances

This stores all active and enabled instances.



float
Threshold

The RGBA values must be within this range of a color for it to be counted.



List<Contribution>
Contributions

Each color contribution will be stored in this list.



static long
GetTotal
ICollection<CwColorCounter> counters = null

The Total of the specified counters.



static long
GetCount
CwColor color, ICollection<CwColorCounter> counters = null

The Count of the specified counters.



static float
GetRatio
CwColor color, ICollection<CwColorCounter> counters = null

The Ratio of the specified counters.



int
Count
CwColor color

This tells you how many pixels of the specified color are in the current PaintableTexture.




CwColorCounterEvent

This component allows you to perform an event when the specified CwColorCounter instances are painted a specific amount.


List<CwColorCounter>
Counters

This allows you to specify the counters that will be used.

None = All active and enabled counters in the scene.



CwColor
Color

This allows you to set which color will be handled by this component.



Vector2
Range

This paint ratio must be inside this range to be considered inside.



bool
Inside

This tells you if the paint ratio is within the current Range.



UnityEvent
OnInside

This event will be called on the first frame Inside becomes true.



UnityEvent
OnOutside

This event will be called on the first frame Inside becomes false.



float
Ratio

This tells you the current paint ratio of the specified Color, where 0 is no paint, and 1 is fully painted.




CwColorCounterFill

This component fills the attached UI Image based on the total amount of pixels that have been painted in the specified CwColorCounter components.


List<CwColorCounter>
Counters

This allows you to specify the counters that will be used.

Zero = All active and enabled counters in the scene.



CwColor
Color

This allows you to set which color will be handled by this component.



bool
Inverse

Inverse the fill?




CwColorCounterText

This component will output the total pixels for the specified color to the OnString event.


List<CwColorCounter>
Counters

This allows you to specify the counters that will be used.

Zero = All active and enabled counters in the scene.



CwColor
Color

This allows you to set which color will be handled by this component.



bool
Inverse

Inverse the Count and Percent values?



int
DecimalPlaces

This allows you to set the amount of decimal places when using the percentage output.



string
Format

This allows you to set the format of the team text. You can use the following tokens:

{TOTAL} = Total amount of pixels that can be painted.

{COUNT} = Total amount of pixel that have been painted.

{PERCENT} = Percentage of pixels that have been painted.



StringEvent
OnString

The color count will be output via this event.




CwCommand

This is the base class for all paint commands. These commands (e.g. paint decal) are added to the command list for each CwPaintableTexture, and are executed at the end of the frame to optimize state changes.


int
Index

This is the original array index, used to stable sort between two commands if they have the same priority.



bool
Preview

Is this preview painting, or real painting?



int
Priority

The draw order priority of this command for this frame.



CwHashedMaterial
Material

The hash of the Material used to apply this paint command.



int
Pass

The material pass that will be used.



CwHashedModel
Model

The hash of the Model used to apply this paint command.



int
Submesh

The mesh submesh that will be painted.



CwHashedTexture
LocalMaskTexture

The LocalMask that will be used when painting.



Vector4
LocalMaskChannel

The channel of the LocalMaskTexture that will be used.




CwCommandDecal2D CwCommand

This class manages the decal 2D painting command.


void
SetShape
Quaternion rotation, Vector3 size, float angle

This method allows you to set the shape and rotation of the texture.

NOTE  The rotation argument is in world space, where Quaternion.identity means the paint faces forward on the +Z axis, and up is +Y.



CwCommandFill CwCommand

This class manages the fill painting command.



CwCommandReplace CwCommand

This class manages the replace painting command.



CwCommandReplaceChannels CwCommand

This class manages the replace channels painting command.



CwCommon

This class contains some useful methods used by this asset.


static void
SaveBytes
string saveName, byte[] data, bool save = true

This method allows you to save a byte array to PlayerPrefs, and is used by the texture saving system.

If you want to save to files instead then just modify this.



static byte[]
LoadBytes
string saveName

This method allows you to load a byte array from PlayerPrefs, and is used by the texture loading system.

If you want to save to files instead then just modify this.



static bool
SaveExists
string saveName

This method tells if you if there exists save data at the specified save name.



static void
ClearSave
string saveName, bool save = true

This method allows you to clear save data at the specified save name.




CwCommon

This class contains some useful methods used by this asset.



CwCoordCopier

This tool allows you to copy UV1 data into UV0. This is useful if you let Unity automatically generate lightmap UV data for you and you want to use them to paint normally.


Mesh
Source

The original mesh whose UV seams you want to fix.



Coord
First

The coord that will be copied into the first UV channel of the output mesh.



Coord
Second

The coord that will be copied into the second UV channel of the output mesh.



Coord
Third

The coord that will be copied into the third UV channel of the output mesh.



Coord
Fourth

The coord that will be copied into the fourth UV channel of the output mesh.




CwDestroyAfterTime

This component automatically destroys this GameObject after some time.


float
Seconds

If this component has been active for this many seconds, the current GameObject will be destroyed.

-1 = DestroyNow must be manually called.




CwDestroyer

This component automatically destroys the specified GameObject when sent a hit point. Hit points will automatically be sent by any CwHit___ component on this GameObject, or its ancestors.


GameObject
Target

This GameObject will be destroyed.




CwDragToMove

This component turns the current sprite into one that can be dragged around using the mouse/touch.

NOTE  This GameObject must have a 2D or 3D collider. If 2D, your main camera must have the Physics2DCollider component attached. If 3D, your main camera must have the PhysicsCollider component attached.


CwGraduallyFade

This component allows you to fade the pixels of the specified CwPaintableTexture.


CwPaintableTexture
PaintableTexture

This allows you to choose which paintable texture will be modified by this component.



float
Threshold

Once this component has accumulated this amount of fade, it will be applied to the PaintableTexture. The lower this value, the smoother the fading will appear, but also the higher the performance cost.



float
Speed

The speed of the fading.

1 = 1 Second.

2 = 0.5 Seconds.



CwBlendMode
BlendMode

This component will paint using this blending mode.

NOTE  See CwBlendMode documentation for more information.


Texture
BlendTexture

The texture that will be faded toward.



CwPaintableTexture
BlendPaintableTexture

The paintable texture that will be faded toward.



Color
BlendColor

The color that will be faded toward.



Texture
MaskTexture

If you want the gradually fade effect to be masked by a texture, then specify it here.



CwPaintableTexture
MaskPaintableTexture

If you want the gradually fade effect to be masked by a paintable texture, then specify it here.



CwChannel
MaskChannel

This allows you to specify the channel of the mask.




CwGroup

This struct allows you to specify a group index with a group dropdown selector.



CwGroupData

This object allows you to define information about a paint group like its name, which can then be selected using the CwGroup setting on components like CwPaintableTexture and CwPaintDecal.


int
Index

This allows you to set the ID of this group (e.g. 100).

NOTE  This number should be unique, and not shared by any other CwGroupData.


static List<CwGroupData>
CachedInstances

This static property returns a list of all cached CwGroupData instances.

NOTE  This will be empty in-game.


string
GetName
bool prefixNumber

This method allows you to get the name of the current group, with an optional prefix of the Index (e.g. "100: Albedo").



static string
GetGroupName
int index, bool prefixNumber

This static method calls GetAlias on the CwGroupData with the specified Index setting, or null.



static CwGroupData
GetGroupData
int index

This static method returns the CwGroupData with the specified Index setting, or null.



static void
UpdateCachedInstances

This static method forces the cached instance list to update.

NOTE  This does nothing in-game.



CwHashedMaterial

This struct can be used to reference a Material by instance or hash for de/serialization.



CwHashedModel

This struct can be used to reference a Material by instance or hash for de/serialization.

NOTE  To support networking you must modify the CwSerialization.TryRegister(CwModel) method to register the model using a hash/id specific to your networking solution.


CwHashedTexture

This struct can be used to reference a Texture by instance or hash for de/serialization.

NOTE  For the de/serialization to work you must call the CwSerialization.TryRegister/TryUnregister methods on your textures.


CwHit

This stores information about a scene point on a mesh. This is usually generated from a RaycastHit, but it can also be filled manually.


Vector3
Position

The world position that was hit.



Vector3
Normal

The world normal that was hit.



Transform
Transform

The Transform that was hit.



int
TriangleIndex

The triangle index that was hit.



float
Distance

The world distance that was hit.



Collider
Collider

The Collider that was hit.




CwHitBetween2D

This component raycasts between two points, and fires hit events when the ray hits something.


PhaseType
PaintIn

Where in the game loop should this component hit?



float
Interval

The time in seconds between each raycast.

0 = Every frame.

-1 = Manual only.



Transform
PointA

The start point of the raycast.



Transform
PointB

The end point of the raycast.



float
Fraction

The end point of the raycast.



LayerMask
Layers

The layers you want the raycast to hit.



OrientationType
Orientation

How should the hit point be oriented?

WorldUp = It will be rotated to the normal, where the up vector is world up.

CameraUp = It will be rotated to the normal, where the up vector is world up.

ThisRotation = The current Transform.rotation will be used.

ThisLocalRotation = The current Transform.localRotation will be used.

CustomRotation = The specified CustomTransform.rotation will be used.

CustomLocalRotation = The specified CustomTransform.localRotation will be used.



Camera
Camera

Orient to a specific camera?

None = MainCamera.



Transform
CustomTransform

If you use Orientation = CustomRotation/CustomLocalRotation, this allows you to set the transform.



NormalType
Normal

Which normal should the hit point rotation be based on?



float
Offset

If you want the raycast hit point to be offset from the surface a bit, this allows you to set by how much in world space.



bool
Preview

Should the applied paint be applied as a preview?



int
Priority

This allows you to override the order this paint gets applied to the object during the current frame.



float
Pressure

This allows you to control the pressure of the painting. This could be controlled by a VR trigger or similar for more advanced effects.



Transform
Point

If you want to display something at the hit point (e.g. particles), you can specify the Transform here.



LineRenderer
Line

If you want to draw a line between the start point and the his point then you can set the line here.



CwPointConnector
Connector

This allows you to connect the hit points together to form lines.



void
ManuallyHitNow

This method will immediately submit a non-preview hit. This can be used to apply real paint to your objects.



void
ClearHitCache

This component sends hit events to a cached list of components that can receive them. If this list changes then you must manually call this method.



void
ResetConnections

If this GameObject has teleported and you have ConnectHits or HitSpacing enabled, then you can call this to prevent a line being drawn between the previous and current points.




CwHitCache

This class stores lists of IHit__ instances, allowing components like CwHit__ to easily invoke hit events.



CwHitCollisions2D

This component can be added to any Rigidbody2D, and it will fire hit events when it hits something.


LayerMask
Layers

This allows you to filter collisions to specific layers.



bool
OnlyUseFirstContact

If there are multiple contact points, skip them?



float
Delay

If this component is generating too many hits, then you can use this setting to ignore hits for the specified amount of seconds.

0 = Unlimited.



OrientationType
Orientation

How should the hit point be oriented?

WorldUp = It will be rotated to the normal, where the up vector is world up.

CameraUp = It will be rotated to the normal, where the up vector is world up.



Camera
Camera

Orient to a specific camera?

None = MainCamera.



bool
Preview

Should the applied paint be applied as a preview?



float
Threshold

If the collision impact speed is below this value, then the collision will be ignored.



PressureType
PressureMode

This allows you to set how the pressure value will be calculated.

Constant = The PressureConstant value will be directly used.

ImpactSpeed = The pressure will be 0 when the collision impact speed is PressureMin, and 1 when the impact speed is or exceeds PressureMax.



float
PressureMin

The impact strength required for a hit to occur with a pressure of 0.



float
PressureMax

The impact strength required for a hit to occur with a pressure of 1.



float
PressureConstant

The pressure value used when PressureMode is set to Constant.



float
PressureMultiplier

The calculated pressure value will be multiplied by this.



float
Offset

If you want the raycast hit point to be offset from the surface a bit, this allows you to set by how much in world space.



int
Priority

This allows you to override the order this paint gets applied to the object during the current frame.



GameObject
Root

Hit events are normally sent to all components attached to the current GameObject, but this setting allows you to override that. This is useful if you want to use multiple CwHitCollisions2D components with different settings and results.



void
ClearHitCache

This component sends hit events to a cached list of components that can receive them. If this list changes then you must manually call this method.




CwHitNearby

This component continuously fires hit events using the current Transform position.


PhaseType
PaintIn

Where in the game loop should this component hit?



float
Interval

The time in seconds between each hit.

0 = Every frame.



bool
Preview

Should the applied paint be applied as a preview?



int
Priority

This allows you to override the order this paint gets applied to the object during the current frame.



float
Pressure

This allows you to control the pressure of the painting. This could be controlled by a VR trigger or similar for more advanced effects.



CwPointConnector
Connector

This allows you to connect the hit points together to form lines.



void
ManuallyHitNow

This method will immediately submit a non-preview hit. This can be used to apply real paint to your objects.



void
ClearHitCache

This component sends hit events to a cached list of components that can receive them. If this list changes then you must manually call this method.



void
ResetConnections

If this GameObject has teleported and you have ConnectHits or HitSpacing enabled, then you can call this to prevent a line being drawn between the previous and current points.




CwHitParticles2D

This component can be added to any ParticleSystem with collisions enabled, and it will fire hits when the particles collide with something.


LayerMask
Layers

This allows you to filter collisions to specific layers.



RotateType
RotateTo

How should the hit data be rotated?



float
Offset

If you want the raycast hit point to be offset from the surface a bit, this allows you to set by how much in world space.



int
Skip

If you have too many particles, then painting can slow down. This setting allows you to reduce the amount of particles that actually cause hits.

0 = Every particle will hit.

5 = Skip 5 particles, then hit using the 6th.



bool
Preview

Should the particles paint preview paint?



int
Priority

This allows you to override the order this paint gets applied to the object during the current frame.



PressureType
PressureMode

This allows you to set how the pressure value will be calculated.

Constant = The PressureConstant value will be directly used.

Distance = A value will be calculated based on the distance between this emitter and the particle hit point.

Speed = A value will be calculated based on the hit speed of the particle.



float
PressureMin

This allows you to specify the distance/speed that gives 0.0 pressure.



float
PressureMax

This allows you to specify the distance/speed that gives 1.0 pressure.



float
PressureConstant

The pressure value used when PressureMode is set to Constant.



float
PressureMultiplier

The calculated pressure value will be multiplied by this.



GameObject
Root

Hit events are normally sent to all components attached to the current GameObject, but this setting allows you to override that. This is useful if you want to use multiple CwHitParticles2D components with different settings and results.



void
ClearHitCache

This component sends hit events to a cached list of components that can receive them. If this list changes then you must manually call this method.




CwHitPointers

This this is the base class for hit screen components that receive data from CwPointer___ components.


LayerMask
GuiLayers

Fingers that began touching the screen on top of these UI layers will be ignored.




CwHitScreen2D CwHitScreenBase2D

This component will perform a raycast under the mouse or finger as it moves across the screen. It will then send hit events to components like CwPaintDecal, allowing you to paint the scene.


FrequencyType
Frequency

This allows you to control how often the screen is painted.

PixelInterval = Once every Interval pixels.

ScaledPixelInterval = Like PixelInterval, but scaled to the screen DPI.

TimeInterval = Once every Interval seconds.

OnceOnRelease = When the finger/mouse goes down a preview will be shown, and when it goes up the paint will apply.

OnceOnPress = When the finger/mouse goes down the paint will apply.

OnceEveryFrame = Every frame the paint will apply.



float
Interval

This allows you to set the pixels/seconds between each hit point based on the current Frequency setting.



CwPointConnector
Connector

This allows you to connect the hit points together to form lines.



void
ClearHitCache

This component sends hit events to a cached list of components that can receive them. If this list changes then you must manually call this method.



void
ResetConnections

If this GameObject has teleported and you have ConnectHits or HitSpacing enabled, then you can call this to prevent a line being drawn between the previous and current points.




CwHitScreenBase2D CwHitPointers

This class contains common code for screen based mouse/finger hit components.


Camera
Camera

Orient to a specific camera?

None = MainCamera.



LayerMask
Layers

The layers you want the raycast to hit.



EmitType
Emit

This allows you to control the hit data this component sends out.

PointsIn3D = Point drawing in 3D.

PointsOnUV = Point drawing on UV (requires non-convex MeshCollider).

TrianglesIn3D = Triangle drawing in 3D (requires non-convex MeshCollider).



RotationType
RotateTo

This allows you to control how the paint is rotated.

CameraUp = The rotation will be aligned to the camera.

DrawAngle = The paint will be rotated to match the drawing angle.

ThisRotation = The current Transform.rotation will be used.

CustomRotation = The specified CustomTransform.rotation will be used.



Transform
CustomTransform

This allows you to specify the Transform when using RotateTo = CustomRotation/CustomLocalRotation.



bool
StoreStates

Should painting triggered from this component be eligible for being undone?



int
Priority

This allows you to override the order this paint gets applied to the object during the current frame.



InterceptType
Intercept

If the mouse/finger doesn't hit a collider, should a hit point be generated anyway?

InterceptZ = A hit point will be created on a plane that lies flat on the Z axis.




CwHitScreenFill2D CwHitScreen2D

This component works like CwHitScreen, but it will fill in the shape you draw.


float
FillSpacing

This allows you to set the pixel distance between each grid point.

NOTE  The lower you set this, the lower the performance will be.



CwHitScreenLine2D CwHitScreenBase2D

This component will perform a raycast under the mouse or finger as it moves across the screen. It will then send hit events to components like CwPaintDecal, allowing you to paint the scene.


FrequencyType
Frequency

This allows you to control how many hit points will be generated along the drawn line.

StartAndEnd = Once at the start, and once at the end.

PixelInterval = Once at the start, and then every Interval pixels.

ScaledPixelInterval = Once at the start, and then every Interval scaled pixels.

StretchedPixelInterval = Like ScaledPixelInterval, but the hits are stretched to reach the end.

StretchedScaledPixelInterval = Like ScaledPixelInterval, but the hits are stretched to reach the end.

Once = Once at the specified Position and PixelOffset along the line.



float
Interval

This allows you to set the pixels between each hit point based on the current Frequency setting.



float
Position

When using Frequency = Once, this allows you to set the 0..1 position along the line.



float
PixelOffset

When using Frequency = Once, this allows you to set the pixel offset along the line.



CwPointConnector
Connector

This allows you to connect the hit points together to form lines.



void
ClearHitCache

This component sends hit events to a cached list of components that can receive them. If this list changes then you must manually call this method.



void
ResetConnections

If this GameObject has teleported and you have ConnectHits or HitSpacing enabled, then you can call this to prevent a line being drawn between the previous and current points.




CwHitThrough2D

This component constantly draws lines between the two specified points.


PhaseType
PaintIn

Where in the game loop should this component hit?



float
Interval

The time in seconds between each hit.

0 = Every frame.

-1 = Manual only.



Transform
PointA

The start point of the raycast.



Transform
PointB

The end point of the raycast.



OrientationType
Orientation

How should the hit point be oriented?

WorldUp = It will be rotated to the normal, where the up vector is world up.

CameraUp = It will be rotated to the normal, where the up vector is world up.



Camera
Camera

Orient to a specific camera?

None = MainCamera.



float
Pressure

This allows you to control the pressure of the painting. This could be controlled by a VR trigger or similar for more advanced effects.



bool
Preview

Should the applied paint be applied as a preview?



int
Priority

This allows you to override the order this paint gets applied to the object during the current frame.



LineRenderer
Line

If you want to draw a line between the start point and the his point then you can set the line here.



CwLineConnector
Connector

This allows you to connect the hit points together to form lines.



void
ManuallyHitNow

This method will immediately submit a non-preview hit. This can be used to apply real paint to your objects.



void
ClearHitCache

This component sends hit events to a cached list of components that can receive them. If this list changes then you must manually call this method.



void
ResetConnections

If this GameObject has teleported and you have ConnectHits or HitSpacing enabled, then you can call this to prevent a line being drawn between the previous and current points.




CwLineConnector

This class allows you to easily create components that can have their paint lines connected together to form quads.


float
HitSpacing

The world space distance between each paint point.

0 = No spacing.



int
HitLimit

When using HitSpacing, this prevents scenarios where something goes wrong and you attempt to paint too many times per frame.



bool
ConnectHits

If you enable this then the hit lines generated by this component will be connected into quads, allowing you to paint continuously.



bool
ClipConnected

If you enable ConnectHits, then each connected quad will overlap with the next. When using semi-transparent painting, this causes the overlap to become double opacity and look obvious. If you enable this setting, then this overlapping area will be removed.



void
ClearHitCache

This component sends hit events to a cached list of components that can receive them. If this list changes then you must manually call this method.



void
ResetConnections

If this GameObject has teleported and you have ConnectHits or HitSpacing enabled, then you can call this to prevent a quad being drawn between the previous and current lines.




CwMask

This component allows you to block paint from being applied at the current position using the specified shape.


Texture
Texture

The mask will use this texture shape.



CwChannel
Channel

The mask will use pixels from this texture channel.



bool
Invert

By default, opaque/white parts of the mask are areas you can paint, and transparent/black parts are parts that are masked. Invert this?



Vector2
Stretch

If you want the sides of the mask to extend farther out, then this allows you to set the scale of the boundary.

1 = Default.

2 = Double size.



static LinkedList<CwMask>
Instances

This stores all active and enabled instances in the open scenes.




CwMaskSprite CwMask

This component turns the current SpriteRenderer component into a paint mask.


void
UpdateTexture

This method will update the sprite mask texture. You must manually call this if you modify the mask's Sprite.




CwModel

This component marks the current GameObject as being paintable, as long as this GameObject has a MeshFilter + MeshRenderer, or a SkinnedMeshRenderer.

NOTE  To actually paint, the CwPaintableTexture component must be on a different object.

CwHash
Hash

The hash code for this model used for de/serialization of this instance.



Vector3
BaseScale

If you want the paintable texture width/height to be multiplied by the scale of this GameObject, this allows you to set the scale where you want the multiplier to be 1.



static LinkedList<CwModel>
Instances

This stores all active and enabled instances in the open scenes.



static List<CwModel>
FindOverlap
Vector3 position, float radius, int layerMask

This will return a list of all paintables that overlap the specified bounds



void
ScaleSize
ref int width, ref int height

This will scale the specified width and height values based on the current BaseScale setting.




CwModifier

This is the base class for all paint modifiers. To make a paint modifier, simply inherit this class, and implement one of the virtual methods to modify its data.


bool
Preview

Should this modifier apply to preview paint as well?



bool
Unique

Should this modifier use a unique seed?




CwModifierList

This class maintains a list of CwModifier instances, and contains helper methods to apply them.

This is used instead of a normal list so the modifiers can be de/serialized with polymorphism.


int
Count

The amount of modifiers in the list.



List<CwModifier>
Instances

This stores all modifiers in this list.




CwModifyAngleRandom CwModifier

This class allows you to randomize the painting angle of the attached component (e.g. CwPaintDecal).


float
Min

This is the minimum random angle that will be picked.



float
Max

This is the maximum random angle that will be picked.



BlendType
Blend

The way the picked angle value will be blended with the current one.




CwModifyColorRandom CwModifier

This class allows you to randomize the painting color of the attached component (e.g. CwPaintDecal).


Gradient
Gradient

This is the gradient containing all the possible colors. A color will be randomly picked from this.



BlendType
Blend

The way the picked color value will be blended with the current one.




CwModifyHardnessPressure CwModifier

This class allows you to change the painting hardness based on the paint pressure.


float
Hardness

The paint component's Hardness value will be modified using this value based on the current Blend setting.



BlendType
Blend

This allows you to control how this new Hardness value will modify the old value in the paint component.

Replace = Transition between [old, new] based on pressure.

Multiply = Transition between [old, old*new] based on pressure.

Increment = Transition between [old, old+new] based on pressure.




CwModifyHardnessRandom CwModifier

This class allows you to randomize the painting hardness of the attached component (e.g. CwPaintDecal).


float
Min

This is the minimum random hardness that will be picked.



float
Max

This is the maximum random hardness that will be picked.



BlendType
Blend

The way the picked hardness value will be blended with the current one.




CwModifyOpacityPressure CwModifier

This class allows you to change the painting opacity based on the paint pressure.


float
Opacity

The paint component's Opacity value will be modified using this value based on the current Blend setting.



BlendType
Blend

This allows you to control how this new Opacity value will modify the old value in the paint component.

Replace = Transition between [old, new] based on pressure.

Multiply = Transition between [old, old*new] based on pressure.

Increment = Transition between [old, old+new] based on pressure.




CwModifyOpacityRandom CwModifier

This class allows you to randomize the painting opacity of the attached component (e.g. CwPaintDecal).


float
Min

This is the minimum random opacity that will be picked.



float
Max

This is the maximum random opacity that will be picked.



BlendType
Blend

The way the picked opacity value will be blended with the current one.




CwModifyPositionRandom CwModifier

This class allows you to randomize the painting position of the attached component (e.g. CwPaintDecal).


float
Radius

The position will be offset up to this radius away in world space.




CwModifyRadiusPressure CwModifier

This class allows you to change the painting radius based on the paint pressure.


float
Radius

The paint component's Radius value will be modified using this value based on the current Blend setting.



BlendType
Blend

This allows you to control how this new Radius value will modify the old value in the paint component.

Replace = Transition between [old, new] based on pressure.

Multiply = Transition between [old, old*new] based on pressure.

Increment = Transition between [old, old+new] based on pressure.




CwModifyRadiusRandom CwModifier

This class allows you to randomize the painting radius of the attached component (e.g. CwPaintDecal).


float
Min

This is the minimum random radius that will be picked.



float
Max

This is the maximum random radius that will be picked.



BlendType
Blend

The way the picked radius value will be blended with the current one.




CwModifyScaleRandom CwModifier

This class allows you to randomize the painting scale of the attached component (e.g. CwPaintDecal).


Vector3
Min

This is the minimum random scale that will be picked.



Vector3
Max

This is the maximum random scale that will be picked.



BlendType
Blend

The way the picked scale value will be blended with the current one.



bool
Uniform

If you disable this then each x, y, and z value will be scaled separately.




CwModifyTexturePressure CwModifier

This class allows you to change the painting texture of the attached component (e.g. CwPaintDecal) based on the paint pressure.


Texture
Texture

The painting texture will be changed to this.



float
PressureMin

The paint pressure must be at least this value.



float
PressureMax

The paint pressure must be at most this value.




CwModifyTextureRandom CwModifier

This class allows you to randomize the painting texture of the attached component (e.g. CwPaintDecal).


List<Texture>
Textures

A random texture will be picked from this list.




CwPaintableManager

This component automatically updates all CwModel and CwPaintableTexture instances at the end of the frame, batching all paint operations together.


static LinkedList<CwPaintableManager>
Instances

This stores all active and enabled instances in the open scenes.



int
ReadPixelsBudget

If the current GPU doesn't support async texture reading, this setting allows you to limit how many pixels are read per frame to reduce lag.



static void
MarkActivelyPainting

If a component is currently painting, it can call this method.




CwPaintableObjects

This window shows you all paintable objects in the scene, and it also allows you to make objects paintable from all paintable presets in your project.

You can open this window from the Window/CW/Paintable Objects menu.



CwPaintableSprite CwModel

This component can be used to make a SpriteRenderer paintable.

NOTE  This paintable must have a CwPaintableTextureSprite that targets Material 0's _MainTex slot.

ActivationType
Activation

This allows you to control when this component actually activates and becomes ready for painting. You probably don't need to change this.



bool
AutoSize

Automatically change the CwPaintableSprite component's Width and Height to match the sprite?



bool
AutoTexture

Automatically change the CwPaintableSprite component's Texture to match the sprite?



bool
AutoMask

Automatically change the CwPaintableSprite component's Advanced/LocalMask to match the sprite?



bool
GenerateMeshCollider

Automatically generate a mesh collider based on this sprite?



UnityEvent
OnActivating

This event will be invoked before this component is activated.



UnityEvent
OnActivated

This event will be invoked after this component is activated.



UnityEvent
OnDeactivating

This event will be invoked before this component is deactivated.



UnityEvent
OnDeactivated

This event will be invoked after this component is deactivated.



bool
IsActivated

This lets you know if this paintable has been activated.

Being activated means each associated CwMaterialCloner and CwPaintableTexture has been Activated.

NOTE  If you manually add CwMaterialCloner or CwPaintableTexture components after activation, then you must manually Activate().


void
RemoveComponents

This method will remove all CwPaintableMesh and CwPaintableTexture components from this GameObject.




CwPaintableSpriteTexture

This component allows you to make one texture on the attached Renderer paintable.

NOTE  If the texture or texture slot you want to paint is part of a shared material (e.g. prefab material), then I recommend you add the CwMaterialCloner component to make it unique.


CwPaintableState

This class stores information about a particular paintable texture state. Either a full texture copy, or a list of commands used to draw it.



CwPaintableTextureMonitor

This base class allows you to quickly create components that listen for changes to the specified CwPaintableTexture.


CwPaintableTexture
PaintableTexture

This is the paintable texture whose pixels we will count.



bool
WaitUntilNotPainting

Should this counter only read when you're not currently painting?

NOTE  You can control this by manually calling CwPaintableManager.MarkActivelyPainting() in Update.


float
Interval

This allows you to specify the minimum delay between when your texture is painted, and when the data is read.

0 = As fast as possible.

1 = Once a second.



bool
Async

If you disable this, then the texture will be updated immediately, which may cause slowdown.

NOTE  This isn't supported on all devices.


bool
ReadAtStart

If you enable this, then the reader will update as soon as it starts. If not, you must manually populate it with default data.



int
DownsampleSteps

Testing all the pixels of a texture can be slow, so you can pick how many times the texture is downsampled. One downsample = half width & height or 1/4 of the pixels.

NOTE  The pixel totals will be multiplied to account for this downsampling.


event System.Action
OnUpdated

This event is invoked each time this texture monitor updates its pixel counts.



bool
Registered

This will be true after Register is successfully called.



void
Register

This forces the specified CwPaintableTexture to be registered.



void
Unregister

This forces the specified CwPaintableTexture to be unregistered.




CwPaintableTextureMonitorMask CwPaintableTextureMonitor

This base class allows you to quickly create components that listen for changes to the specified CwPaintableTexture.


Mesh
MaskMesh

If you want this component to accurately count pixels relative to a mask mesh, then specify it here.

NOTE  For best results this should be the original mesh, NOT the seam-fixed version.


int
MaskSubmesh

If you have a MaskMesh set, then this allows you to choose which submesh of it will be used for the mask.



Texture
MaskTexture

If you want this component to accurately count pixels relative to a mask texture, then specify it here.



CwChannel
MaskChannel

This allows you to specify which channel of the MaskTexture will be used to define the mask.



int
Total

The previously counted total amount of pixels.




CwPaintAction

This component performs an action every time a paint hit is received. Hit points will automatically be sent by any CwHit___ component on this GameObject, or its ancestors.


UnityEvent
Action

The event that will be invoked.




CwPaintDebug

This component allows you to debug hit points into the Scene tab. Hit points will automatically be sent by any CwHit___ component on this GameObject, or its ancestors.


Color
Color

The color of the debug.



float
Duration

The duration of the debug.



float
Size

The size of the debug.




CwPaintDecal2D

This allows you to paint a decal at a hit point. Hit points will automatically be sent by any CwHit___ component on this GameObject, or its ancestors.


LayerMask
Layers

Only the CwModel/CwPaintableSprite GameObjects whose layers are within this mask will be eligible for painting.



CwModel
TargetModel

If this is set, then only the specified CwModel/CwPaintableSprite will be painted, regardless of the layer setting.



CwGroup
Group

Only the CwPaintableTexture components with a matching group will be painted by this component.



CwPaintableTexture
TargetTexture

If this is set, then only the specified CwPaintableTexture will be painted, regardless of the layer or group setting.



CwBlendMode
BlendMode

This allows you to choose how the paint from this component will combine with the existing pixels of the textures you paint.

NOTE  See the Blend Mode section of the documentation for more information.


Texture
Texture

The decal texture that will be painted.



Texture
Shape

This allows you to specify the shape of the decal. This is optional for most blending modes, because they usually derive their shape from the RGB or A values. However, if you're using the Replace blending mode, then you must manually specify the shape.



CwChannel
ShapeChannel

This allows you specify the texture channel used when sampling Shape.



Color
Color

The color of the paint.



float
Opacity

The opacity of the brush.



float
Angle

The angle of the texture in degrees.



Vector3
Scale

This allows you to control the mirroring and aspect ratio of the texture.

1, 1 = No scaling.

-1, 1 = Horizontal Flip.



float
Radius

The radius of the paint brush.



Texture
TileTexture

This allows you to apply a tiled detail texture to your texture. This tiling will be applied in world space using triplanar mapping.



Transform
TileTransform

This allows you to adjust the tiling position + rotation + scale using a Transform.



float
TileOpacity

This allows you to control the triplanar influence.

0 = No influence.

1 = Full influence.



float
TileTransition

This allows you to control how quickly the triplanar mapping transitions between the X/Y/Z planes.



bool
FindMask

If your scene contains a CwMask, should this paint component use it?



CwModifierList
Modifiers

This stores a list of all modifiers used to change the way this component applies paint (e.g. CwModifyColorRandom).



void
FlipHorizontal

This method will invert the scale.x value.



void
FlipVertical

This method will invert the scale.y value.



void
IncrementAngle
float degrees

This method increments the angle by the specified amount of degrees, and wraps it to the -180..180 range.



void
MultiplyOpacity
float multiplier

This method multiplies the Opacity by the specified value.



void
IncrementOpacity
float delta

This method increments the Opacity by the specified value.



void
MultiplyRadius
float multiplier

This method multiplies the Radius by the specified value.



void
IncrementRadius
float delta

This method increases the Radius by the specified value.



void
MultiplyScale
float multiplier

This method multiplies the Scale by the specified value.



void
IncrementScale
float multiplier

This method increases the Scale by the specified value.



void
HandleHitPoint
bool preview, int priority, float pressure, int seed, Vector3 position, Quaternion rotation

This method paints all pixels at the specified point using the shape of a texture.



void
HandleHitLine
bool preview, int priority, float pressure, int seed, Vector3 position, Vector3 endPosition, Quaternion rotation, bool clip

This method paints all pixels between the two specified points using the shape of a texture.



void
HandleHitTriangle
bool preview, int priority, float pressure, int seed, Vector3 positionA, Vector3 positionB, Vector3 positionC, Quaternion rotation

This method paints all pixels between three points using the shape of a texture.



void
HandleHitQuad
bool preview, int priority, float pressure, int seed, Vector3 position, Vector3 endPosition, Vector3 position2, Vector3 endPosition2, Quaternion rotation, bool clip

This method paints all pixels between two pairs of points using the shape of a texture.



void
HandleHitCoord
bool preview, int priority, float pressure, int seed, CwHit hit, Quaternion rotation

This method paints the scene using the current component settings at the specified CwHit.




CwPaintFill

This component implements the fill paint mode, which will modify all pixels in the specified texture in the same way.

This is useful if you want to gradually fade a texture to a specific color.


CwGroup
Group

Only the CwPaintableTexture components with a matching group will be painted by this component.



CwBlendMode
BlendMode

This allows you to choose how the paint from this component will combine with the existing pixels of the textures you paint.

NOTE  See the Blend Mode section of the documentation for more information.


Texture
Texture

The color of the paint.



Color
Color

The color of the paint.



float
Opacity

The opacity of the brush.



float
Minimum

The minimum RGBA value change. This is useful if you're doing very subtle color changes over time.



CwModifierList
Modifiers

This stores a list of all modifiers used to change the way this component applies paint (e.g. CwModifyColorRandom).



void
IncrementOpacity
float delta

This method increments Opacity by the specified value.




CwPaintReplace

This component implements the replace paint mode, which will replace all pixels in the specified texture.


CwGroup
Group

Only the CwPaintableTexture components with a matching group will be painted by this component.



Texture
Texture

The texture that will be painted.



Color
Color

The color of the paint.



CwModifierList
Modifiers

This stores a list of all modifiers used to change the way this component applies paint (e.g. CwModifyColorRandom).




CwPaintReplaceChannels

This component implements the replace channels paint mode, which will replace all pixels in the specified textures and channel weights.


CwGroup
Group

Only the CwPaintableTexture components with a matching group will be painted by this component.




CwPointConnector

This class allows you to easily create components that can have their paint points connected together to form lines.


float
HitSpacing

The world space distance between each paint point.

0 = No spacing.



int
HitLimit

When using HitSpacing, this prevents scenarios where something goes wrong and you attempt to paint too many times per frame.



bool
ConnectHits

If you enable this then the hit points generated by this component will be connected into lines, allowing you to paint continuously.



bool
ClipConnected

If you enable ConnectHits, then each connected line will overlap with the next. When using semi-transparent painting, this causes the overlap to become double opacity and look obvious. If you enable this setting, then this overlapping area will be removed.



void
ClearHitCache

This component sends hit events to a cached list of components that can receive them. If this list changes then you must manually call this method.



void
ResetConnections

If this GameObject has teleported and you have ConnectHits or HitSpacing enabled, then you can call this to prevent a line being drawn between the previous and current points.




CwPointer

This this is the base class for any component that sends pointer information to any CwHitScreen component.



CwPointerMouse CwPointer

This component sends pointer information to any CwHitScreen component, allowing you to paint with the mouse.


bool
Preview

If you enable this, then a paint preview will be shown under the mouse as long as the RequiredKey is not pressed.



List<KeyCode>
Keys

This component will paint while any of the specified mouse buttons or keyboard keys are held.




CwPointerPen CwPointer

This component sends pointer information to any CwHitScreen component, allowing you to paint with a pen.


bool
Preview

If you enable this, then a paint preview will be shown under the pen as long as the tip is not pressed.



float
Offset

If you want the paint to appear above the pen, then you can set this number to something positive.




CwPointerTouch CwPointer

This component sends pointer information to any CwHitScreen component, allowing you to paint with a touchscreen.


float
Offset

If you want the paint to appear above the finger, then you can set this number to something positive.




CwPreset

This component allows you to define a set of CwPaintableTexture and CwMaterial components that are configured for a specific set of Materials.


string
Title

This allows you to name this preset.

None/null = The GameObject name will be used.



List<string>
ShaderPaths

This preset is designed to work with the specified shaders.



static List<CwPreset>
CachedPresets

This gives you a list of all presets in the project.

NOTE  This is editor-only.


void
AddTo
Renderer root

This method applies the preset components to the specified paintable.

NOTE  This is editor-only.



CwReadColor

This component allows you to read the paint color at a hit point. A hit point can be found using a companion component like: CwHitScreen, CwHitBetween.

NOTE  This component only works when you hit a non-convex MeshCollider that has UV data.

CwGroup
Group

Only the CwPaintableTexture components with a matching group will be painted by this component.



bool
Preview

Should the color be read during preview painting too?



ReadType
Read

How should the texture be read?

Immediate = The reading method will block until the pixel is fetched from the GPU.

Async = The pixel value will be read after some time, giving you better performance.



Color
Color

The last read color value.



ColorEvent
OnColor

When a color is read, this event will be invoked.

Color = The color that was read.




CwReadColorEvent

This component allows you to perform an event when the attached CwReadColor component reads a specific color.


Color
Color

This color we want to detect.



float
Threshold

The RGBA values must be within this range of a color for it to be counted.



ColorEvent
OnColor

When the expected color is read, this event will be invoked.

Color = The expected color.




CwReader

This class allows you to read the contents of a RenderTexture immediately or async.



CwRenderDepth

This component renders scene depth to a RenderTexture. This scene depth can be set in a CwPaint___ component's Advanced/DepthMask setting, which allows you to paint on the first surface in the view of the specified camera.


Camera
SourceCamera

The camera whose depth information will be read.



Matrix4x4
SourceMatrix

The transformation matrix of the camera when the depth texture was generated.



int
ResizeAndDownscale

If this is 0, the RenderTexture size will match the viewport. If it's above 0, then the RenderTexture size will be set to the viewport size divided by this value.



float
Bias

The rendered depth must be at least this mant units different from the painted surface for the paint to be masked out.



bool
ReadInStart

Should the scene depth be rendered in Start?



bool
ReadInUpdate

Should the scene depth be rendered every frame in Update?



static LinkedList<CwRenderDepth>
Instances

This stores all active and enabled instances in the open scenes.



void
ReadNow

This method will update the TargetTexture with what the SourceCamera currently sees.




CwSerialization

This class handles the low level de/serialization of different paint objects to allow for things like networking.


static Dictionary<int, Material>
HashToMaterial

This stores an association between a Material hash code and the Material instance, so it can be de/serialized.



static Dictionary<Material, int>
MaterialToHash

This stores an association between a Material instance and the Material hash code, so it can be de/serialized.



static Dictionary<CwHash, CwModel>
HashToModel

This stores an association between a CwModel hash code and the CwModel instance, so it can be de/serialized.



static Dictionary<CwModel, CwHash>
ModelToHash

This stores an association between a CwModel instance and the CwModel hash code, so it can be de/serialized.



static Dictionary<CwHash, Texture>
HashToTexture

This stores an association between a Texture hash code and the Texture instance, so it can be de/serialized.



static Dictionary<Texture, CwHash>
TextureToHash

This stores an association between a Texture instance and the Texture hash code, so it can be de/serialized.



static Dictionary<CwHash, CwPaintableTexture>
HashToPaintableTexture

This stores an association between a CwModel hash code and the CwModel instance, so it can be de/serialized.



static Dictionary<CwPaintableTexture, CwHash>
PaintableTextureToHash

This stores an association between a CwModel instance and the CwModel hash code, so it can be de/serialized.




CwSlot

This struct stores a reference to a texture on a GameObject.


int
Index

The material index in the attached renderer.



string
Name

The name of the texture in the specified material.




CwSpawner

This allows you to spawn a prefab at a hit point. Hit points will automatically be sent by any CwHit___ component on this GameObject, or its ancestors.


List<GameObject>
Prefabs

A random prefab from this list will be spawned.



float
Radius

The spawned prefab will be randomly offset by a random point within this radius in world space.



Vector3
Velocity

If the prefab contains a Rigidbody, it will be given this velocity in local space.



float
OffsetNormal

The spawned prefab will be offset from the hit point based on the hit normal by this value in world space.



Vector3
OffsetWorld

The spawned prefab will be offset from the hit point based on this value in world space.



void
Spawn

Call this if you want to manually spawn the specified prefab.




CwStateManager

This component allows you to manage undo/redo states on all CwPaintableTextures in your scene.


static void
StoreAllStates

This method will call StoreState on all active and enabled CwPaintableTextures.

NOTE  This should be called before you perform manual changes to paintable textures.


static void
PotentiallyStoreAllStates

This method should be called if you're about to send paint hits that might apply paint to objects. If so, StoreState will be called on all active and enabled CwPaintableTextures



static void
ClearAllStates

This method will call ClearStates on all active and enabled CwPaintableTextures.



static void
UndoAll

This method will call Undo on all active and enabled CwPaintableTextures.



static void
RedoAll

This method will call Redo on all active and enabled CwPaintableTextures.




CwTapEvent

This component turns the current sprite into one that can be tapped, which will then invoke an event.

NOTE  This GameObject must have a 2D or 3D collider. If 2D, your main camera must have the Physics2DCollider component attached. If 3D, your main camera must have the PhysicsCollider component attached.

// float
MaxDelta

If the mouse/finger moves more than this pixel distance during the click/tap, it will be ignored. This is used to prevent conflicts with dragging.



UnityEvent
OnTap

When this sprite is tapped, this event will be invoked.




CwTapToReadColor

This component turns the current sprite into one that can be read when you tap on it.

NOTE  This GameObject must have a 2D or 3D collider. If 2D, your main camera must have the Physics2DCollider component attached. If 3D, your main camera must have the PhysicsCollider component attached.
NOTE  To be read, this sprite must have its Advanced / Read/Write setting enabled.
NOTE  To be read, this sprite must NOT be part of a texture atlas.

ColorEvent
OnColor

When a color is read, this event will be invoked.

Color = The color that was read.




CwTextureHash

This component allows you to manually associate a Texture with a hash code so it can be de/serialized.


Texture
Texture

The texture that will be hashed.



CwHash
Hash

The hash code for the texture.




IClone

This interface allows you to define classes that can clone paint points (e.g. mirror).



IHit

All IHit___ interfaces implement this interface so they can all be easily found with GetComponent.



IHitCoord IHit

This interface allows you to make components that can paint points defined by UV coordinates.

NOTE  The rotation argument is in world space, where Quaternion.identity means the paint faces forward on the +Z axis, and up is +Y.


IHitLine IHit

This interface allows you to make components that can paint lines defined by two points.



IHitPoint IHit

This interface allows you to make components that can paint 3D points with a specified orientation.



IHitQuad IHit

This interface allows you to make components that can paint quads defined by a pair of two points.



IHitTriangle IHit

This interface allows you to make components that can paint triangles defined by three points.



Index

Thank you for using Paint in 2D ❤️

How do I upgrade?

Getting Started

What Examples Are Included?



Assets

Lean Touch

Lean Touch+

Lean Localization

Lean Pool

Lean Transition

Lean GUI

Lean GUI Shapes

Lean Texture

Lean Texture+

CW Spaceships

CW Orbit

CW Nebula

CW Gas Giant

CW Galaxy

CW Silhouette

CW Cosmos

Paint in 3D

FLOW

Destructible 2D

Space Graphics Toolkit

Space Graphics Planets

Volumetric Audio



Versions

1.1.1

1.1.0

1.0.2

1.0.1

1.0.0



Components

CwActionOnEnable

CwBlendMode

CwButtonClearAll

CwButtonRedoAll

CwButtonUndoAll

CwChangeCounter

CwChangeCounterEvent

CwChangeCounterFill

CwChangeCounterText

CwChannelCounter

CwChannelCounterEvent

CwChannelCounterFill

CwChannelCounterText

CwClone

CwCloneMirror

CwColor

CwColorCounter

CwColorCounterEvent

CwColorCounterFill

CwColorCounterText

CwCommand

CwCommandDecal2D

CwCommandFill

CwCommandReplace

CwCommandReplaceChannels

CwCommon

CwCommon

CwCoordCopier

CwDestroyAfterTime

CwDestroyer

CwDragToMove

CwGraduallyFade

CwGroup

CwGroupData

CwHashedMaterial

CwHashedModel

CwHashedTexture

CwHit

CwHitBetween2D

CwHitCache

CwHitCollisions2D

CwHitNearby

CwHitParticles2D

CwHitPointers

CwHitScreen2D

CwHitScreenBase2D

CwHitScreenFill2D

CwHitScreenLine2D

CwHitThrough2D

CwLineConnector

CwMask

CwMaskSprite

CwModel

CwModifier

CwModifierList

CwModifyAngleRandom

CwModifyColorRandom

CwModifyHardnessPressure

CwModifyHardnessRandom

CwModifyOpacityPressure

CwModifyOpacityRandom

CwModifyPositionRandom

CwModifyRadiusPressure

CwModifyRadiusRandom

CwModifyScaleRandom

CwModifyTexturePressure

CwModifyTextureRandom

CwPaintableManager

CwPaintableObjects

CwPaintableSprite

CwPaintableSpriteTexture

CwPaintableState

CwPaintableTextureMonitor

CwPaintableTextureMonitorMask

CwPaintAction

CwPaintDebug

CwPaintDecal2D

CwPaintFill

CwPaintReplace

CwPaintReplaceChannels

CwPointConnector

CwPointer

CwPointerMouse

CwPointerPen

CwPointerTouch

CwPreset

CwReadColor

CwReadColorEvent

CwReader

CwRenderDepth

CwSerialization

CwSlot

CwSpawner

CwStateManager

CwTapEvent

CwTapToReadColor

CwTextureHash

IClone

IHit

IHitCoord

IHitLine

IHitPoint

IHitQuad

IHitTriangle