Skip to content

[UUM-133529] ProBuilder GameObjects not changing back to 3D shapes after Plane/Sprite transition#670

Open
lopezt-unity wants to merge 3 commits into
masterfrom
bugfix/uum-133529-update-shape-creation
Open

[UUM-133529] ProBuilder GameObjects not changing back to 3D shapes after Plane/Sprite transition#670
lopezt-unity wants to merge 3 commits into
masterfrom
bugfix/uum-133529-update-shape-creation

Conversation

@lopezt-unity
Copy link
Copy Markdown
Collaborator

#Purpose of this PR

##Problem

When a ProBuilder GameObject (e.g., Arch, Cube) had its shape changed to Plane or Sprite, it could not be changed back to a 3D shape. The GameObject would remain flat instead of becoming a proper 3D mesh.

##Reproduction steps:

  1. Create any ProBuilder 3D GameObject (e.g., GameObject > ProBuilder > Arch)
  2. Change Shape to Plane or Sprite in the ProBuilder Shape component
  3. Change Shape back to any 3D shape
  4. Bug: GameObject remains flat instead of becoming 3D

##Root Cause

The ProBuilderShape.SetShape() method had logic to flatten the Y dimension when transitioning TO Plane/Sprite shapes, but no corresponding logic to restore the Y dimension when transitioning FROM Plane/Sprite TO 3D shapes. This left m_Size.y at 0, causing the 3D shape to be built with zero height.

##Solution

Added detection for 2D→3D shape transitions in SetShape(). When transitioning from a flat shape (Plane/Sprite) to a 3D shape, the Y dimension is now restored to 1.0 if it was previously zero.

Links

Jira: https://jira.unity3d.com/browse/UUM-133529

Comments to Reviewers

[List known issues, planned work, provide any extra context for your code.]

Copy link
Copy Markdown
Contributor

@u-pr u-pr Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great

Thank you for this pull request! We've completed our review and identified one area that can be improved:

  • Floating-point Tolerance & Property Setter Bypass: The check on m_Size.y uses Mathf.Epsilon which is too small for general zero-tolerance comparisons, and it directly modifies the backing field instead of updating through the size property. This can cause state desynchronization and logic failure.

Please see the inline comment for detailed explanations and suggested code replacements.

🤖 Helpful? 👍/👎

Comment thread Runtime/Shapes/ProBuilderShape.cs Outdated
else if(wasFlat && !isFlat)
{
// Transitioning FROM a 2D shape TO a 3D shape - restore Y dimension
if(Mathf.Abs(m_Size.y) < Mathf.Epsilon)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Have you considered using a small absolute tolerance threshold (like 0.0001f) instead of Mathf.Epsilon, and updating the dimension through the public size property rather than modifying the backing field m_Size.y directly?

1. The Mathf.Epsilon Precision Trap

In Unity, Mathf.Epsilon is defined as float.Epsilon (1.4e-45), which is the absolute minimum denormalized positive float rather than the standard machine epsilon (1.19e-7). If the Y size undergoes any minor floating-point calculations, scaling, or serialized rounding/precision loss, it might be a tiny positive non-zero value. Because of this, the Mathf.Abs(m_Size.y) < Mathf.Epsilon check would evaluate to false, and the Y dimension would fail to restore. Using a small practical tolerance (like 0.0001f) is much more robust.

2. Bypassing the Property Setter

Modifying the backing field m_Size.y directly bypasses the size property setter. If the size setter handles internal validation, clamping, component dirtying, or undo/redo registration, direct field manipulation can lead to state desynchronization. The idiomatic C# way to update a field on a struct property is to retrieve it, modify the component, and write it back.

Suggested change (apply manually):

                if (Mathf.Abs(size.y) < 0.0001f)
                {
                    Vector3 currentSize = size;
                    currentSize.y = 1f;
                    size = currentSize;
                }

🤖 Helpful? 👍/👎 by guardian

@codecov-github-com
Copy link
Copy Markdown

codecov-github-com Bot commented May 26, 2026

Codecov Report

Attention: Patch coverage is 50.00000% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
Runtime/Shapes/ProBuilderShape.cs 50.00% 6 Missing ⚠️
@@            Coverage Diff             @@
##           master     #670      +/-   ##
==========================================
+ Coverage   36.05%   36.77%   +0.71%     
==========================================
  Files         277      278       +1     
  Lines       34909    35439     +530     
==========================================
+ Hits        12588    13033     +445     
- Misses      22321    22406      +85     
Flag Coverage Δ
probuilder_MacOS_6000.3 35.14% <44.44%> (+0.56%) ⬆️
probuilder_MacOS_6000.4 35.13% <44.44%> (+0.56%) ⬆️
probuilder_MacOS_6000.5 35.14% <44.44%> (+0.56%) ⬆️
probuilder_MacOS_6000.6 35.14% <44.44%> (?)
probuilder_Windows_6000.0 35.06% <44.44%> (-0.18%) ⬇️
probuilder_Windows_6000.3 35.06% <44.44%> (-0.19%) ⬇️
probuilder_Windows_6000.4 35.05% <44.44%> (-0.19%) ⬇️
probuilder_Windows_6000.5 35.06% <44.44%> (-0.19%) ⬇️
probuilder_Windows_6000.6 35.06% <44.44%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
Runtime/Shapes/ProBuilderShape.cs 74.00% <50.00%> (-2.67%) ⬇️

... and 84 files with indirect coverage changes

ℹ️ Need help interpreting these results?

Copy link
Copy Markdown
Contributor

@modrimkus-unity modrimkus-unity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, though AI might have a point on Mathf.Epsilon. I'd check what has more precedent in the codebase (are we checking more against Mathf.Epsilon or 0.0001f for example).

 Unity typically uses tolerances like 0.0001f for geometric comparisons (e.g., in collision detection, mesh validation)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants