You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor.Experimental.SceneManagement;
#endif
namespace SplineMesh {
///
/// Deform a mesh and place it along a spline, given various parameters.
///
/// This class intend to cover the most common situations of mesh bending. It can be used as-is in your project,
/// or can serve as a source of inspiration to write your own procedural generator.
///
[ExecuteInEditMode]
[SelectionBase]
[DisallowMultipleComponent]
public class SplineMeshTiling : MonoBehaviour {
string _instanceId = "";
private GameObject generated;
private Spline spline = null;
private bool toUpdate = false;
public bool initOnEnable = false;
[Tooltip("Mesh to bend along the spline.")]
public Mesh mesh;
[Tooltip("Material to apply on the bent mesh.")]
public Material material;
[Tooltip("Physic material to apply on the bent mesh.")]
public PhysicMaterial physicMaterial;
[Tooltip("Translation to apply on the mesh before bending it.")]
public Vector3 translation;
[Tooltip("Rotation to apply on the mesh before bending it.")]
public Vector3 rotation;
[Tooltip("Scale to apply on the mesh before bending it.")]
public Vector3 scale = Vector3.one;
[Tooltip("If true, a mesh collider will be generated.")]
public bool generateCollider = true;
[Tooltip("If true, the mesh will be bent on play mode. If false, the bent mesh will be kept from the editor mode, allowing lighting baking.")]
public bool updateInPlayMode;
[Tooltip("If true, a mesh will be placed on each curve of the spline. If false, a single mesh will be placed for the whole spline.")]
public bool curveSpace = false;
[Tooltip("The mode to use to fill the choosen interval with the bent mesh.")]
public MeshBender.FillingMode mode = MeshBender.FillingMode.StretchToInterval;
private void OnEnable() {
if (initOnEnable) {
Init();
}
}
public void Init() {
if (_instanceId.Length < 1) {
if (transform.childCount > 0 && transform.GetChild(0).name.Contains(GetType().Name)) {
string name = transform.GetChild(0).name;
_instanceId = name.Substring(0, name.IndexOf("_"));
} else {
_instanceId = UnityEngine.Random.Range(0, 999999999).ToString();
}
}
// tip : if you name all generated content in the same way, you can easily find all of it
// at once in the scene view, with a single search.
string generatedName = _instanceId + "_genBy_" + GetType().Name;
var generatedTranform = transform.Find(generatedName);
generated = generatedTranform != null ? generatedTranform.gameObject : UOUtility.Create(generatedName, gameObject);
spline = GetComponentInParent<Spline>();
spline.NodeListChanged += (s, e) => toUpdate = true;
toUpdate = true;
}
private void OnValidate() {
if (spline == null) return;
toUpdate = true;
}
private void Update() {
// we can prevent the generated content to be updated during playmode to preserve baked data saved in the scene
if (!updateInPlayMode && Application.isPlaying) return;
if (toUpdate) {
toUpdate = false;
CreateMeshes();
}
}
public void CreateMeshes() {
#if UNITY_EDITOR
// we don't update if we are in prefab mode
if (PrefabStageUtility.GetCurrentPrefabStage() != null) return;
#endif
var used = new List();
if (curveSpace) {
int i = 0;
foreach (var curve in spline.curves) {
var go = FindOrCreate(_instanceId + "segment " + i++ + " mesh");
go.GetComponent<MeshBender>().SetInterval(curve);
go.GetComponent<MeshCollider>().enabled = generateCollider;
used.Add(go);
}
} else {
var go = FindOrCreate(_instanceId + "segment 1 mesh");
go.GetComponent<MeshBender>().SetInterval(spline, 0);
go.GetComponent<MeshCollider>().enabled = generateCollider;
used.Add(go);
}
// we destroy the unused objects. This is classic pooling to recycle game objects.
foreach (var go in generated.transform
.Cast<Transform>()
.Select(child => child.gameObject).Except(used)) {
UOUtility.Destroy(go);
}
}
private GameObject FindOrCreate(string name) {
var childTransform = generated.transform.Find(name);
GameObject res;
if (childTransform == null) {
res = UOUtility.Create(name,
generated,
typeof(MeshFilter),
typeof(MeshRenderer),
typeof(MeshBender),
typeof(MeshCollider));
res.isStatic = !updateInPlayMode;
} else {
res = childTransform.gameObject;
}
res.GetComponent<MeshRenderer>().material = material;
res.GetComponent<MeshCollider>().material = physicMaterial;
MeshBender mb = res.GetComponent<MeshBender>();
mb.Source = SourceMesh.Build(mesh)
.Translate(translation)
.Rotate(Quaternion.Euler(rotation))
.Scale(scale);
mb.Mode = mode;
return res;
}
}
}
The text was updated successfully, but these errors were encountered:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor.Experimental.SceneManagement;
#endif
namespace SplineMesh {
///
/// Deform a mesh and place it along a spline, given various parameters.
///
/// This class intend to cover the most common situations of mesh bending. It can be used as-is in your project,
/// or can serve as a source of inspiration to write your own procedural generator.
///
[ExecuteInEditMode]
[SelectionBase]
[DisallowMultipleComponent]
public class SplineMeshTiling : MonoBehaviour {
string _instanceId = "";
#if UNITY_EDITOR
// we don't update if we are in prefab mode
if (PrefabStageUtility.GetCurrentPrefabStage() != null) return;
#endif
var used = new List();
}
The text was updated successfully, but these errors were encountered: