I am creating a molecule by combining two sphere game objects and spawning a cylinder game object between them when they collide to form a molecule game object.
Now what I want to do is to grab an atom from the molecule so that it get detached from the molecule .
For this I am using onGraspEvents provided with the Leap Motion unity packages. Sometimes when I grab the one of the atom using hands, then molecule kind of explodes and all the child game objects get scattered in the scene but they again form the molecule at some different place properly.
This explosion kind of thing doesn't show any error or anything else in console so I think this is not a bug in the sdk. However what I suspect is it is something related to Physics model or with the weight of the hands which puts huge force on the molecule object so that it breaks.
Here is my code for Grasp events and way I am creating molecule.
private void OnAtomGrasped()
{
grasppedAtoms.Add(_interactionBehaviour.gameObject);
Debug.Log("Grasp begin");
// as soon as we have two atoms graspped we need to change the force so we can break it
if(grasppedAtoms.Count == 2)
{
// check if they belong to same molecule
if (grasppedAtoms.ElementAt(0).transform.parent && grasppedAtoms.ElementAt(1).transform.parent &&
grasppedAtoms.ElementAt(0).transform.parent.gameObject == grasppedAtoms.ElementAt(1).transform.parent.gameObject &&
grasppedAtoms.ElementAt(0).transform.parent.gameObject.name.Contains("Molecule"))
{
// ideally we want to find a route of this atom to other atom and then apply break force to the joints that connect this atom
// for eg: if we have A->B->C->D && B->E->F (think of it as a graph), then if user is pulling A & D, we will find a route from A to D and the apply break force to A's immediate joints and D's immediate joints
var atom1 = grasppedAtoms.ElementAt(0).GetComponent<Atom>();
atom1.joint.breakForce = breakForce;
var atom2 = grasppedAtoms.ElementAt(1).GetComponent<Atom>();
atom2.joint.breakForce = breakForce;
_interactionBehaviour.moveObjectWhenGrasped = false;
}
}
}
Grasp End method
private void OnAtomReleased()
{
Debug.Log("Grasp released");
if (grasppedAtoms.Count == 2)
{
// revert back the force, so molecule can't be broken
// check if they belong to same molecule
if (grasppedAtoms.ElementAt(0).transform.parent && grasppedAtoms.ElementAt(1).transform.parent &&
grasppedAtoms.ElementAt(0).transform.parent.gameObject == grasppedAtoms.ElementAt(1).transform.parent.gameObject &&
grasppedAtoms.ElementAt(0).transform.parent.gameObject.name.Contains("Molecule"))
{
var atom1 = grasppedAtoms.ElementAt(0).GetComponent<Atom>();
atom1.joint.breakForce = Mathf.Infinity;
var atom2 = grasppedAtoms.ElementAt(1).GetComponent<Atom>();
atom2.joint.breakForce = Mathf.Infinity;
}
}
grasppedAtoms.Remove(_interactionBehaviour.gameObject);
}
Forming molecule
private IEnumerator SetAtomPosition(Transform atomOne, Transform atomTwo, Transform cylinder)
{
while (Vector3.Distance(atomOne.position, atomTwo.position) > atomDistance)
{
atomTwo.position = Vector3.MoveTowards(atomTwo.position, atomOne.position, Time.deltaTime * 0.1f);
yield return 0;
}
while (Vector3.Distance(atomOne.position, atomTwo.position) < atomDistance)
{
atomTwo.position = Vector3.MoveTowards(atomTwo.position, -atomTwo.forward * 1000f, Time.deltaTime * 0.1f);
yield return 0;
}
cylinder.transform.position = (atomTwo.position - atomOne.position) / 2.0f + atomOne.position;
cylinder.transform.rotation = Quaternion.FromToRotation(Vector3.up, atomTwo.transform.position - atomOne.transform.position);
#region JoinAtoms
cylinder.gameObject.AddComponent<FixedJoint>();
cylinder.gameObject.AddComponent<FixedJoint>();
var cylinderJoints = cylinder.GetComponents<FixedJoint>();
cylinderJoints[0].connectedBody = atomOne.GetComponent<Rigidbody>();
// cylinderJoints[0].breakForce = 500f;
atomOne.GetComponent<Atom>().joint = cylinderJoints[0];
//cylinderJoints[0].breakForce = breakForce;
cylinderJoints[1].connectedBody = atomTwo.GetComponent<Rigidbody>();
// cylinderJoints[1].breakForce = 500f;
atomTwo.GetComponent<Atom>().joint = cylinderJoints[1];
KinematicToggle(cylinder.gameObject);
cylinder.GetComponent<Rigidbody>().mass = 10f;
#endregion
yield return null;
}
P.S. Cylinder are joined using fixed joints with atom game object
Any help will be appreciated