Great to see you still working with Unity! I hope you make more VR content! I'm a big fan of your work.
bio998
Recent community posts
Hi Andrea,
In a previous version of clayxels, it was possible to control the size of the clayxel particles, using a parameter that was exposed in the inspector window called 'Clayxel Size'. The new version on the Asset Store is missing this parameter, and I can't find any public variables in 'Clayxel Container' that I could use to change this via script.
Any chance of exposing this parameter please? Or am I missing something? Any way to access/modify it?
Regards,
Ben
Sorry for double post.
The following script controls the Transform component of a Curve clayxel object so that the curve intersects the world-space control points p0,p1,p2.
Useful if you want to create a snakelike object that is defined by a series of control points, for example.
Note this does not work with older versions of Clayxels.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Clayxels;
using System;
public class ClayCurveControl : MonoBehaviour
{
ClayObject clayObject;
void Start()
{
clayObject = GetComponent<ClayObject>();
}
public void SetPositionsNew(Vector3 _p0, Vector3 _p1, Vector3 _p2, float _weight, float _fat, float _blend)
{
//if numbers are too similar, the shape won't be created properly.
if (Mathf.Abs(_p0.x - _p1.x) < 0.001f)
_p1 += Vector3.left * 0.002f;
if (Mathf.Abs(_p1.x - _p2.x) < 0.001f)
_p2 += Vector3.left * 0.002f;
if (Mathf.Abs(_p0.y - _p1.y) < 0.001f)
_p1 += Vector3.up * 0.002f;
if (Mathf.Abs(_p1.y - _p2.y) < 0.001f)
_p2 += Vector3.up * 0.002f;
if (Mathf.Abs(_p0.z - _p1.z) < 0.001f)
_p1 += Vector3.forward * 0.002f;
if (Mathf.Abs(_p1.z - _p2.z) < 0.001f)
_p2 += Vector3.forward * 0.002f;
Vector3 p0 = _p0;
Vector3 p1 = _p1;
Vector3 p2 = _p2;
ClayObject clayObject = GetComponent<ClayObject>();
//set w (slide)
float w = Vector3.Dot(p1 - p0, Vector3.Normalize(p2 - p0)) / Vector3.Distance(p2, p0);
clayObject.attrs.x = (w - 0.5f) * 2f + 0.5f;
//set fat and weight
clayObject.attrs.y = _weight;
clayObject.attrs.z = _fat * 1.25f; //NEW
clayObject.blend = _blend;
//set rotation
Vector3 x0 = p2 - p0;
Vector3 z0 = Vector3.Cross(p1 - p0, p2 - p0);
Vector3 y0 = Vector3.Cross(z0, x0);
transform.rotation = Quaternion.LookRotation(-z0, -y0);
//set scale
float sx = 0.1f + Vector3.Distance(p0, p2);
float bb = Vector3.SqrMagnitude(w * (p2 - p0));
float cc = Vector3.SqrMagnitude(p1 - p0);
float aa = Mathf.Sqrt(cc - bb);
float sy = 0.06f + aa/(0.25f + 0.5f); //hopefully not a negative route.
float sz = 1f;
if (sy == 0)
sy = float.Epsilon;
if (!float.IsNaN(sy))
transform.localScale = new Vector3(sx / transform.parent.localScale.x, sy / transform.parent.localScale.y, sz);
if(p0 != p2)
transform.position = 0.5f * ((p0 + p2) - Vector3.Normalize(y0) * (sy - 0.1f));// - 0.5f * Vector3.Scale(new Vector3(-0.455f, -0.455f, 0), transform.localScale);
}
}
The previous solution doesn't work for the 'curve' in the latest version of Clayxels including the one on the Unity Asset Store. I've modified the code above to work - use the following instead. The following takes three control points in world space and adjusts the Transform of the Clayxel curve object so that the curve intersects the 3 control points.
public void SetPositionsNew(Vector3 _p0, Vector3 _p1, Vector3 _p2, float _weight, float _fat, float _blend)
{
//if numbers are too similar, the shape won't be created properly.
if (Mathf.Abs(_p0.x - _p1.x) < 0.001f)
_p1 += Vector3.left * 0.002f;
if (Mathf.Abs(_p1.x - _p2.x) < 0.001f)
_p2 += Vector3.left * 0.002f;
if (Mathf.Abs(_p0.y - _p1.y) < 0.001f)
_p1 += Vector3.up * 0.002f;
if (Mathf.Abs(_p1.y - _p2.y) < 0.001f)
_p2 += Vector3.up * 0.002f;
if (Mathf.Abs(_p0.z - _p1.z) < 0.001f)
_p1 += Vector3.forward * 0.002f;
if (Mathf.Abs(_p1.z - _p2.z) < 0.001f)
_p2 += Vector3.forward * 0.002f;
Vector3 p0 = _p0;
Vector3 p1 = _p1;
Vector3 p2 = _p2;
ClayObject clayObject = GetComponent<ClayObject>();
//set w (slide)
float w = Vector3.Dot(p1 - p0, Vector3.Normalize(p2 - p0)) / Vector3.Distance(p2, p0);
clayObject.attrs.x = (w - 0.5f) * 2f + 0.5f;
//set fat and weight
clayObject.attrs.y = _weight;
clayObject.attrs.z = _fat * 1.25f; //NEW
clayObject.blend = _blend;
//set rotation
Vector3 x0 = p2 - p0;
Vector3 z0 = Vector3.Cross(p1 - p0, p2 - p0);
Vector3 y0 = Vector3.Cross(z0, x0);
transform.rotation = Quaternion.LookRotation(-z0, -y0);
//set scale
float sx = 0.1f + Vector3.Distance(p0, p2);
float bb = Vector3.SqrMagnitude(w * (p2 - p0));
float cc = Vector3.SqrMagnitude(p1 - p0);
float aa = Mathf.Sqrt(cc - bb);
float sy = 0.06f + aa/(0.25f + 0.5f); //hopefully not a negative route.
float sz = 1f;
if (sy == 0)
sy = float.Epsilon;
if (!float.IsNaN(sy))
transform.localScale = new Vector3(sx / transform.parent.localScale.x, sy / transform.parent.localScale.y, sz);
if(p0 != p2)
transform.position = 0.5f * ((p0 + p2) - Vector3.Normalize(y0) * (sy - 0.1f));// - 0.5f * Vector3.Scale(new Vector3(-0.455f, -0.455f, 0), transform.localScale);
}
Hi Andrea! Thanks for the response. I'll have a look into the normals script thanks!
Even though it is not perfect, I'd still like to automate it at run time (understanding the caveats). For my purposes, the odd missing triangle isn't a problem anyway. It would also be great to control the 'max verts' parameter from script. What are your priorities at the moment? Any estimate on when this feature might come out? Else I'll look into alternative methods for post processing the meshes for now.
Great work though Andrea! I couldn't have built my game without Clayxels.
I noticed you also changed how the 'curve' is scaled and positioned relative to its transform. Will post on other thread.
Regards,
Ben
Hi.
I've been using the alpha version and have called this function without issues in the past, but now I'm finding problems.
1) On the previous version, freezing the mesh (either from the editor or from script using clayContainer.generateMesh()), also smoothed the normals. Now, however, it seems to produce hard normals (so low poly meshes look very polyganol). Am I doing something wrong or is this a bug? To reproduce: new scene, empty GameObject, add ClayContainer, hit 'add clay' button (creating a box) then 'freeze to mesh' - generates angular corners.
2) When calling from script clayContainer.generateMesh(), the mesh generated ignores the 'retopology' option, producing the same mesh as above. I'd love to call the generate mesh from script with the retopology funtion please.
The reasons I want this: I'm generating many shapes procedurally and do not want to manually export hundreds of meshes.
Thanks!
Hi Andrea! Really congratulations on releasing on the Asset Store - I purchased a copy immediately.
I'm most excited about having unlimited shapes, the retopology, and the spline mode. I don't suppose you could put up some examples of before and after the retopology process to see how it works? Would be useful to illustrate for people. I was finding that the mesh generated was far from optimal and was looking into ways to bulk convert these output meshes into more friendly ones, but now maybe I won't need to. Also, is there any documentation/video of the spline tool?
Looking forward to getting stuck into this release.
All the best,
Ben
hi,
yes indeed. I want to load up a premade clayxel, then mesh it, then apply my own shader to it (all at once). I haven’t tested performance but presume that a large clayxel will perform better as a mesh model than as a clayxel, and I can also apply my vertex and fragment shaders to it. An alternative would be for me to freeze all the level meshes and store them in the build. This would add to the build file size and also I’d like to enable users to design their own clayxel and make that into a mesh themselves in the app.
When I load a new level, I fade to black while the clayxel sets up and meshes the model, currently. It would be nicer to give the user still the ability to look around during this time (it’s in VR).
I’m using clayxels to build tunnel-like levels for my game.
Any suggestions you have would be welcome!
Hi Andrea! Thanks so much. Yes I figured I can control the Bezier points using a few custom transforms and controlling the position, rotation and scale of the object (although it would be nice to be able to access these directly). Here is the code to do so!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ClayCurveControl : MonoBehaviour
{
ClayObject clayObject;
void Start()
{
clayObject = GetComponent<ClayObject>();
}
public void SetPositions(Vector3 _p0, Vector3 _p1, Vector3 _p2, float _weight, float _fat)
{
//if numbers are too similar, the shape won't be created properly.
if (Mathf.Abs(_p0.x - _p1.x) < 0.001f)
_p1 += Vector3.left * 0.002f;
if (Mathf.Abs(_p1.x - _p2.x) < 0.001f)
_p2 += Vector3.left * 0.002f;
if (Mathf.Abs(_p0.y - _p1.y) < 0.001f)
_p1 += Vector3.up * 0.002f;
if (Mathf.Abs(_p1.y - _p2.y) < 0.001f)
_p2 += Vector3.up * 0.002f;
if (Mathf.Abs(_p0.z - _p1.z) < 0.001f)
_p1 += Vector3.forward * 0.002f;
if (Mathf.Abs(_p1.z - _p2.z) < 0.001f)
_p2 += Vector3.forward * 0.002f;
Vector3 p0 = _p0;
Vector3 p1 = _p1;
Vector3 p2 = _p2;
ClayObject clayObject = GetComponent<ClayObject>();
//set w (slide)
float w = Vector3.Dot(p1 - p0, Vector3.Normalize(p2 - p0))/Vector3.Distance(p2,p0);
clayObject.attrs.x = w;
//set fat and fat
clayObject.attrs.y = _weight;
clayObject.attrs.z = _fat;
//set position
transform.position = p0;
//set rotation
Vector3 x0 = p2 - p0;
Vector3 z0 = Vector3.Cross(p1 - p0, p2 - p0);
Vector3 y0 = Vector3.Cross(z0, x0);
transform.rotation = Quaternion.LookRotation(-z0, -y0);
//set scale
float sx = 2f * Vector3.Distance(p0, p2);
float bb = Vector3.SqrMagnitude(w * (p2 - p0));
float cc = Vector3.SqrMagnitude(p1 - p0);
float sy = 4f * Mathf.Sqrt(cc - bb); //hopefully not a negative route.
float sz = 1f;
if(sy == 0)
sy = float.Epsilon;
if (!float.IsNaN(sy))
transform.localScale = new Vector3(sx/transform.parent.localScale.x, sy/transform.parent.localScale.y, sz);
}
}
I've noticed the 'curve' object is a Bezier SDF, but the points are linked to the position and scale of the object. I'd like to control them directly. How can I do this?
I don't understand why the 'Clay Object' script has choice 'curve' in the solidType dropdown, but in the script there is an enum, which doesn't have 'curve', but does have 'hexagon'. Not sure how this works.
Any help would be appreciated!