public void Grow(float deltaTime) { if (length < MaxLength) { length += deltaTime * Random.Range(GrowthRate * 0.50f, GrowthRate); if (length > hairNodes.Count * nodeLength) { // add a new 'node' to this strand GameObject go = Instantiate(HairNodePrefab, transform); HairNode script = go.GetComponent <HairNode>(); script.SetHead(head); go.transform.parent = transform; if (hairNodes.Count == 0) { // grow first node straight out from the head script.position = transform.position + (transform.position - head.transform.position).normalized * 0.1f; } else { // grow next node in a straight line with previous nodes GameObject prior = hairNodes[hairNodes.Count - 1]; GameObject priorer = NodeBefore(hairNodes.Count - 1); script.position = prior.transform.position + (prior.transform.position - priorer.transform.position).normalized * 0.1f; } go.transform.position = script.lastPosition = script.position; hairNodes.Add(go); } } }
void ConstrainLine(GameObject node1, GameObject node2, bool locked1) { HairNode script1 = null; Vector3 p1; if (!locked1) { script1 = node1.GetComponent <HairNode>(); p1 = script1.position; } else { p1 = transform.position; } HairNode script2 = node2.GetComponent <HairNode>(); Vector3 p2 = script2.position; Vector3 diff = p2 - p1; float distance = diff.magnitude; float move = ((nodeLength - distance) / distance) / 2.0f; diff *= move; if (!locked1) { script1.position -= diff; script2.position += diff; } else { script2.position += diff * 2; } }
void lengthConstraint(HairNode hairNode1, HairNode hairNode2, int index) { float distance = Vector3.Distance(hairNode1.curPos, hairNode2.curPos); Vector3 newPos1 = hairNode1.curPos + (hairNode2.curPos - hairNode1.curPos) * (distance - Mathf.Pow(length, (hairNodes.Count - 1 - index))) / (2 * distance); Vector3 newPos2 = hairNode2.curPos - (hairNode2.curPos - hairNode1.curPos) * (distance - Mathf.Pow(length, (hairNodes.Count - 1 - index))) / (2 * distance); hairNode1.curPos = newPos1; hairNode2.curPos = newPos2; }
void collideSphere(HairNode hairNode) { float distance = Vector3.Distance(hairNode.curPos, Head.position); if (distance < 1.15) { double newX = 1.15 / distance * (hairNode.curPos.x - Head.position.x) + Head.position.x; double newY = 1.15 / distance * (hairNode.curPos.y - Head.position.y) + Head.position.y; double newZ = 1.15 / distance * (hairNode.curPos.z - Head.position.z) + Head.position.z; Vector3 newPos = new Vector3((float)newX, (float)newY, (float)newZ); hairNode.curPos = newPos; } }
void Verlet(HairNode hairNode) { timer += Time.deltaTime; Vector3 at = new Vector3(0, -g, 0); at += Force * Mathf.Abs(Mathf.Sin(10 * timer * Mathf.Deg2Rad)); if (timer >= 360.0f) { timer -= 360.0f; } Vector3 nextPos = hairNode.curPos + D * (hairNode.curPos - hairNode.prePos) + at * Mathf.Pow(deltaT, 2); hairNode.prePos = hairNode.curPos; hairNode.curPos = nextPos; }
void Update() { // Profiler.BeginSample("verlet"); // iterate the hairNodes to update their Verlet parameters foreach (GameObject go in hairNodes) { HairNode script = go.GetComponent <HairNode>(); script.VerletMove(Time.deltaTime); } // fix the Verlet line length constraints int c = iterations; while (c-- > 0) { ConstrainLines(); } foreach (GameObject go in hairNodes) { HairNode script = go.GetComponent <HairNode>(); script.VerletConstrainHead(); } Vector3 prior = transform.position; foreach (GameObject go in hairNodes) { HairNode script = go.GetComponent <HairNode>(); if (prior != null) { script.VerletConnect(prior); } prior = go.transform.position; } // Profiler.EndSample(); }
void Start() { Hair = this.GetComponent <Transform>(); Head = GameObject.FindGameObjectWithTag("Head").GetComponent <Transform>(); hairNodes = new List <HairNode>(); for (int i = 0; i < transform.childCount; i++) { HairNode hairNode = new HairNode(); hairNode.pointTrans = transform.GetChild(i); hairNode.curPos = transform.GetChild(i).position; hairNode.prePos = transform.GetChild(i).position; hairNodes.Add(hairNode); } rootPos = hairNodes[0].curPos; selfLinerender = this.GetComponent <LineRenderer>(); //Debug.Log(hairNodes.Count); for (int i = 0; i < hairNodes.Count; i++) { selfLinerender.SetPosition(i, hairNodes[i].curPos); } //Debug.Log(selfLinerender.positionCount); }