Skip to content

Instantly share code, notes, and snippets.

@FriendSea
Created November 25, 2022 03:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FriendSea/e36242fe249dc984e3717b75460e9125 to your computer and use it in GitHub Desktop.
Save FriendSea/e36242fe249dc984e3717b75460e9125 to your computer and use it in GitHub Desktop.
C#の式からメッシュ作るくん
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.AssetImporters;
using UnityEditor;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
[ScriptedImporter(0, ".meshgenerator")]
public class SurfaceMeshGenerator : ScriptedImporter
{
[SerializeField]
Vector2Int divCount = new Vector2Int(10, 10);
public class Inputs
{
public float u;
public float v;
}
public async override void OnImportAsset(AssetImportContext ctx)
{
var text = System.IO.File.ReadAllText(ctx.assetPath);
var options = ScriptOptions.Default.AddReferences(typeof(Vector3).Assembly).AddImports("UnityEngine");
var script = CSharpScript.Create(text, globalsType: typeof(Inputs), options: options);
var verticies = new List<Vector3>();
var uvs = new List<Vector2>();
for(int i = 0; i <= divCount.x; i++)
{
for(int j = 0; j <= divCount.y; j++)
{
var inputs = new Inputs() {
u = (float)i / divCount.x,
v = (float)j / divCount.y,
};
var pos = (Vector3)((await script.RunAsync(globals: inputs)).ReturnValue);
verticies.Add(pos);
uvs.Add(new Vector2(inputs.u, inputs.v));
}
}
var triangles = new List<int>();
for (int i = 0; i < divCount.x; i++)
{
for (int j = 0; j < divCount.y; j++)
{
var baseIndex = (divCount.y+1) * i + j;
TryAddTriangle(baseIndex, baseIndex + 1, baseIndex + divCount.y + 1);
TryAddTriangle(baseIndex+1, baseIndex + divCount.y + 2, baseIndex + divCount.y + 1);
}
}
var mesh = new Mesh();
mesh.SetVertices(verticies);
mesh.SetTriangles(triangles, 0);
mesh.SetUVs(0, uvs);
mesh.RecalculateBounds();
mesh.RecalculateNormals();
ctx.AddObjectToAsset("main", mesh, AssetPreview.GetMiniThumbnail(mesh));
ctx.SetMainObject(mesh);
void TryAddTriangle(int i0, int i1, int i2)
{
if (verticies[i0] == verticies[i1]) return;
if (verticies[i0] == verticies[i2]) return;
if (verticies[i1] == verticies[i2]) return;
triangles.Add(i0);
triangles.Add(i1);
triangles.Add(i2);
}
}
[MenuItem("Assets/Create/📃📦Surface Mesh Generator")]
static void CreateFile()
{
ProjectWindowUtil.CreateAssetWithContent("New Surface Mesh.meshgenerator", defaultCode);
AssetDatabase.Refresh();
}
static string defaultCode =
@"
// Cylinder
//Quaternion.Euler(0,-u*360, 0)*(Vector3.forward*1 + Vector3.up*v*2)
// Cone
//Quaternion.Euler(0,-u*360, 0)*(Vector3.forward*(v*0.5f) + Vector3.up*v)
// Sphere
//Quaternion.Euler(Mathf.Lerp(-90f,90f,v),u*360, 0) * Vector3.forward
// Waved Plane
new Vector3(u*10f, Mathf.Sin(u*10f)*Mathf.Sin(v*10f), v*10f)
// Spiral
//Quaternion.Euler(0,-u*360*1, 0)*Vector3.forward*(v/2f+1+u-Mathf.Abs(0.5f-v)) + Vector3.up*(v+u*3)
";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment