Hi everyone.
Following the interest some of you had for the custom script used in the Unity Pixyz Plugin Webinar. I’ll try to explain here how I created this one and how you could use the same process to match your special need or customize your dataprep pipeline as you wish.
Create a Custom Action Script
The first thing you need to do is to create the script. We tried to mimic the regular way of creating a custom MonoBehavior.
-
Right click in your project window Create->Pixyz->C#CustomScript
-
Type the name you want to give to your action. In my case: MaterialNameGenerator
-
Type Enter. It will reload the domain and rebuild the PixyzToolobox. You will be able to see the new icon in the toolbar, and also be able to add it in any ruleset
-
Open your created action in your IDE to start editing it.
Modify your Custom Action Script
In the created file, you will see your new class inherited from ActionInOut. It comes with methods you have to overwrite, and example about how to add new parameters. Those parameters will be exposed in the UI generated automatically. You can also add tooltips and have access to different settings in [UserParameter]. But I wont go too much into detail here.
You can customize the category it will be exposed (here in “Custom”) and also you can change the icon path of your action. I won’t touch this params here.
Then the most important part is the Run method you will have to implement. This is what will be executed when you click on Run. The input list is what is retrieved from the action above. And the returned list is what is sent to the next one.
How did I change the name of the materials
I wanted to ensure that each name reflects the value of the parameters contained in the material so I won’t have two times the same name for two different materials. And also that if I rerun my rule twice or reimport the model, the name doesn’t change. That way, Cam can rely on them for his Material Swaping step.
My solution whas to retrieve the properties of some material channel that are present in both URP and HDRP, so the action is compatible with both LIT standard material pipeline. Then I hash the string created to generate a small ID.
I do not garanty the code is super robust in every situation. But it’s a good start
#if PIXYZ_PLUGIN_FOR_UNITY
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.PixyzPlugin4Unity.Actions;
// Please ensure your class and your file have the same name
public class MaterialNameGenerator : ActionInOut<IList<GameObject>, IList<GameObject>>
{
public override int Id { get { return 106117606;} }
public override string MenuPathRuleEngine { get { return "Custom/MaterialNameGenerator"; } }
public override string MenuPathToolbox { get { return "Custom/MaterialNameGenerator"; } }
public override string Tooltip { get { return "Generate a new material named based on Material properties (based color, metallic and smoothness)";} }
public override string Icon { get { return null ; } }
public override int Priority => 15001;
public override IList<GameObject> Run(IList<GameObject> input)
{
foreach (GameObject go in input)
{
MeshRenderer renderer = go.GetComponent<MeshRenderer>();
if (renderer == null)
{
continue;
}
Material[] materials = renderer.sharedMaterials;
foreach (Material mat in materials)
{
if (mat == null)
{
continue;
}
string newName = "";
if (mat.HasProperty("_BaseColor"))
{
Color baseColor = mat.GetColor("_BaseColor");
newName += baseColor.r + "," + baseColor.g + "," + baseColor.b;
}
if (mat.HasProperty("_Metallic"))
{
newName += "," + mat.GetFloat("_Metallic");
}
if (mat.HasProperty("_Smoothness"))
{
newName += "," + mat.GetFloat("_Smoothness");
}
mat.name = Mathf.Abs(newName.GetHashCode()).ToString();
}
}
return input;
}
}
#endif
For more info: Actions | Pixyz Plugin for Unity | 3.0.3
I hope it will help you to create your own custom action !