3D & 2D drawing
This module demonstrates how to synchronize 3D points to create 3D drawings made with line renderers.
3D Drawing
Principle
3D drawings are made of a group of line renderers, with a common handle that can be grabbed and moved once the drawing is finished.
The line renderers are in local based positioning, allowing them to move along with the handle.
A draw is made of several lines.
The data synchronization is based on the Data Sync Helpers addon.
Synchronized data
The Draw
class uses a ring buffer from the Data sync Helpers addon to store the drawing data. More precisely, it is a subclass of RingBufferLosslessSyncBehaviour
, a version of the helpers that synchronizes all the data that passed through the ring buffer so that late joiners receive the full drawing too.
The ring buffer synchonizes DrawPoint
entries. A DrawPoint
contains a vector3 and a float, and its meaning depends on the float value:
- a positive value describes a regular point. The `Vector3`` contains the local position of the point to add in the current line
- a
NEW_LINE_PRESSURE
(-1) value describes a line change. The Vector3 contains the color (r/g/b) of the line that is starting. A new line renderer is created for those points
Note that in this prototyping code, all data is stored on Fusion networked properties, or synched through reliable transfer API. In real-life scenarios, including in regards to persistence, Fusion should be used for real time synchronization, while a third-party storage service should be used for the long term data persistence.
Drawing
A 3D pen holds a Drawer
component, which spawns a drawing prefab holding a Draw
component. The Draw
component ensures that all the drawn points are synchronized over Fusion.
The drawing is triggered by using a button (trigger on VR controllers, space on desktop).
2D drawing
Principle
2D drawings are just invisible (to the user) 3D drawings, recorded by a dedicated camera, whose render result is projected on a board texture.
For performance purposes, this camera is only enabled when the pens near the board are used, or when the drawings created with them are moved.
Drawing
The drawing is triggered by the contact on the board surface, the depth of the contact determining the width of the drawing.
Note: the blocking tip module code shares similarities with this board detection. In future versions, they will probably be mutualised.
Color Selection
A ColorSelection
component can be added to a Drawer in order to synchronize the pen color modification.
The CheckColorModification()
method is called during FixedUpdateNetwork
to check if the local user used the joystick to change the pen color.
C#
public override void FixedUpdateNetwork()
{
if (Object == null || Object.HasStateAuthority == false) return;
CheckColorModification();
}
In this case, ChangePenColor()
updates the networked variable PenColor
. So, OnColorChanged()
is called on all players (thanks to a change detector).
C#
[Networked]
public Color PenColor { get; set; }
public override void Render()
{
base.Render();
foreach(var changedVar in changeDetector.DetectChanges(this))
{
if (changedVar == nameof(PenColor))
{
OnColorChanged();
}
}
}
void OnColorChanged()
{
UpdatePenMaterials();
}
Then, UpdatePenMaterials()
updates the pen's material & UpdateDrawColor()
end the previous drawing and start a new drawing with the new color.
Dependencies
- DataSyncHelpers addon
- Blocking Contact addon
- Interactive Menu addon
- Feedback addon
Demo
A demo scene can be found in Assets\Photon\FusionAddons\Drawing\Demo\Scenes\
folder.
The scene contains 2D pens with several boards :
a first simple square board with a
BlockingSurface
component to prevent pens from crossing the surface. Make sure that the box colliderIsTrigger
bool is set to true.
The child camera is set to perspective.
Also make sure that the board camera'sCullingMask
includes the layers used for 3D lines and the board background (if any).
In the same way, the camera of the player's rigs should NOT include the board background (it is visible thanks to the camera's render texture).a second simple board with a double width.
The child camera is set to orthographic.
The output texture of the camera must be set with a render texture with a double width resolution compare to the square board.a third board with a visual including a background texture. As explained above, the background texture's game object layer should NOT be included in the player rig camera (but must be included in the culling mask of the board's camera).
This board includes a 3D pen with a color selection feature.
When the pen is released, a pin appears, allowing players to move the lines.
The scene also contains two 3D pens.
When the pen is released, a handle appears, allowing players to move the 3D lines.
Download
This addon latest version is included into the Industries addon project
Supported topologies
- shared mode
Changelog
- Version 2.0.8: Update ColorSelcection to implement IColorProvider interface
- Version 2.0.7: User layer tools to automatically set the proper layer for 2D projection
- Version 2.0.6:
- Fix to ensure compatibility with VisionOSHelpers add-on.
- Fix issue with force use.
- Version 2.0.5: ColorSelection KeyboardBindings are added at runtime
- Version 2.0.4: Drawer: Use virtual variables & add verification+ Draw: fix lastDrawingTipPosition
- Version 2.0.3: Fix because of feedback namespace modification
- Version 2.0.2: Add LargeBoard with visual prefab
- Version 2.0.1: Add demo scene + prefabs update + add namespace
- Version 2.0.0: First release