338 lines
14 KiB
C#
338 lines
14 KiB
C#
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
|
||
|
public class LeafGrowScript : MonoBehaviour
|
||
|
{
|
||
|
public GameObject parent;
|
||
|
public GameObject materialSettings;
|
||
|
[Header("Leaf shape")]
|
||
|
public Vector2[] widthCurveKeyPoints = {new Vector2(0.0f, 0.0f), new Vector2(0.5f, 1.0f), new Vector2(1.0f, 0.0f)};
|
||
|
public Vector2[] foldCurveKeyPoints = {new Vector2(0.0f, 0.0f), new Vector2(0.5f, 1.0f), new Vector2(1.0f, 0.0f)};
|
||
|
public float lengthScale = 0.06f;
|
||
|
public float thickness = 0.01f;
|
||
|
public float infold = 0.03f;
|
||
|
|
||
|
[Header("Animation and resolution")]
|
||
|
public float framesBetweenSteps = 2.0f;
|
||
|
public int numberOfAnimationSteps = 30;
|
||
|
[Comment("The number of animation steps also affects the resolution of the model", "8 * numberOfAnimationSteps = number of vertices")]
|
||
|
public bool commentSpace = true;
|
||
|
// EditorGUILayout.HelpBox("Number of animation steps also affects resolution of the model" , MessageType.Info);
|
||
|
|
||
|
[Header("Special features")]
|
||
|
public bool roughEdges = false;
|
||
|
public int roughEdgesSize = 10;
|
||
|
public int numberOfBranchesPairs = 10;
|
||
|
public bool showBranches = false;
|
||
|
public bool colision = false;
|
||
|
public Rigidbody colisionJoint;
|
||
|
|
||
|
[Header("Position")]
|
||
|
public float positionX = 0.0f;
|
||
|
public float positionY = 0.0f;
|
||
|
public float positionZ = 0.0f;
|
||
|
|
||
|
[Header("Rotation")]
|
||
|
public float rotationX = 0.0f;
|
||
|
public float rotationY = 0.0f;
|
||
|
public float rotationZ = 0.0f;
|
||
|
|
||
|
[Header("Copies of leaf")]
|
||
|
public int numberOfCopies = 0;
|
||
|
|
||
|
public float positionXMove = 0.0f;
|
||
|
public float positionYMove = 0.0f;
|
||
|
public float positionZMove = 0.0f;
|
||
|
public float rotationXChange = 0.0f;
|
||
|
public float rotationYChange = 0.0f;
|
||
|
public float rotationZChange = 0.0f;
|
||
|
public int animationStepsChange = -1;
|
||
|
[Comment("Decrease the number of animation steps with each copy", "AnimationStepsLimit")]
|
||
|
public bool commentSpaceB = true;
|
||
|
public int animationFrameDelay = 2;
|
||
|
[Comment("Delay between creation of each copy", "animationFrameDelay")]
|
||
|
public bool commentSpaceC = true;
|
||
|
|
||
|
int maxNumberOfSteps = 0;
|
||
|
int frame = 0;
|
||
|
// Start is called before the first frame update
|
||
|
public void addNewLeaf(GameObject newParent, Vector3 newPosition, Vector3 newRotation, Vector2[] newWidthCurveKeyPoints, Vector2[] newFoldCurveKeyPoints, float newLengthScale, float newThickness, float newInfold)
|
||
|
{
|
||
|
GameObject leafObject = new GameObject("newLeaf");
|
||
|
int i = 0;
|
||
|
MeshFilter leafMeshFilter = leafObject.AddComponent<MeshFilter>();
|
||
|
leafMeshFilter = materialSettings.GetComponent<MeshFilter>();
|
||
|
MeshRenderer leafMeshRenderer = leafObject.AddComponent<MeshRenderer>();
|
||
|
leafMeshRenderer = materialSettings.GetComponent<MeshRenderer>();
|
||
|
leafObject.GetComponent<MeshRenderer>().material = materialSettings.GetComponent<MeshRenderer>().material;
|
||
|
|
||
|
|
||
|
LeafGrow newLeaf = leafObject.AddComponent<LeafGrow>();
|
||
|
leafObject.GetComponent<Transform>().parent = newParent.GetComponent<Transform>();
|
||
|
leafObject.GetComponent<Transform>().localPosition = newPosition;
|
||
|
leafObject.GetComponent<Transform>().localRotation = Quaternion.Euler(newRotation.x, newRotation.y, newRotation.z);
|
||
|
|
||
|
|
||
|
Keyframe[] widthCurveKeys = new Keyframe[newWidthCurveKeyPoints.Length];
|
||
|
float directionIn = 0.0f;
|
||
|
float directionOut= 0.0f;
|
||
|
for(i=0;i<newWidthCurveKeyPoints.Length;i++)
|
||
|
{
|
||
|
directionIn = 0.0f;
|
||
|
directionOut = 0.0f;
|
||
|
if(i != 0 && i != newWidthCurveKeyPoints.Length-1)
|
||
|
{
|
||
|
if(newWidthCurveKeyPoints[i+1].y > newWidthCurveKeyPoints[i-1].y)
|
||
|
{
|
||
|
directionIn = (newWidthCurveKeyPoints[i+1].x - newWidthCurveKeyPoints[i-1].x);
|
||
|
}
|
||
|
if(newWidthCurveKeyPoints[i+1].y < newWidthCurveKeyPoints[i-1].y)
|
||
|
{
|
||
|
directionIn = (newWidthCurveKeyPoints[i-1].x - newWidthCurveKeyPoints[i+1].x);
|
||
|
}
|
||
|
if(newWidthCurveKeyPoints[i-1].y > newWidthCurveKeyPoints[i+1].y)
|
||
|
{
|
||
|
directionOut = (newWidthCurveKeyPoints[i-1].x - newWidthCurveKeyPoints[i+1].x);
|
||
|
}
|
||
|
if(newWidthCurveKeyPoints[i-1].y < newWidthCurveKeyPoints[i+1].y)
|
||
|
{
|
||
|
directionOut = (newWidthCurveKeyPoints[i+1].x - newWidthCurveKeyPoints[i-1].x);
|
||
|
}
|
||
|
widthCurveKeys[i] = new Keyframe(newWidthCurveKeyPoints[i].x, newWidthCurveKeyPoints[i].y, directionIn, directionOut, 0.4f ,0.4f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
widthCurveKeys[i] = new Keyframe(newWidthCurveKeyPoints[i].x, newWidthCurveKeyPoints[i].y, 0,0,0,0);
|
||
|
}
|
||
|
}
|
||
|
AnimationCurve widthCurve = new AnimationCurve(widthCurveKeys);
|
||
|
// widthCurve.preWrapMode = WrapMode.PingPong;
|
||
|
// widthCurve.postWrapMode = WrapMode.PingPong;
|
||
|
|
||
|
Keyframe[] foldCurveKeys = new Keyframe[newFoldCurveKeyPoints.Length];
|
||
|
|
||
|
for(i=0;i<newFoldCurveKeyPoints.Length;i++)
|
||
|
{
|
||
|
directionIn = 0.0f;
|
||
|
directionOut = 0.0f;
|
||
|
if(i != 0 && i != newFoldCurveKeyPoints.Length-1)
|
||
|
{
|
||
|
if(newFoldCurveKeyPoints[i+1].y > newFoldCurveKeyPoints[i-1].y)
|
||
|
{
|
||
|
directionIn = (newFoldCurveKeyPoints[i+1].x - newFoldCurveKeyPoints[i-1].x);
|
||
|
}
|
||
|
if(newFoldCurveKeyPoints[i+1].y < newFoldCurveKeyPoints[i-1].y)
|
||
|
{
|
||
|
directionIn = (newFoldCurveKeyPoints[i-1].x - newFoldCurveKeyPoints[i+1].x);
|
||
|
}
|
||
|
if(newFoldCurveKeyPoints[i-1].y > newFoldCurveKeyPoints[i+1].y)
|
||
|
{
|
||
|
directionOut = (newFoldCurveKeyPoints[i-1].x - newFoldCurveKeyPoints[i+1].x);
|
||
|
}
|
||
|
if(newFoldCurveKeyPoints[i-1].y < newFoldCurveKeyPoints[i+1].y)
|
||
|
{
|
||
|
directionOut = (newFoldCurveKeyPoints[i+1].x - newFoldCurveKeyPoints[i-1].x);
|
||
|
}
|
||
|
foldCurveKeys[i] = new Keyframe(newFoldCurveKeyPoints[i].x, newFoldCurveKeyPoints[i].y, directionIn, directionOut, 0.4f ,0.4f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
foldCurveKeys[i] = new Keyframe(newFoldCurveKeyPoints[i].x, newFoldCurveKeyPoints[i].y, 0,0,0,0);
|
||
|
}
|
||
|
}
|
||
|
AnimationCurve foldCurve = new AnimationCurve(foldCurveKeys);
|
||
|
// foldCurve.preWrapMode = WrapMode.PingPong;
|
||
|
// foldCurve.postWrapMode = WrapMode.PingPong;
|
||
|
|
||
|
|
||
|
newLeaf.widthCurve = widthCurve;
|
||
|
newLeaf.foldCurve = foldCurve;
|
||
|
newLeaf.length = newLengthScale;
|
||
|
newLeaf.thickness = newThickness;
|
||
|
newLeaf.infold = newInfold;
|
||
|
newLeaf.framesBetweenSteps = framesBetweenSteps;
|
||
|
newLeaf.numberOfAnimationSteps = numberOfAnimationSteps;
|
||
|
newLeaf.roughEdges = roughEdges;
|
||
|
newLeaf.roughEdgesSize = roughEdgesSize;
|
||
|
newLeaf.numberOfBranchesPairs = numberOfBranchesPairs;
|
||
|
newLeaf.showBranches = showBranches;
|
||
|
newLeaf.colision = colision;
|
||
|
newLeaf.colisionJoint = colisionJoint;
|
||
|
newLeaf.maxNumberOfSteps = maxNumberOfSteps;
|
||
|
}
|
||
|
public void Grow(bool inEditor = false)
|
||
|
{
|
||
|
GameObject leafObject = new GameObject("leafScriptStart");
|
||
|
int i = 0;
|
||
|
MeshFilter leafMeshFilter = leafObject.AddComponent<MeshFilter>();
|
||
|
leafMeshFilter = materialSettings.GetComponent<MeshFilter>();
|
||
|
MeshRenderer leafMeshRenderer = leafObject.AddComponent<MeshRenderer>();
|
||
|
leafMeshRenderer = materialSettings.GetComponent<MeshRenderer>();
|
||
|
leafObject.GetComponent<MeshRenderer>().material = materialSettings.GetComponent<MeshRenderer>().material;
|
||
|
|
||
|
|
||
|
LeafGrow newLeaf = leafObject.AddComponent<LeafGrow>();
|
||
|
leafObject.GetComponent<Transform>().parent = parent.GetComponent<Transform>();
|
||
|
leafObject.GetComponent<Transform>().localPosition = new Vector3(positionX, positionY, positionZ);
|
||
|
leafObject.GetComponent<Transform>().localRotation = Quaternion.Euler(rotationX, rotationY, rotationZ);
|
||
|
|
||
|
Keyframe[] widthCurveKeys = new Keyframe[widthCurveKeyPoints.Length];
|
||
|
float directionIn = 0.0f;
|
||
|
float directionOut= 0.0f;
|
||
|
for(i=0;i<widthCurveKeyPoints.Length;i++)
|
||
|
{
|
||
|
directionIn = 0.0f;
|
||
|
directionOut = 0.0f;
|
||
|
if(i != 0 && i != widthCurveKeyPoints.Length-1)
|
||
|
{
|
||
|
if(widthCurveKeyPoints[i+1].y > widthCurveKeyPoints[i-1].y)
|
||
|
{
|
||
|
directionIn = (widthCurveKeyPoints[i+1].x - widthCurveKeyPoints[i-1].x);
|
||
|
}
|
||
|
if(widthCurveKeyPoints[i+1].y < widthCurveKeyPoints[i-1].y)
|
||
|
{
|
||
|
directionIn = (widthCurveKeyPoints[i-1].x - widthCurveKeyPoints[i+1].x);
|
||
|
}
|
||
|
if(widthCurveKeyPoints[i-1].y > widthCurveKeyPoints[i+1].y)
|
||
|
{
|
||
|
directionOut = (widthCurveKeyPoints[i-1].x - widthCurveKeyPoints[i+1].x);
|
||
|
}
|
||
|
if(widthCurveKeyPoints[i-1].y < widthCurveKeyPoints[i+1].y)
|
||
|
{
|
||
|
directionOut = (widthCurveKeyPoints[i+1].x - widthCurveKeyPoints[i-1].x);
|
||
|
}
|
||
|
widthCurveKeys[i] = new Keyframe(widthCurveKeyPoints[i].x, widthCurveKeyPoints[i].y, directionIn, directionOut, 0.4f ,0.4f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
widthCurveKeys[i] = new Keyframe(widthCurveKeyPoints[i].x, widthCurveKeyPoints[i].y, 0,0,0,0);
|
||
|
}
|
||
|
}
|
||
|
AnimationCurve widthCurve = new AnimationCurve(widthCurveKeys);
|
||
|
// widthCurve.preWrapMode = WrapMode.PingPong;
|
||
|
// widthCurve.postWrapMode = WrapMode.PingPong;
|
||
|
|
||
|
Keyframe[] foldCurveKeys = new Keyframe[foldCurveKeyPoints.Length];
|
||
|
|
||
|
for(i=0;i<foldCurveKeyPoints.Length;i++)
|
||
|
{
|
||
|
directionIn = 0.0f;
|
||
|
directionOut = 0.0f;
|
||
|
if(i != 0 && i != foldCurveKeyPoints.Length-1)
|
||
|
{
|
||
|
if(foldCurveKeyPoints[i+1].y > foldCurveKeyPoints[i-1].y)
|
||
|
{
|
||
|
directionIn = (foldCurveKeyPoints[i+1].x - foldCurveKeyPoints[i-1].x);
|
||
|
}
|
||
|
if(foldCurveKeyPoints[i+1].y < foldCurveKeyPoints[i-1].y)
|
||
|
{
|
||
|
directionIn = (foldCurveKeyPoints[i-1].x - foldCurveKeyPoints[i+1].x);
|
||
|
}
|
||
|
if(foldCurveKeyPoints[i-1].y > foldCurveKeyPoints[i+1].y)
|
||
|
{
|
||
|
directionOut = (foldCurveKeyPoints[i-1].x - foldCurveKeyPoints[i+1].x);
|
||
|
}
|
||
|
if(foldCurveKeyPoints[i-1].y < foldCurveKeyPoints[i+1].y)
|
||
|
{
|
||
|
directionOut = (foldCurveKeyPoints[i+1].x - foldCurveKeyPoints[i-1].x);
|
||
|
}
|
||
|
foldCurveKeys[i] = new Keyframe(foldCurveKeyPoints[i].x, foldCurveKeyPoints[i].y, directionIn, directionOut, 0.4f ,0.4f);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
foldCurveKeys[i] = new Keyframe(foldCurveKeyPoints[i].x, foldCurveKeyPoints[i].y, 0,0,0,0);
|
||
|
}
|
||
|
}
|
||
|
AnimationCurve foldCurve = new AnimationCurve(foldCurveKeys);
|
||
|
// foldCurve.preWrapMode = WrapMode.PingPong;
|
||
|
// foldCurve.postWrapMode = WrapMode.PingPong;
|
||
|
|
||
|
|
||
|
newLeaf.widthCurve = widthCurve;
|
||
|
newLeaf.foldCurve = foldCurve;
|
||
|
newLeaf.length = lengthScale;
|
||
|
newLeaf.thickness = thickness;
|
||
|
newLeaf.infold = infold;
|
||
|
newLeaf.framesBetweenSteps = framesBetweenSteps;
|
||
|
newLeaf.numberOfAnimationSteps = numberOfAnimationSteps;
|
||
|
newLeaf.roughEdges = roughEdges;
|
||
|
newLeaf.roughEdgesSize = roughEdgesSize;
|
||
|
newLeaf.numberOfBranchesPairs = numberOfBranchesPairs;
|
||
|
newLeaf.showBranches = showBranches;
|
||
|
newLeaf.colision = colision;
|
||
|
newLeaf.colisionJoint = colisionJoint;
|
||
|
newLeaf.maxNumberOfSteps = maxNumberOfSteps;
|
||
|
|
||
|
if(inEditor)
|
||
|
{
|
||
|
newLeaf.DrawLeaf();
|
||
|
}
|
||
|
nextCopy();
|
||
|
}
|
||
|
void nextCopy()
|
||
|
{
|
||
|
positionX += positionXMove;
|
||
|
positionY += positionYMove;
|
||
|
positionZ += positionZMove;
|
||
|
|
||
|
rotationX += rotationXChange;
|
||
|
rotationY += rotationYChange;
|
||
|
rotationZ += rotationZChange;
|
||
|
|
||
|
if(numberOfAnimationSteps > 4)
|
||
|
{
|
||
|
numberOfAnimationSteps += animationStepsChange;
|
||
|
}
|
||
|
}
|
||
|
private Vector3 spos;
|
||
|
private Vector3 srot;
|
||
|
private int numberOfAnimationStepsStart;
|
||
|
void Start()
|
||
|
{
|
||
|
maxNumberOfSteps = numberOfAnimationSteps;
|
||
|
spos = new Vector3(positionX, positionY, positionZ);
|
||
|
srot = new Vector3(rotationX, rotationY, rotationZ);
|
||
|
numberOfAnimationStepsStart = numberOfAnimationSteps;
|
||
|
}
|
||
|
public void DrawLeaf()
|
||
|
{
|
||
|
Start();
|
||
|
for(int i=0; i<numberOfCopies; i++)
|
||
|
{
|
||
|
Grow(true);
|
||
|
}
|
||
|
positionX = spos.x;
|
||
|
positionY = spos.y;
|
||
|
positionZ = spos.z;
|
||
|
|
||
|
rotationX = srot.x;
|
||
|
rotationY = srot.y;
|
||
|
rotationZ = srot.z;
|
||
|
numberOfAnimationSteps = numberOfAnimationStepsStart;
|
||
|
}
|
||
|
// Update is called once per frame
|
||
|
void Update()
|
||
|
{
|
||
|
if(frame < numberOfCopies*animationFrameDelay)
|
||
|
{
|
||
|
if(frame%animationFrameDelay == 0)
|
||
|
{
|
||
|
Grow();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(animationFrameDelay == 0 && frame == 1)
|
||
|
{
|
||
|
for(int i=0; i<numberOfCopies; i++)
|
||
|
{
|
||
|
Grow();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
frame += 1;
|
||
|
}
|
||
|
}
|