Hi guys,
I’m quite new to Unity so I could need some advice. I have imported the human model called “carl” from the Asset Store. It has got the following joint hierarchy:
-
carl
-
Hips
-
LeftUpLeg
-
RightUpLeg
-
Spine
-
Spine1
-
Spine2
-
LeftShoulder
-
LeftArm
-
Neck
-
RightShoulder
-
RightArm
I wrote some piece of code that moves the joints of the model - represented as Transforms - sequentially.
/*
* Perform some example movements
*/
SequencedMotion s1,s2,s3;
Motion neckRotation = new Motion(Joints.Neck, Sides.Left, MotionTypes.Rotation);
// (motion, starting time, duration, start angle, end angle)
s1 = new SequencedMotion(neckRotation, 0, 3, 0, 80);
sequencer.Add(s1);
Motion armAbduction = new Motion(Joints.Shoulder, Sides.Left, MotionTypes.Abduction);
s2 = new SequencedMotion(armAbduction, 1, 2, 90, 180);
sequencer.Add(s2);
What the sequencer basically does is updating the joints depending on the time that has passed.
/**
* Updates the state of the motions that were added to the sequencer
*/
public void Update() {
float time = Time.time;
foreach(SequencedMotion m in motions) {
if(time >= m.GetTimeStart()) {
adjustPosition (m.GetMotion(), m.GetCurrentPosition(time));
}
}
}
private void adjustPosition(Motion m, float position) {
// Neck
if(m.GetJoint().Equals(Joints.Neck)) {
if(m.GetMotionType().Equals(MotionTypes.Rotation)) {
lm.AbsNeckRotation(position, m.GetSide());
}
// Shoulder
} else if(m.GetJoint().Equals(Joints.Shoulder)) {
if(m.GetMotionType().Equals(MotionTypes.Abduction)) {
lm.AbsShoulderAbduction(position, m.GetSide());
}
}
}
What now happens is that the neck joint moves properly but when the arm starts moving after a second the arm does not only move in the direction it is supposed to but also performs the rotation that was originally assigned to the neck. I found on Google that you should be aware that Transforms are also performed on children of Transforms but in this case there should not be any parent-child-relationships:
neck = root.FindChild("Hips/Spine/Spine1/Spine2/Neck");
lShoulder = root.FindChild("Hips/Spine/Spine1/Spine2/LeftShoulder/LeftArm");
rShoulder = root.FindChild("Hips/Spine/Spine1/Spine2/RightShoulder/RightArm");
The manipulation of the joints is implemented by altering the euler angles:
public void AbsNeckRotation(float degrees, Sides direction) {
int rotationFactor = -1;
if(direction.Equals(Sides.Right)) {
rotationFactor = 1;
}
Vector3 newEulerAngles = new Vector3(
neck.eulerAngles.x,
rotationFactor*degrees,
neck.eulerAngles.z
);
neck.eulerAngles = newEulerAngles;
}
public void AbsShoulderAbduction(float degrees, Sides side) {
// Move left side by default
Transform shoulder = lShoulder;
int rotationFactor = -1;
if(side.Equals(Sides.Right)) {
shoulder = rShoulder;
rotationFactor = 1;
}
// Why does this even work? There should be a much easier solution.
Vector3 newEulerAngles = new Vector3(
neck.eulerAngles.x,
neck.eulerAngles.y,
Add360(neck.eulerAngles.z-rotationFactor*90, rotationFactor*degrees)
);
shoulder.eulerAngles = newEulerAngles;
}
Does anyone have a clue how this behaviour is possible? I am quite lost
Thank you!