Sculpting Pro Realtime
Full solution of sculpting at runtime. Apply this script to any empty object and properly assign all the required fields.
Public Methods
public void SPR_Setup(Camera mainCamera, Transform targetBrush, bool useMultithreading = true, bool customSculpting = false)
public void SPR_OnProcessSculpting()
public void SPR_OnStopSculpting()
public void SPR_OnCustomSculpting(SculptingPro_Model targetModel, Vector3 worldPoint, Vector3 worldNormal, bool raiseBrush, float radius, float intensity, bool recordToHistory = true)
public void SPR_OnCustomSculpting(SculptingPro_Model targetModel, Vector3 worldPoint, Vector3 worldNormal, Vector3 worldEuler, SculptingPro_HeightmapBrushSrc hbs, float yRotation, float radius, float intensity, bool recordToHistory = true)
public void SPR_OnCustomSculpting(SculptingPro_Thread.SculptingInputData sidData, bool recordToHistory = true)
public void SPR_OnEnableDisableSculpting(bool v)
public void SPR_ChangeRadius(float v)
public void SPR_ChangeRadius_Add(float addVal)
public void SPR_ChangeRadius_Sub(float subVal)
public void SPR_ChangeIntensity(float v)
public void SPR_ChangeIntensity_Add(float addVal)
public void SPR_ChangeIntensity_Sub(float subVal)
public void SPR_ChangeBrushState(int v)
public void SPR_ChangeSculptingType(int v)
public void SPR_ChangeNoiseDirection(int v)
public void SPR_ChangeSmoothingType(int v)
public void SPR_ChangeRadiusType(int v)
public void SPR_EnableDisableDistanceLimit(bool v)
public void SPR_ChangeDistanceLimit(float v)
public void SPR_ChangeSetHeightYValue(float v)
public void SPR_ChangeHeightmapBrush(SculptingPro_HeightmapBrushSrc hbs)
public void SPR_ChangeHeightmapBrushRotationOffset(float v)
public void SPR_OnUndo()
public void SPR_OnRestoreTarget()
public void SPR_SubdivideTarget()
public void SPR_SmoothTarget()
public void SPR_FlipTarget()
public void SPR_TryCloseSeamsTarget(float v)
public void SPR_TryAutoCloseSeamsTarget(bool v)
Examples
It's possible to create your own sculpting process at runtime from scratch using the available APi above. You don't have to use the built-in functionality in SculptingPro_Realtime.
Before that, make sure the 'Custom Sculpting' field in the SculptingPro_Realtime is enabled. See the example below - sculpting from a specific external object - the external object represents a 'sculpting raycast origin' from which the actual sculpting will happen. It's a simple sculpting process that controls raise/lower brush features in a certain radius.
using UnityEngine;
using SculptingPro;
public class CustomSculpting : MonoBehaviour
{
public SculptingPro_Realtime realtimeSculpting;
public Transform sampleGameObject;
public SculptingPro_Model targetModel;
[Space]
public float customRadius = 0.25f;
public float customIntensity = 0.8f;
public bool lowerBrush = false;
public float sampleGameObjectHeight = 0.1f;
private bool doingSculpting = false;
private void Start()
{
if (realtimeSculpting == null)
Debug.LogError("Realtime sculpting component has not been assigned!");
if (sampleGameObject == null)
Debug.LogError("Sample Object has not been assigned!");
if (targetModel == null)
Debug.LogError("Target Model has not been assigned!");
}
private void Update()
{
Vector3 p = new Vector3
{
x = Mathf.Sin(Time.time * 1.5f) * 0.8f,
z = Mathf.Cos(Time.time * 1.2f) * 0.8f,
y = sampleGameObjectHeight
};
sampleGameObject.position = p;
Ray r = new Ray(sampleGameObject.position, -sampleGameObject.up);
if (Physics.Raycast(r, out RaycastHit hit, 1.0f))
{
if (hit.collider)
{
realtimeSculpting.SPR_OnCustomSculpting(targetModel, hit.point, hit.normal, !lowerBrush, customRadius, customIntensity);
doingSculpting = true;
}
else ReleaseSculpting();
}
else ReleaseSculpting();
}
private void ReleaseSculpting()
{
if (!doingSculpting) return;
realtimeSculpting.SPR_OnStopSculpting();
doingSculpting = false;
}
}
If you would like to make a complete sculpting solution from scratch, you can use the advanced features of the SculptingPro APi. There's a class wrapper that holds
all the essential sculpting data called Sculpting Input Data. Certain fields are required to be assigned in your custom sculpting script. See the example below.
The script contains a complete sculpting process build from scratch using Sculpting Input Data. Please pay attention to the comments.
using UnityEngine;
using SculptingPro;
public class CustomSculpting : MonoBehaviour
{
public Camera mainCamera;
public SculptingPro_Thread.BrushState brushState = SculptingPro_Thread.BrushState.Raise;
public SculptingPro_Thread.SculptingInputData sculptingInputData;
public SculptingPro_Realtime realtimeSculpting;
public SculptingPro_Model targetModel;
private bool doingSculpting = false;
private bool grabSet = false;
private void Start()
{
if (mainCamera == null)
Debug.LogError("Main Camera has not been assigned!");
if (realtimeSculpting == null)
Debug.LogError("Realtime sculpting component has not been assigned!");
if (targetModel == null)
Debug.LogError("Target Model has not been assigned!");
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.U))
realtimeSculpting.SPR_OnUndo();
if (Input.GetKeyDown(KeyCode.R))
targetModel.RestoreOriginalMesh();
if (!Input.GetMouseButton(0))
{
ReleaseSculpting();
return;
}
bool grabFeature = brushState == SculptingPro_Thread.BrushState.Grab;
if (Input.GetMouseButtonDown(0) && grabFeature)
sculptingInputData.addParams.grabOrigin = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0);
if (grabFeature && grabSet)
{
sculptingInputData.addParams.grabDirection = mainCamera.transform.TransformDirection(
new Vector3(Input.mousePosition.x - sculptingInputData.addParams.grabOrigin.x, Input.mousePosition.y - sculptingInputData.addParams.grabOrigin.y, 0));
realtimeSculpting.SPR_OnCustomSculpting(sculptingInputData);
return;
}
Ray r = mainCamera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(r, out RaycastHit hit, Mathf.Infinity))
{
if (hit.collider)
{
var sid = sculptingInputData;
sid.worldPoint = hit.point;
sid.normalVector = hit.normal;
sid.modelInput = targetModel;
var t = targetModel.transform;
sid.modelTransformData = new SculptingPro_Thread.SculptingInputData.TransformModelData() { pos = t.position, rot = t.rotation, sca = t.lossyScale };
sid.addParams.brushState = brushState;
grabSet = true;
realtimeSculpting.SPR_OnCustomSculpting(sid);
doingSculpting = true;
}
else ReleaseSculpting();
}
else ReleaseSculpting();
}
private void ReleaseSculpting()
{
if (!doingSculpting) return;
realtimeSculpting.SPR_OnStopSculpting();
doingSculpting = false;
grabSet = false;
}
}