- Home /
Create SpringJoint with specfic distance or ConfigurableJoint
I am creating a SpringJoint whenever there is a specific collision. This is all working well, but the SpringJoint is created with the initial length of the distance between the two rigidbodies (which is how it works according to the documentation).
However, the behavior I want is a SpringJoint that has 0 length (it will pull the objects together until they touch).
From what I can tell, there is no way to override the initial distance of the SpringJoint. If I could change the target distance to 0, that would be ideal. It seems though, that I will need to create a ConfigurableJoint instead, which is much more complicated than the SpringJoint.
So could you help me either: 1. Modify the SpringJoint's target distance to 0. 2. Create a ConfigurableJoint which will pull 2 objects together until they touch (like a spring with 0 length).
Thanks
I didn't get this to work, so I went a different route which turned out much easier: I created a new class SimpleJoint with a FixedUpdate method that manually calculates the forces and applies them to the rigidbodies. This was rather simple and much easier than trying to figure out the ConfigurableJoint which is largely undocumented.
Answer by djarcas · Jan 27, 2013 at 05:00 PM
A quick SimpleJoint function I knocked up:
Vector3 lTarg = rigidbody.transform.position
Vector3 lVec = lTarg - mAttachedObject.rigidbody.position;
mAttachedObject.rigidbody.AddForce(lVec * 15.0f);
15 is the force strength. It could do with dampening, etc, but it might well be useful for someone out there.
Hi There.
Please don't post comments as answers. Post comments by clicking the [add new comment] button, a window then open for you to type in. Answer fields are for answers only, as this is a knowledge base.
Here at Unity Answers, Answer means Solution, not Response.
You can convert this answer to a comment, you'll also get a better chance of getting an actual answer if the main list shows none or one answer in blue =]
Under the answer where it says edit | delete | more , click on more , then convert to comment
Also you don't have to wait for a moderator to approve a comment.
Answer by unity_ANdq1DQ_78jrEQ · Sep 11, 2018 at 12:56 PM
I've just had the same problem and noticed the anchor elements, which are configured automatically by default. It looks like they are both references to the owning element, and it seems to work a bit like a target length. Try turning off the default configuration, and then set the connectedAnchor to a vector length that you like, i.e. a short one.
j.autoConfigureConnectedAnchor = false;
j.connectedAnchor = new Vector3(0, 1, 0);
Answer by I5 · Sep 11, 2018 at 03:45 PM
I've burned through many hours trying to accomplish something similar, with no luck. One solution I got working pretty well (I'm trying to create a magnet effect) it to use a trigger collider that triggers calls in FixedUpdate to continually add force to a rigidbody to move it to where I want it to go, and when it gets to where I want it to go (as indicated by a collision) I then add a FixedJoint to the object I moved, attaching it to an object with a rigidbody. Here's code snippet (I've only pasted the two relevant methods to simply the solution, hopefully the rest of the code is easy to deduce).
private float inc = 0f;
void FixedUpdate() {
if (movingRB != null) {
if (boundM != null) {
movingRB = null;
return;
}
//Debug.LogError(gameObject.name + " magnet still binding " + movingRB.gameObject.name + " for " + secsBinding + " secs");
dist = Vector3.Distance(gameObject.transform.position, movingRB.gameObject.transform.position);
if(secsBinding > maxSecsToBind) {
secsBinding = 0f;
inc = 0f;
Debug.LogError(gameObject.name + " binding BROKEN to " + movingRB.gameObject.name + "::" + dist);
movingRB = null;
return;
}
moveInDirection = transform.position - movingRB.gameObject.transform.position;
inc += Time.deltaTime * attractSpeed;
movingRB.velocity = (moveInDirection * inc);
secsBinding += Time.fixedDeltaTime;
}
}
void OnCollisionEnter(Collision hit) {
Debug.LogError(gameObject.name + " hit by:" + hit.gameObject.name + ":" + enabled + ":" + hit.rigidbody);
if (!enabled || hit.rigidbody == null || boundM != null) return;
bool stickit = false;
for (int i = 0; i < hit.contacts.Length; i++) {
Debug.LogError("magnet part hit--->" + hit.contacts[i].thisCollider.gameObject.name);
if (hit.contacts[i].thisCollider != null && hit.contacts[i].thisCollider.GetInstanceID() == stickPoint.GetInstanceID()) {
stickit = true;
break;
}
}
if (!stickit) return;
I5Magnatizable m = hit.rigidbody.gameObject.GetComponent<I5Magnatizable>();
if (m == null || !m.isMagnatizable || (letGoOfM != null && letGoOfM.GetInstanceID() == m.GetInstanceID())) return;
if (movingRB == null) movingRB = hit.rigidbody;
if (hit.rigidbody.GetInstanceID() == movingRB.GetInstanceID()) {
if (m == null) m = hit.rigidbody.gameObject.GetComponent<I5Magnatizable>();
if (m == null) {
movingRB = null;
return;
}
boundM = m;
movingRB = null;
hit.rigidbody.velocity = Vector3.zero;
boundRBOrigMass = hit.rigidbody.mass;
hit.rigidbody.mass = 0.01f;//to prevent banging into player
//Debug.LogError("binding:" + hit.gameObject.name);
if (hit.rigidbody.gameObject.transform.parent != null) hit.rigidbody.gameObject.transform.SetParent(null);
FixedJoint fj = hit.rigidbody.gameObject.GetComponent<FixedJoint>();
if (fj == null) fj = hit.rigidbody.gameObject.AddComponent<FixedJoint>();
fj.connectedBody = myRB;
m.bindingMagnet = this;
inc = 0f;
secsBinding = 0f;
}
if (magnatizableConnectedListeners != null) magnatizableConnectedListeners(m);
Debug.LogError(gameObject.name + " magnet binding complete with " + hit.gameObject.name);
}