//Breaks the rope at hinge with specified Segment public void BreakAt( RopeSegment segment){ if( !Broken ){ //Add rope end to previous segment int prev = segment.index - 1; //handle case when player slices the first/Last segment if ( prev < 0) prev = 0; Transform prevT = segments[prev].transform; GameObject breakEnd = new GameObject("RopeEnd"); breakEnd.transform.parent = prevT; breakEnd.transform.localPosition = new Vector3(0, - ROPE_END_OFFSET, 0); //Resize number of segments numActiveSegments = prev + 1; this.RopeEnd = breakEnd.transform; SetLineRenderer(); //release the goat Goat.ReleaseGoat(); Broken = true; } }
public void ModifyTrailBetweenPlayerAndThrowable() { foreach (Transform child in ropeContainer) { Destroy(child.gameObject); } float direction = GameManager.vectorToAngle(this.transform.position - Thrower.transform.position) - 90; Vector2 rope_pos = Thrower.transform.position; float distance = Vector2.Distance(this.transform.position, Thrower.transform.position); ropes.Clear(); for (float i = 0; i <= distance; i += 0.1f) { rope_pos = Vector2.Lerp(Thrower.transform.position, transform.position, i / distance); GameObject ropeobject = Instantiate(ropeSegment_prefab, rope_pos, Quaternion.Euler(0, 0, direction)) as GameObject; ropeobject.transform.parent = ropeContainer; RopeSegment ropesegment = ropeobject.GetComponent <RopeSegment> (); ropesegment.SqrDistanceFromStart = Mathf.Pow(i, 2); ropes.Add(ropesegment); } }
void SimulateRope() { Vector3 gravity = new Vector2(0, -ropeGravity); //Simulation for (int i = 0; i < ropeLength; i++) { RopeSegment firstSegment = ropeSegments[i]; Vector3 velocity = firstSegment.currentPos - firstSegment.prevPos; firstSegment.prevPos = firstSegment.currentPos; firstSegment.currentPos += velocity + (gravity * Time.deltaTime); ropeSegments[i] = firstSegment; } //Constraints if (!firstTime) { for (int i = 0; i < 20; i++) { ApplyConstraints(); } } else { for (int i = 0; i < 200; i++) { ApplyConstraints(); } firstTime = true; } }
// Simulate functions private void Simulate() { // Abort if no rope if (ropeSegments.Count > 0) { // Forced gravity Vector2 forceGravity = new Vector2(0f, -1f); // Simulate each rope segment for (int i = 0; i < subdivideAmount; i++) { RopeSegment segment = ropeSegments[i]; Vector2 velocity = segment.posNow - segment.posOld; segment.posOld = segment.posNow; segment.posNow += velocity; segment.posNow += forceGravity * Time.deltaTime; ropeSegments[i] = segment; } // Constrain the points for (int i = 0; i < constraintIterations; i++) { ApplyConstraints(); } } }
public void SplitSegment(RopeSegment toSplit, Vector2 pivotPoint, Vector2 pivotPointNormal) { // get distance from pivot point to start and end positions; float distToStart = (pivotPoint - toSplit.startPosition).magnitude; float distToEnd = (pivotPoint - toSplit.endPosition).magnitude; if (distToStart < 0.5f || distToEnd < 0.5f) // don't split if it will create tiny segments. { return; } if (ropeSegments.Count > 32) { return; } RopeSegment newSegment = CreateRopeSegment(); newSegment.splitBarrier = true; toSplit.splitBarrier = true; Vector2 oldEndPosition = toSplit.endPosition; toSplit.SetRopeSegment(toSplit.startPosition, pivotPoint); toSplit.attachmentNormalEnd = pivotPointNormal; toSplit.isAttachmentPointEnd = true; newSegment.SetRopeSegment(pivotPoint, oldEndPosition); newSegment.attachmentNormalStart = pivotPointNormal; newSegment.isAttachmentPointStart = true; InsertSegmentAt(newSegment, toSplit.segmentNumber + 1); newSegment.splitBarrier = false; toSplit.splitBarrier = false; }
private void AddComponents(List <GameObject> objects) { for (int i = 0; i < objects.Count; i++) { Rigidbody rgbd; rgbd = objects[i].AddComponent <Rigidbody>(); rgbd.drag = segmentDrag; rgbd.mass = segmentMass; } objects[0].GetComponent <Rigidbody>().isKinematic = true; objects[0].transform.parent = starPos; objects[objects.Count - 1].GetComponent <Rigidbody>().isKinematic = true; objects[objects.Count - 1].transform.parent = endPos; for (int i = 0; i < objects.Count - 1; i++) { GameObject item = objects[i]; SpringJoint spring = item.AddComponent <SpringJoint>(); spring.connectedBody = objects[i + 1].GetComponent <Rigidbody>(); spring.spring = springS; spring.damper = damperS; spring.minDistance = minDistanceS; spring.maxDistance = maxDistanceS; RopeSegment segmentModel = item.AddComponent <RopeSegment>(); segmentModel.start = item.transform; segmentModel.end = objects[i + 1].transform; segmentModel.width = ropeWidth; segmentModel.parent = gameObject; segmentModel.material = ropeMaterial; segmentModel.CustomStart(); } }
//Verlet integration moves each point in the line based on how far it moved in the previous frame (simulating inertia) // other forces are also added such as gravity void Simulate() { //SIMULATION Vector2 g = new Vector2(0, _gravity); for (int i = 0; i < _segments.Count; i++) { RopeSegment seg = _segments[i]; Vector2 d = seg.currPos - seg.prevPos; seg.prevPos = seg.currPos; seg.currPos += d; //inertia seg.currPos += g * Time.deltaTime; //gravity //Changes to the struct "seg" are not saved in the List so the updated value needs to be // passed back in to the List _segments[i] = seg; } //ApplyCollisionConstraints(); /*CONSTRAINTS*/ for (int i = 0; i < _precision; i++) { ApplyConstraints(); } _contacts = null; }
public void Slide(int direction) { RopeSegment myConnection = hj.connectedBody.gameObject.GetComponent <RopeSegment>(); GameObject newSeg = null; if (direction > 0) { if (myConnection.connectedAbove != null) { if (myConnection.connectedAbove.gameObject.GetComponent <RopeSegment>() != null) { newSeg = myConnection.connectedAbove; } } } else { if (myConnection.connectedBelow != null) { newSeg = myConnection.connectedBelow; } } if (newSeg != null) { transform.position = newSeg.transform.position; myConnection.isPlayerAttached = false; newSeg.GetComponent <RopeSegment>().isPlayerAttached = true; hj.connectedBody = newSeg.GetComponent <Rigidbody2D>(); } }
private void ApplyCollisionConstraints() { if (_contacts == null) { return; } if (_contacts.Length <= 0) { return; } foreach (ContactPoint2D contact in _contacts) { int i = GetNearestSegment(contact.point); RopeSegment currSeg = _segments[i]; Vector2 correction = contact.normal * (contact.normalImpulse * _impulseFactor); currSeg.currPos += correction; currSeg.prevPos = currSeg.currPos; _segments[i] = currSeg; } //_contacts = null; }
void Attach(RopeSegment rope) { hips.transform.position = rope.transform.position; hipsJoint = hips.gameObject.AddComponent <CharacterJoint> (); hipsJoint.connectedBody = rope.rb; grabbedSegment = rope; }
private void Simulate() { var strength = ClampStrength; // SIMULATION for (int i = 1; i < this.segmentLength; i++) { RopeSegment firstSegment = this.ropeSegments[i]; Vector2 velocity = firstSegment.posNow - firstSegment.posOld; firstSegment.posOld = firstSegment.posNow; firstSegment.posNow += velocity; firstSegment.posNow += (forceGravity / this.segmentLength * i * GravityIncrementMultiplier) * Time.fixedDeltaTime; // Clamp to wire rack var ystart = StartPoint.position.y + ClampedToY; //if ( CLAMP_BOTTOM && firstSegment.posNow.y < ystart ) if (CLAMP_BOTTOM && i <= ClampCount) { firstSegment.posNow.x = Mathf.Lerp(firstSegment.posNow.x, StartPoint.position.x, Time.deltaTime * strength); firstSegment.posNow.y = Mathf.Lerp(firstSegment.posNow.y, ystart, Time.deltaTime * strength); strength /= ClampDecay; } this.ropeSegments[i] = firstSegment; } //CONSTRAINTS for (int i = 0; i < constraintIterations; i++) { this.ApplyConstraint(); } }
private void ApplyConstraint() { //Constrant to First Point RopeSegment firstSegment = this.ropeSegments[0]; firstSegment.posNow = this.StartPoint.position; this.ropeSegments[0] = firstSegment; //Constrant to Second Point RopeSegment endSegment = this.ropeSegments[this.ropeSegments.Count - 1]; endSegment.posNow = this.EndPoint.position; this.ropeSegments[this.ropeSegments.Count - 1] = endSegment; for (int i = 0; i < this.segmentLength - 1; i++) { RopeSegment firstSeg = this.ropeSegments[i]; RopeSegment secondSeg = this.ropeSegments[i + 1]; float dist = (firstSeg.posNow - secondSeg.posNow).magnitude; float error = Mathf.Abs(dist - this.ropeSegLen); Vector3 changeDir = Vector3.zero; if (dist > ropeSegLen) { changeDir = (firstSeg.posNow - secondSeg.posNow).normalized; } else if (dist < ropeSegLen) { changeDir = (secondSeg.posNow - firstSeg.posNow).normalized; } Vector3 changeAmount = changeDir * error; changeAmount2 = new Vector3(0, changeAmount.x / 2.5f, changeAmount.z * -1.3f); if (i != 0) { firstSeg.posNow -= changeAmount * 0.5f; this.ropeSegments[i] = firstSeg; secondSeg.posNow += changeAmount * 0.5f; this.ropeSegments[i + 1] = secondSeg; } else { secondSeg.posNow += changeAmount; this.ropeSegments[i + 1] = secondSeg; } if (this.moveToMouse && indexMousePos > 0 && indexMousePos < this.segmentLength - 1 && i == indexMousePos) { RopeSegment segment = this.ropeSegments[i]; RopeSegment segment2 = this.ropeSegments[i + 1]; segment.posNow = new Vector3(this.mousePositionWorld.x, this.mousePositionWorld.y, this.mousePositionWorld.z); segment2.posNow = new Vector3(this.mousePositionWorld.x, this.mousePositionWorld.y, this.mousePositionWorld.z); this.ropeSegments[i] = segment; this.ropeSegments[i + 1] = segment2; } } }
protected void InsertSegmentAt(RopeSegment segment, int location) { ropeSegments.Insert(location, segment); for (int i = 0; i < ropeSegments.Count; ++i) { ropeSegments[i].segmentNumber = i; // renumber all the segments so that they match the list. } }
public List <RopeSegment> DeepCopyRopes(List <RopeSegment> ropes) { return(ropes.Select(r => { RopeSegment nr = Instantiate(r); nr.SqrDistanceFromStart = r.SqrDistanceFromStart; return nr; }).ToList()); }
private void OnTriggerEnter(Collider other) { RopeSegment segment = other.GetComponent <RopeSegment> (); if (segment != null) { ropeswingController.Grab(segment); } }
void RemoveSegment(int segmentNumber, bool direction) { if (segmentNumber >= 0 && segmentNumber < ropeSegments.Count) { RopeSegment thisSegment = ropeSegments[segmentNumber]; thisSegment.splitBarrier = true; if (direction) { // start with prevSegment if (segmentNumber > 0) { RopeSegment prevSegment = ropeSegments[segmentNumber - 1]; prevSegment.splitBarrier = true; prevSegment.SetRopeSegment(prevSegment.startPosition, thisSegment.endPosition); prevSegment.isAttachmentPointEnd = thisSegment.isAttachmentPointEnd; prevSegment.attachmentNormalEnd = thisSegment.attachmentNormalEnd; prevSegment.splitBarrier = false; } } else { // pair with next // start with prevSegment Assert.IsTrue(segmentNumber < ropeSegments.Count - 1); if (segmentNumber < ropeSegments.Count - 1) { RopeSegment nextSegment = ropeSegments[segmentNumber + 1]; nextSegment.splitBarrier = true; nextSegment.SetRopeSegment(thisSegment.startPosition, nextSegment.endPosition); nextSegment.isAttachmentPointStart = thisSegment.isAttachmentPointStart; nextSegment.attachmentNormalStart = thisSegment.attachmentNormalStart; nextSegment.splitBarrier = false; } } /*if (segmentNumber < ropeSegments.Count-1) * { * RopeSegment nextSegment = ropeSegments[segmentNumber + 1]; * * nextSegment.splitBarrier = true; * * nextSegment.SetRopeSegment(thisSegment.startPosition, nextSegment.endPosition); * nextSegment.isAttachmentPointStart = thisSegment.isAttachmentPointStart; * nextSegment.attachmentNormalStart = thisSegment.attachmentNormalStart; * * nextSegment.splitBarrier = false; * }*/ RemoveSegmentAt(segmentNumber); } }
private void PushSegment(RopeSegment ropeSegment) { var firstSegment = _ropeSegments[0]; firstSegment.SetConnectedBody(ropeSegment.body); ropeSegment.SetConnectedBody(_body); AddFirst(ropeSegment); }
protected void RemoveSegment(RopeSegment segment) { Destroy(segment.gameObject); ropeSegments.Remove(segment); for (int i = 0; i < ropeSegments.Count; ++i) { ropeSegments[i].segmentNumber = i; // renumber all the segments so that they match the list. } }
void OnRopegrab(RopeSegment rope) { if (rope != null) { stateMachine.ChangeState("Ropeswing"); ragdoll.ApplyVelocityToBones(motor.Velocity); motor.Zero(); } }
private void ApplyConstraint() { /* * //Constrant to Mouse * RopeSegment firstSegment = this.ropeSegments[0]; * firstSegment.posNow = RopeHangPoint.transform.position; * this.ropeSegments[0] = firstSegment; */ RopeSegment firstSegment = this.ropeSegments[0]; firstSegment.posNow = startPos.position; this.ropeSegments[0] = firstSegment; if (!endSegLock) { RopeSegment lastSegment = this.ropeSegments[segmentLength - 1]; lastSegment.posNow = endPos.position; this.ropeSegments[segmentLength - 1] = lastSegment; } for (int i = 0; i < this.segmentLength - 1; i++) { RopeSegment firstSeg = this.ropeSegments[i]; RopeSegment secondSeg = this.ropeSegments[i + 1]; float dist = (firstSeg.posNow - secondSeg.posNow).magnitude; float error = Mathf.Abs(dist - this.ropeSegLen); Vector3 changeDir = Vector3.zero; if (dist > ropeSegLen) { changeDir = (firstSeg.posNow - secondSeg.posNow).normalized; } else if (dist < ropeSegLen) { changeDir = (secondSeg.posNow - firstSeg.posNow).normalized; } Vector3 changeAmount = changeDir * error; if (i != 0) { firstSeg.posNow -= changeAmount * 0.5f; secondSeg.posNow += changeAmount * 0.5f; this.ropeSegments[i] = firstSeg; this.ropeSegments[i + 1] = secondSeg; } else { secondSeg.posNow += changeAmount; this.ropeSegments[i + 1] = secondSeg; } } }
/* * Rope Segment Operations */ protected void SetupRope() { DestroyRope(); // Get rid of the old rope ropeSegments = new List <RopeSegment>(); RopeSegment segment = CreateRopeSegment(); InsertSegmentAt(segment, 0); }
public void Execute(int index) { float2 gravity = new float2(0, -1); RopeSegment segment = segments[index]; float2 velocity = segment.posNow - segment.posOld; segment.posOld = segment.posNow; segment.posNow += velocity; segment.posNow += gravity * fixedDeltaTime; segments[index] = segment; }
protected void RemoveSegmentAt(int location) { RopeSegment ropeSegment = ropeSegments[location]; ropeSegments.RemoveAt(location); for (int i = 0; i < ropeSegments.Count; ++i) { ropeSegments[i].segmentNumber = i; // renumber all the segments so that they match the list. } Destroy(ropeSegment.gameObject); }
private void AttachRope(GameObject start, GameObject end) { // Attach endpoint RopeSegment firstSeg = ropeSegments[0]; firstSeg.posNow = end.transform.position; // Attach start point RopeSegment lastSeg = ropeSegments[ropeSegments.Count - 1]; lastSeg.posNow = start.transform.position; }
protected RopeSegment CreateRopeSegment() { Transform go = Instantiate(RopeSegmentPrefab, transform); RopeSegment newSegment = go.GetComponent <RopeSegment>(); Assert.IsNotNull(newSegment); newSegment.rope = this; return(newSegment); }
private void ApplyConstraint() { RopeSegment firstSegment = this.ropeSegments[0]; firstSegment.posNow = fishingRodPivot.transform.position; this.ropeSegments[0] = firstSegment; if (isGrabbing) { this.ropeSegLen = (firstSegment.posNow - grabPosition).magnitude / segmentLength; } for (int i = 0; i < this.segmentLength - 1; i++) { RopeSegment firstSeg = this.ropeSegments[i]; RopeSegment secondSeg = this.ropeSegments[i + 1]; float dist = (firstSeg.posNow - secondSeg.posNow).magnitude; float error = Mathf.Abs(dist - this.ropeSegLen); Vector2 changeDir = Vector2.zero; if (dist > ropeSegLen) { changeDir = (firstSeg.posNow - secondSeg.posNow).normalized; } else if (dist < ropeSegLen) { changeDir = (secondSeg.posNow - firstSeg.posNow).normalized; } Vector2 changeAmount = changeDir * error; if (i != 0) { firstSeg.posNow -= changeAmount * 0.5f; this.ropeSegments[i] = firstSeg; secondSeg.posNow += changeAmount * 0.5f; this.ropeSegments[i + 1] = secondSeg; } else { secondSeg.posNow += changeAmount; this.ropeSegments[i + 1] = secondSeg; } } if (isGrabbing) { RopeSegment lastSegment = ropeSegments[segmentLength - 1]; lastSegment.posNow = grabPosition; this.ropeSegments[segmentLength - 1] = lastSegment; } }
// Use this for initialization void Awake() { lineRenderer = GetComponent <LineRenderer>(); Vector3 ropePoint = transform.position; ropeSegments = new NativeArray <RopeSegment>(segments, Allocator.Persistent); for (int i = 0; i < segments; i++) { ropeSegments[i] = new RopeSegment(ropePoint); ropePoint.y -= segmentLength; } ropePositions = new Vector3[segments]; }
private void ApplyConstraint() { //Tests with Mouse position //RopeSegment firstSegment = this.ropeSegments[0]; //firstSegment.posNow = Camera.main.ScreenToWorldPoint(Input.mousePosition); //this.ropeSegments[0] = firstSegment; RopeSegment firstSegment = this.ropeSegments[0]; firstSegment.posNow = this.startPoint.position; this.ropeSegments[0] = firstSegment; RopeSegment endSegment = this.ropeSegments[this.segmentLength - 1]; endSegment.posNow = this.endPoint.position; this.ropeSegments[this.segmentLength - 1] = endSegment; for (int i = 0; i < this.segmentLength - 1; i++) { RopeSegment firstSeg = this.ropeSegments[i]; RopeSegment secondSeg = this.ropeSegments[i + 1]; float dist = (firstSeg.posNow - secondSeg.posNow).magnitude; float error = Mathf.Abs(dist - this.ropeSegLen); Vector2 changeDir = Vector2.zero; if (dist > ropeSegLen) { changeDir = (firstSeg.posNow - secondSeg.posNow).normalized; } else if (dist < ropeSegLen) { changeDir = (secondSeg.posNow - firstSeg.posNow).normalized; } Vector2 changeAmount = changeDir * error; if (i != 0) { firstSeg.posNow -= changeAmount * 0.5f; this.ropeSegments[i] = firstSeg; secondSeg.posNow += changeAmount * 0.5f; this.ropeSegments[i + 1] = secondSeg; } else { secondSeg.posNow += changeAmount; this.ropeSegments[i + 1] = secondSeg; } } }
void ApplyConstraints() { RopeSegment firstSegment = ropeSegments[0]; RopeSegment endSegment = ropeSegments[segmentLength - 1]; //follow mouse firstSegment.currPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); //follow points if (!usingMouse) { firstSegment.currPos = firstPoint.position; endSegment.currPos = secondPoint.position; ropeSegments[segmentLength - 1] = endSegment; } ropeSegments[0] = firstSegment; for (int i = 0; i < this.segmentLength - 1; i++) { RopeSegment firstSeg = this.ropeSegments[i]; RopeSegment secondSeg = this.ropeSegments[i + 1]; float dist = (firstSeg.currPos - secondSeg.currPos).magnitude; float error = Mathf.Abs(dist - this.ropeSegmentLen); Vector2 changeDir = Vector2.zero; if (dist > ropeSegmentLen) { changeDir = (firstSeg.currPos - secondSeg.currPos).normalized; } else if (dist < ropeSegmentLen) { changeDir = (secondSeg.currPos - firstSeg.currPos).normalized; } Vector2 changeAmount = changeDir * error; if (i != 0) { firstSeg.currPos -= changeAmount * 0.5f; this.ropeSegments[i] = firstSeg; secondSeg.currPos += changeAmount * 0.5f; this.ropeSegments[i + 1] = secondSeg; } else { secondSeg.currPos += changeAmount; this.ropeSegments[i + 1] = secondSeg; } } }
private void ApplyConstraint() { //constrant between start to end, this is start RopeSegment firstSegment = this.ropeSegments[0]; firstSegment.posNow = this.lineStartPoint.position; this.ropeSegments[0] = firstSegment; //this is end constraint RopeSegment endSegment = this.ropeSegments[segmentLength - 1]; endSegment.posNow = this.lineEndPoint.position; this.ropeSegments[segmentLength - 1] = endSegment; ////////////////////////////////////////// Vector3 distance = endSegment- firstSegment for (int i = 0; i < this.segmentLength - 1; i++) { RopeSegment firstSeg = this.ropeSegments[i]; RopeSegment secondSeg = this.ropeSegments[i + 1]; float dist = (firstSeg.posNow - secondSeg.posNow).magnitude; float error = Mathf.Abs(dist - this.ropeSegLen); Vector2 changeDir = Vector2.zero; if (dist > ropeSegLen) { changeDir = (firstSeg.posNow - secondSeg.posNow).normalized; } else if (dist < ropeSegLen) { changeDir = (secondSeg.posNow - firstSeg.posNow).normalized; } Vector2 changeAmount = changeDir * error; if (i != 0) { firstSeg.posNow -= changeAmount * 0.5f; this.ropeSegments[i] = firstSeg; secondSeg.posNow += changeAmount * 0.5f; this.ropeSegments[i + 1] = secondSeg; } else { secondSeg.posNow += changeAmount; this.ropeSegments[i + 1] = secondSeg; } } }
private void ApplyConstraint() { //Constrant to Mouse RopeSegment firstSegment = this.ropeSegments[0]; GameObject primaryBlob = blobController.primaryBlob; firstSegment.posNow = new Vector2(primaryBlob.transform.position.x, primaryBlob.transform.position.y); RopeSegment lastSegment = this.ropeSegments[segmentLength - 1]; lastSegment.posNow = Camera.main.ScreenToWorldPoint(Input.mousePosition); //changed this from 0 to segmentLength - 1 //this should be going from ropeSegments[0] at the transform.position to whatever this ends up. mousePosition? this.ropeSegments[segmentLength - 1] = firstSegment; for (int i = 0; i < this.segmentLength - 1; i++) { RopeSegment firstSeg = this.ropeSegments[i]; RopeSegment secondSeg = this.ropeSegments[i + 1]; float dist = (firstSeg.posNow - secondSeg.posNow).magnitude; float error = Mathf.Abs(dist - this.ropeSegLen); Vector2 changeDir = Vector2.zero; if (dist > ropeSegLen) { changeDir = (firstSeg.posNow - secondSeg.posNow).normalized; } else if (dist < ropeSegLen) { changeDir = (secondSeg.posNow - firstSeg.posNow).normalized; } Vector2 changeAmount = changeDir * error; if (i != 0) { firstSeg.posNow -= changeAmount * 0.5f; this.ropeSegments[i] = firstSeg; secondSeg.posNow += changeAmount * 0.5f; this.ropeSegments[i + 1] = secondSeg; } else { secondSeg.posNow += changeAmount; this.ropeSegments[i + 1] = secondSeg; } } }