Created
January 24, 2019 20:10
-
-
Save karl-/47c7b8b60cccc9cd38b7f571cd6e7921 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using UnityEngine; | |
using UnityEngine.ProBuilder; | |
using UnityEngine.ProBuilder.MeshOperations; | |
namespace PipeDreams | |
{ | |
sealed class Pipe : MonoBehaviour | |
{ | |
static System.Random s_Random = new System.Random(); | |
float m_ExtrudeSpeed = 1f; | |
float m_MinExtrudeDistance = 3f; | |
float m_MaxExtrudeDistance = 20f; | |
ProBuilderMesh m_Mesh; | |
Face[] m_ActiveFaces = new Face[1]; | |
List<Vector3> m_Positions; | |
List<int> m_Indices = new List<int>(); | |
Vector3 m_ExtrudeDirection; | |
float m_ExtrudeDistance; | |
Face activeFace | |
{ | |
get { return m_ActiveFaces[0]; } | |
set { m_ActiveFaces[0] = value; } | |
} | |
public ProBuilderMesh mesh | |
{ | |
get { return m_Mesh; } | |
} | |
void Awake() | |
{ | |
m_Mesh = GetComponent<ProBuilderMesh>(); | |
} | |
public void Begin(float extrudeSpeed, float minimumExtrudeDistance, float maximumExtrudeDistance) | |
{ | |
m_ExtrudeSpeed = extrudeSpeed; | |
m_MinExtrudeDistance = minimumExtrudeDistance; | |
m_MaxExtrudeDistance = maximumExtrudeDistance; | |
activeFace = m_Mesh.faces[s_Random.Next(0, m_Mesh.faceCount)]; | |
ChangeDirection(); | |
} | |
void ChangeDirection() | |
{ | |
// Extrude once to create a turn | |
Face[] extrudedSides = m_Mesh.Extrude(m_ActiveFaces, ExtrudeMethod.FaceNormal, 1f); | |
// Select a new active face | |
activeFace = extrudedSides[s_Random.Next(0, extrudedSides.Length)]; | |
// Extrude again to create the extending segment | |
m_Mesh.Extrude(m_ActiveFaces, ExtrudeMethod.FaceNormal, .001f); | |
// Get the direction of the extruded face | |
m_ExtrudeDirection = Math.Normal(m_Mesh, activeFace); | |
m_Positions = m_Mesh.positions.ToList(); | |
// Populate the list of coincident vertex indices | |
m_Mesh.GetCoincidentVertices(m_ActiveFaces, m_Indices); | |
float distance = m_MinExtrudeDistance + (float) s_Random.NextDouble() * (m_MaxExtrudeDistance - m_MinExtrudeDistance); | |
Ray dir =new Ray( | |
m_Mesh.transform.TransformPoint(Math.Average(m_Positions, activeFace.distinctIndexes)), | |
m_Mesh.transform.TransformDirection(m_ExtrudeDirection)); | |
if (dir.GetPoint(distance).magnitude > m_MaxExtrudeDistance * 2f) | |
distance = m_MaxExtrudeDistance * 2f - dir.origin.magnitude; | |
StartCoroutine(ExtrudeFace(distance)); | |
} | |
IEnumerator ExtrudeFace(float targetDistance) | |
{ | |
float distance = 0f; | |
while (distance < targetDistance) | |
{ | |
distance += m_ExtrudeSpeed * Time.deltaTime; | |
foreach (var index in m_Indices) | |
m_Positions[index] += m_ExtrudeDirection * m_ExtrudeSpeed * Time.deltaTime; | |
m_Mesh.positions = m_Positions; | |
m_Mesh.ToMesh(); | |
m_Mesh.Refresh(); | |
yield return null; | |
} | |
ChangeDirection(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment