Hello,
I had posted a topic earlier on this form about how to make it so that I can make something like a hand from a character move to a specific vector spot in world space, and make all the other connecting limbs from that character re-attach themselves accordingly so that no limbs would stretch outside the proper boundaries of that character.
I was told that it was called “inverse kinematics” and that it can’t be done in Unity without a high cost, so I developed a script of my own that does exactly what I wanted. I place my script on the parent of the hip and when ran, the scripts then automatically duplicate themselves onto the children, then the grand children, etc. all the way up to the ‘leaves’ of each objects.
Where I originally put my scripts, I have 3 reference variables I need to set, (LimbObj, StopObj and GoalObj). LimbObj is the part I want to move (like the right hand). StopObj is where the connections stop (if I am using the right hand, the stop object should be the right shoulder so that the abdomen, hips, neck and head along the upper hierarchy don’t also move along with the shoulder). GoalObj is where the limb tries their best to meet up with the goal object’s position. If it is not within reach, the limbs stretch as close as they can to the object. If within reach, the other limbs will bend in a way so that the limb object’s position will approximately equal the goal object’s position in world space.
Here is the code I’ve written so far. How would I publish it so that I can be the author and get good references so I can get my foot in the door in this economy we’re in with no work experience and minimal education in the computer field?
class ik extends MonoBehaviour {
public var posArray;
public var rotArray;
public var posDiff;
public var rotDiff;
public var pRoot;
public static var pLimbObj;
public static var pStopObj;
public static var pGoalObj;
}
var LimbObj : Transform;
var StopObj : Transform;
var GoalObj : Transform;
function Start () {
posArray = Array();
posArray.clear();
rotArray = Array();
rotArray.clear();
for (var child : Transform in transform) {
dist = getDistance(transform.position.x, transform.position.y, transform.position.z, child.position.x, child.position.y, child.position.z);
posArray.Add(dist);
rot = child.localEulerAngles;
child.LookAt(transform.position);
rotArray.Add(child.localEulerAngles);
child.localEulerAngles = rot;
}
if (transform.parent != null) {
rot1 = transform.parent.eulerAngles;
transform.parent.LookAt(transform.position);
rot2 = transform.parent.eulerAngles;
transform.parent.eulerAngles = rot1;
rotDiff = rot2 - rot1;
posDiff = getDistance(transform.parent.position.x,transform.parent.position.y,transform.parent.position.z,transform.position.x,transform.position.y,transform.position.z);
} else {
rotDiff = 0;
posDiff = 0;
}
if (transform.parent == null) {
pRoot = transform;
pStopObj = StopObj;
} else {
if (transform.parent.GetComponent(“ik”) == null) {
pRoot = transform;
pStopObj = StopObj;
pGoalObj = GoalObj;
pLimbObj = LimbObj;
}
}
for (var child : Transform in transform) {
if (child.gameObject.GetComponent(“ik”) == null) {
child.gameObject.AddComponent(“ik”);
child.gameObject.GetComponent(“ik”).pRoot = pRoot;
child.gameObject.GetComponent(“ik”).pStopObj = pStopObj;
child.gameObject.GetComponent(“ik”).pGoalObj = pGoalObj;
child.gameObject.GetComponent(“ik”).pLimbObj = pLimbObj;
}
}
}
function getDistance(x1, y1, z1, x2, y2, z2) {
return (Mathf.Sqrt((Mathf.Abs(x1-x2)*Mathf.Abs(x1-x2))+(Mathf.Abs(y1-y2)*Mathf.Abs(y1-y2))+(Mathf.Abs(z1-z2)*Mathf.Abs(z1-z2))));
}
function Update () {
i = 0;
var t : Transform;
for (var child : Transform in transform) {
if (child.gameObject.GetComponent(“ik”) != null) {
child.position.x = transform.position.x;
child.position.y = transform.position.y;
child.position.z = transform.position.z;
ang = child.localEulerAngles;
child.localEulerAngles = rotArray*;*
_ child.Translate(Vector3(0, 0, -posArray*));_
_ if (child.name == pLimbObj.name) {_
_ t = child;_
_ while (t.parent != null t.name != pRoot.name t.name != pStopObj.name) {_
_ if (t.name != pRoot.name t.name != pStopObj.name) {_
_ if (t.GetComponent(“ik”).rotDiff != null) {_
_ t.LookAt(pGoalObj.position);_
_ t.Rotate(-t.GetComponent(“ik”).rotDiff);_
_ }_
_ t = t.parent;_
_ }_
_ }_
_ } else {_
_ child.localEulerAngles = ang;_
_ }_
_ }_
_ i++;_
_}*_
}