Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

ProBuilder API - using ProBuilder from script

Discussion in 'World Building' started by jariwake, Jul 8, 2018.

  1. tomjycUnity

    tomjycUnity

    Joined:
    Feb 16, 2018
    Posts:
    2
    thanks a lot, I searched for this for 3 days, you saved my career
     
  2. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    560
    If you want CSG in Unity there are other options with full editor integration. SabreCSG and Realtime CSG are both free, excellent and easily found on Github/Asset Store
     
  3. tomjycUnity

    tomjycUnity

    Joined:
    Feb 16, 2018
    Posts:
    2
    as I understood that these tools cannot be used in Play Mode, I need to create doors and windows in the game
     
    Last edited: Aug 21, 2020
  4. SgtLame

    SgtLame

    Joined:
    Nov 26, 2015
    Posts:
    129
    Last edited: Nov 3, 2020
  5. SgtLame

    SgtLame

    Joined:
    Nov 26, 2015
    Posts:
    129
    Ok, I got my script to build a probuilder mesh from a list of points forming the base polygon of it.

    Code (CSharp):
    1.  
    2. IList<Vector3> pointsList = new List<Vector3>();
    3. pointsList.Add(new Vector3(-12887.3f, 0, 34048.5f));
    4. pointsList.Add(new Vector3(-12886.0f, 0, 34041.5f));
    5. pointsList.Add(new Vector3(-12878.4f, 0, 34042.5f));
    6. pointsList.Add(new Vector3(-12877.1f, 0, 34035.0f));
    7. pointsList.Add(new Vector3(-12870.5f, 0, 34036.0f));
    8. pointsList.Add(new Vector3(-12872.9f, 0, 34051.0f));
    9.              
    10. ProBuilderMesh pbMesh = ProBuilderMesh.Create();
    11. Material mat = (Material)Resources.Load<Material>("Materials/BuildingDefaultMaterial") as Material;
    12. pbMesh.SetMaterial(pbMesh.faces, mat);
    13. pbMesh.CreateShapeFromPolygon(pointsList, 2, false);
    14.  
    But I'm having two problems I'm really stuck on.
    First, the gameobject seems "incomplete" since the editor gizmos for moving or rotating it won't appear when the mesh is selected.
    Then, there are artefacts when moving around the mesh:

    Probuilder.gif

    If I manually move the object towards the scene center, by setting x to 13000 and z to -34000, the artefacts are gone. They are also gone if I set "cast shadows" to Off int the mesh renderer component.
    Any ideas? :)
     
  6. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    560
    Are you sure? I recall a runtime API - if not a UI around it.
     
  7. yinch

    yinch

    Joined:
    Jun 18, 2016
    Posts:
    6

    Hi,
    The shimmer you are seeing is to do with the finite precision of the Vector3 mathematics within Unity. So it isn't specifically a Probuilder problem. The short answer is that higher numbers have to use some of their bits for large values and therefore lose "decimal places" (technically binary places) from the accuracy.
    So when you move the camera around, the screen co-ordinates for any given vertex is returning slightly different values for each frame - producing inconsistencies in the Z-value and causing the shimmer you see.
     
  8. yinch

    yinch

    Joined:
    Jun 18, 2016
    Posts:
    6
    Hello Probuilder API friends,

    Does anyone know if the API has functions for any of these useful Editor actions?
    1. Edge Loop
    2. Edge Ring
    3. Face Loop
    4. Face Ring

    I have tried feeding one face to the top-cap of a cylinder to GetCoincidentVertices() and I do get a list of vertex indices back. Then I traverse all the faces of the Probuilder mesh and look for faces whose indices are in the coincident return list.
    But no face matches all three indices except the original one top-cap face.

    Am I using GetCoincidentVertices() wrong?

    Thank you!
     
    Last edited: Nov 26, 2020
  9. SgtLame

    SgtLame

    Joined:
    Nov 26, 2015
    Posts:
    129
    Thank you!
     
  10. Sidadi657

    Sidadi657

    Joined:
    May 15, 2020
    Posts:
    2
    Hello everyone does anyone know how to make a script to edit a bezier shape during runtime.I have been trying for days and have not found a solution.
     
    dannit likes this.
  11. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    560
    Specifically in Probuilder or just generally in Unity? If the latter then just search Github for "unity spline"
     
  12. stychu

    stychu

    Joined:
    May 9, 2016
    Posts:
    62
    Could someone explain to me why this is not working?? Do I have something wrong or I missed some step?? I'm unable to extrude the combined mesh..


    Code (CSharp):
    1. // some vector3 in the world
    2.       List<Vector3>        points = waypoints.Select(point => point.transform.position).ToList();
    3.       List<ProBuilderMesh> meshes = new List<ProBuilderMesh>();
    4.  
    5.       // generate plane using shapeGenerator and adjust position to given point
    6.       points.Select(CreateMesh).ToList().ForEach(meshes.Add);
    7.  
    8.       // combine first plane with the rest planes into single mesh
    9.       m_Mesh = CombineMeshes.Combine(meshes, meshes.First()).First();
    10.  
    11.       // THIS DOESNT WORK... THROWS KeyNotFoundException: The given key was not present in the dictionary.
    12.       m_Mesh.Extrude(m_Mesh.faces, ExtrudeMethod.VertexNormal, 1);
    13.       m_Mesh.ToMesh();
    14.       m_Mesh.Refresh();
    Code (CSharp):
    1. KeyNotFoundException: The given key was not present in the dictionary.
    2. System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <fb001e01371b4adca20013e0ac763896>:0)
    3. UnityEngine.ProBuilder.WingedEdge.GetWingedEdges (UnityEngine.ProBuilder.ProBuilderMesh mesh, System.Collections.Generic.IEnumerable`1[T] faces, System.Boolean oneWingPerFace) (at Library/PackageCache/com.unity.probuilder@4.2.3/Runtime/Core/WingedEdge.cs:353)
    4. UnityEngine.ProBuilder.MeshOperations.ExtrudeElements.ExtrudeAsGroups (UnityEngine.ProBuilder.ProBuilderMesh mesh, System.Collections.Generic.IEnumerable`1[T] faces, System.Boolean compensateAngleVertexDistance, System.Single distance) (at Library/PackageCache/com.unity.probuilder@4.2.3/Runtime/MeshOperations/ExtrudeElements.cs:385)
    5. UnityEngine.ProBuilder.MeshOperations.ExtrudeElements.Extrude (UnityEngine.ProBuilder.ProBuilderMesh mesh, System.Collections.Generic.IEnumerable`1[T] faces, UnityEngine.ProBuilder.ExtrudeMethod method, System.Single distance) (at Library/PackageCache/com.unity.probuilder@4.2.3/Runtime/MeshOperations/ExtrudeElements.cs:30)
     
  13. Andrew_Zim

    Andrew_Zim

    Joined:
    Aug 30, 2017
    Posts:
    20
    We have some issues, using this library, (also plugin from Asset Store) to cut the meshes. For example, there are some overflow issues with large meshes, or Unity just crashes. If we decreasing the epsilon value some time doesn't help.
    Is there some possibility that ProBuilder boolean operations (cutting) will be more stable than csg library? How far Probuilder from not "experimental" boolean operations?
    Thanks
     
  14. eslamabdo18

    eslamabdo18

    Joined:
    Apr 6, 2020
    Posts:
    1
    hey karrrlll sorry for bothering you but is there any way to create probulider sphere at runtime and change the subdivision value or not ?
     
  15. kaarrrllll

    kaarrrllll

    Unity Technologies

    Joined:
    Aug 24, 2017
    Posts:
    537
  16. batteryyrettab

    batteryyrettab

    Joined:
    Sep 20, 2013
    Posts:
    3
    Hi kaarrrllll,
    First of all, thanks for you posts and time, on this thread.

    Second, here's my question:
    I would like to be able to preview these in the Scene window (like pressing SHIFT and positioning with mouse when using 'New Shape'/'Create Shape' Probuilder Window).

    I can get it to show using [ExecuteInEditMode] but my implementation feels a bit hacky, and I can't seem to get to it only update and show on a keypress. I was wondering if there was an existing Method or process that might just preview the Probuilder mesh that I'm dynamically making?

    See images and code if it helps...

    https://imgur.com/a/AtAgoB8

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. using UnityEngine.ProBuilder;
    6. using UnityEngine.ProBuilder.MeshOperations;
    7. using Cinemachine;
    8.  
    9.  
    10.     /// <summary>
    11.     /// Description: This script demonstrates how to dynamically create Probuilder Meshes using Cinemachine Paths in Unity
    12.     /// Inspiration from: https://github.com/Unity-Technologies/ProBuilder-API-Examples/blob/master/Runtime/Misc/CreatePolyShape.cs
    13.     /// </summary>
    14.     [RequireComponent(typeof(CinemachineSmoothPath))]
    15.     [ExecuteInEditMode]
    16.     public class ProbuilderAndCinemachine : MonoBehaviour
    17.     {
    18.  
    19.         [SerializeField] float heightOfMesh = 1f;
    20.         [SerializeField] bool flipMeshNormals = false;
    21.  
    22.         [SerializeField] float width = 3f;
    23.         [SerializeField] int sampleDistance = 10;
    24.  
    25.         private float lastHeightOfMesh;
    26.         private bool lastFlipMeshNormals;
    27.         private float lastWidth;
    28.         private float lastPathLength;
    29.         private int lastSampleDistance;
    30.  
    31.         private ProBuilderMesh dynamicProbuilderMesh;
    32.         private CinemachineSmoothPath path;
    33.  
    34.         GameObject capsuleHolder;
    35.         GameObject probuilderPathMesh;
    36.         void Start()
    37.         {
    38.          
    39.  
    40.             path = this.GetComponent<CinemachineSmoothPath>();
    41.  
    42.             StoreLatestMeshSetting();
    43.             Rebuild();
    44.         }
    45.  
    46.         private void StoreLatestMeshSetting()
    47.         {
    48.             lastHeightOfMesh = heightOfMesh;
    49.             lastFlipMeshNormals = flipMeshNormals;
    50.             lastWidth = width;
    51.             lastPathLength = path.PathLength;
    52.             lastSampleDistance = sampleDistance;
    53.         }
    54.  
    55.         private void Update()
    56.         {
    57.             if (heightOfMesh != lastHeightOfMesh
    58.                 || flipMeshNormals != lastFlipMeshNormals
    59.                 || width != lastWidth
    60.                 || path.PathLength != lastPathLength
    61.                 || sampleDistance != lastSampleDistance)
    62.             {
    63.  
    64. //CANNOT GET WORKING
    65. //#if UNITY_EDITOR
    66. //
    67. //               if (Input.GetKeyDown(KeyCode.RightShift))
    68. //               {
    69. //                    Rebuild();
    70. //                }
    71. //#else
    72.                 Rebuild();
    73. //#endif
    74.                 StoreLatestMeshSetting();
    75.             }
    76.         }
    77.         void Rebuild()
    78.         {
    79.             if (capsuleHolder != null)
    80.             {
    81.                 DestroyImmediate(capsuleHolder);
    82.             }
    83.  
    84.             if (probuilderPathMesh !=null)
    85.             {
    86.                 DestroyImmediate(probuilderPathMesh);
    87.             }
    88.             // Create a new GameObject
    89.             probuilderPathMesh = new GameObject("Dynamically Created Path");
    90.  
    91.             // Add a ProBuilderMesh component (ProBuilder mesh data is stored here)
    92.             dynamicProbuilderMesh = probuilderPathMesh.gameObject.AddComponent<ProBuilderMesh>();
    93.  
    94.             capsuleHolder = new GameObject("Capsule Locators");
    95.             // Create a circle of points with randomized distance from origin.
    96.             CinemachineSmoothPath.Waypoint[] points = new CinemachineSmoothPath.Waypoint[path.m_Waypoints.Length];
    97.  
    98.             int vertexPoints = points.Length * 2;
    99.             List<Vector3> pointsOnPath = new List<Vector3>();
    100.             List<Vector3> reversePointsOnPath = new List<Vector3>();
    101.  
    102.             for (int i = 0; i < path.PathLength; i += sampleDistance)
    103.             {
    104.                 Vector3 locationAlongPath = path.EvaluatePositionAtUnit(i, CinemachinePathBase.PositionUnits.Distance);
    105.                 Quaternion rotationAlongPath = path.EvaluateOrientationAtUnit(i, CinemachinePathBase.PositionUnits.Distance);
    106.  
    107.                 GameObject leftObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    108.                 leftObject.transform.SetParent(capsuleHolder.transform);
    109.                 leftObject.transform.SetPositionAndRotation(locationAlongPath, rotationAlongPath);
    110.                 leftObject.transform.Translate(-transform.right * (width*0.5f));
    111.  
    112.                 pointsOnPath.Add(leftObject.transform.position);
    113.  
    114.                 GameObject rightObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    115.                 rightObject.transform.SetParent(capsuleHolder.transform);
    116.                 rightObject.transform.SetPositionAndRotation(locationAlongPath, rotationAlongPath);
    117.                 rightObject.transform.Translate(transform.right * (width * 0.5f));
    118.                 reversePointsOnPath.Add(rightObject.transform.position);
    119.                 //pointsOnPath[i+ (pointsOnPath.Length/2)-1] = capsule2.transform.position;
    120.  
    121.                   ProBuilderMesh arch = ShapeGenerator.GenerateArch(
    122.                  pivotType: PivotLocation.Center,
    123.                  angle: 180,
    124.                  radius: width+2,
    125.                  width: 2,
    126.                  depth: 3,
    127.                  radialCuts: 9,
    128.                 insideFaces: true,
    129.                 outsideFaces: true,
    130.                 frontFaces: true,
    131.                 backFaces: true,
    132.                 endCaps: false
    133.                 );
    134.  
    135.                 arch.transform.SetParent(capsuleHolder.transform);
    136.                 arch.transform.SetPositionAndRotation(locationAlongPath+(Vector3.up*width), rotationAlongPath);
    137.                 arch.GetComponent<MeshRenderer>().sharedMaterial = BuiltinMaterials.defaultMaterial;
    138.             }
    139.  
    140.             reversePointsOnPath.Reverse();
    141.  
    142.             pointsOnPath.AddRange(reversePointsOnPath);
    143.  
    144.             // CreateShapeFromPolygon is an extension method that sets the probuilder mesh data with vertices and faces
    145.             // generated from a polygon path.
    146.             dynamicProbuilderMesh.CreateShapeFromPolygon(pointsOnPath, heightOfMesh, flipMeshNormals);
    147.  
    148.  
    149.             // Assign the default material
    150.             dynamicProbuilderMesh.GetComponent<MeshRenderer>().sharedMaterial = BuiltinMaterials.defaultMaterial;
    151.  
    152.  
    153.         }
    154.  
    155.     }
    156.  
     

    Attached Files:

  17. GiannisA357

    GiannisA357

    Joined:
    Oct 3, 2022
    Posts:
    1
    Hey @kaarrrllll, I would to check if there is a way to use ProBuilder on runtime so user can build his "own scene".