private IEnumerator KeyDownRoutine(IKTargets target, Vector3 targetPos) { bool isLeftHand = (target == IKTargets.LHand); IKDataRecord ikTarget = isLeftHand ? _leftHand : _rightHand; //NOTE: 第2項は手首を正面に向けるための前処理みたいなファクターです var keyboardRot = _keyboard.GetKeyboardRotation() * Quaternion.AngleAxis(isLeftHand ? 90 : -90, Vector3.up); var keyboardRootPos = _keyboard.transform.position; var keyboardUp = _keyboard.KeyboardUp; float startTime = Time.time; Vector3 startPos = ikTarget.Position; float startVertical = Vector3.Dot(startPos - keyboardRootPos, keyboardUp); float targetVertical = Vector3.Dot(targetPos - keyboardRootPos, keyboardUp); while (Time.time - startTime < keyboardMotionDuration) { float rate = (Time.time - startTime) / keyboardMotionDuration; Vector3 lerpApproach = Vector3.Lerp(startPos, targetPos, horizontalApproachCurve.Evaluate(rate)); //Y成分に相当するところをキャンセルしておく lerpApproach -= keyboardUp * Vector3.Dot(lerpApproach - keyboardRootPos, keyboardUp); if (rate >= 0.5f) { break; } //アプローチ中: 垂直方向のカーブのつけかたをいい感じにする。 float verticalTarget = Mathf.Lerp( startVertical, targetVertical, verticalApproachCurve.Evaluate(rate) ); float vertical = Mathf.Lerp( Vector3.Dot(ikTarget.Position - keyboardRootPos, keyboardUp), verticalTarget, keyboardVerticalWeightCurve.Evaluate(rate) ); ikTarget.Position = lerpApproach + keyboardUp * vertical; //一応Lerpしてるけどあんまり必要ないかもね ikTarget.Rotation = Quaternion.Slerp( ikTarget.Rotation, keyboardRot, 0.2f ); yield return(null); } //最後: キーを押し下げてるときの位置にぴったりあわせて終わり ikTarget.Position = targetPos; ikTarget.Rotation = keyboardRot; }
private IEnumerator KeyPressRoutine(IKTargets target, Vector3 targetPos) { bool isLeftHand = (target == IKTargets.LHand); IKDataRecord ikTarget = isLeftHand ? _leftHand : _rightHand; //NOTE: 第2項は手首を正面に向けるための前処理みたいなファクターです var keyboardRot = keyboard.GetKeyboardRotation() * Quaternion.AngleAxis(isLeftHand ? 90 : -90, Vector3.up); var keyboardRootPos = keyboard.transform.position; var keyboardUp = keyboard.KeyboardUp; float startTime = Time.time; Vector3 startPos = ikTarget.Position; float startVertical = Vector3.Dot(startPos - keyboardRootPos, keyboardUp); float targetVertical = Vector3.Dot(targetPos - keyboardRootPos, keyboardUp); while (Time.time - startTime < keyboardMotionDuration) { float rate = (Time.time - startTime) / keyboardMotionDuration; Vector3 lerpApproach = Vector3.Lerp(startPos, targetPos, horizontalApproachCurve.Evaluate(rate)); //Y成分に相当するところをキャンセルしておく lerpApproach -= keyboardUp * Vector3.Dot(lerpApproach - keyboardRootPos, keyboardUp); if (rate < 0.5f) { //アプローチ中: 垂直方向のカーブのつけかたをいい感じにする。 float verticalTarget = Mathf.Lerp( startVertical, targetVertical, verticalApproachCurve.Evaluate(rate) ); float vertical = Mathf.Lerp( Vector3.Dot(ikTarget.Position - keyboardRootPos, keyboardUp), verticalTarget, keyboardVerticalWeightCurve.Evaluate(rate) ); ikTarget.Position = lerpApproach + keyboardUp * vertical; } else { //離れるとき: キーボードから垂直方向に手を引き上げる。Lerpの係数は1から0に戻っていくことに注意 float vertical = Mathf.Lerp( targetVertical + YOffsetAfterKeyDown, targetVertical, verticalApproachCurve.Evaluate(rate)); ikTarget.Position = lerpApproach + keyboardUp * vertical; } //一応Lerpしてるけどあんまり必要ないかもね ikTarget.Rotation = Quaternion.Slerp( ikTarget.Rotation, keyboardRot, 0.2f ); yield return(null); } //最後: ピッタリ合わせておしまい ikTarget.Position = targetPos + keyboardUp * YOffsetAfterKeyDown; ikTarget.Rotation = keyboardRot; }