Пример #1
0
        private IEnumerator MoveToNote(IKDataRecord ik, Vector3 notePosition, Quaternion noteRot, Vector3 upDiff)
        {
            float start = Time.time;

            while (Time.time - start < noteMotionDuration)
            {
                float rate = (Time.time - start) / noteMotionDuration;

                if (rate < 0.5f)
                {
                    //接近動作: このとき既存位置を考慮してウェイトをいじる点に注意
                    Vector3 target = Vector3.Lerp(notePosition + upDiff, notePosition, rate * 2.0f);
                    ik.Position = Vector3.Lerp(ik.Position, target, rate * 2.0f);
                    ik.Rotation = Quaternion.Slerp(ik.Rotation, noteRot, rate * 2.0f);
                }
                else
                {
                    //上がる動作
                    ik.Position = Vector3.Lerp(
                        notePosition,
                        notePosition + upDiff,
                        1 - 4.0f * (rate - 1.0f) * (rate - 1.0f)
                        );
                    ik.Rotation = noteRot;
                }

                yield return(null);
            }

            //最後はぴったり揃えて終了
            ik.Position = notePosition + upDiff;
            ik.Rotation = noteRot;
        }
Пример #2
0
        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;
        }
Пример #3
0
        private IEnumerator KeyUpRoutine(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;
            float targetVertical = Vector3.Dot(targetPos - keyboardRootPos, keyboardUp);

            while (Time.time - startTime < keyboardMotionDuration)
            {
                //NOTE: 歴史的経緯により、+0.5することで後半の動作をするように仕向ける
                float rate = (Time.time - startTime) / keyboardMotionDuration + 0.5f;

                //NOTE: キー上げの時点で水平方向が合ってなかった場合、ぴったり合わせてしまう(あえてlerpしない)
                Vector3 lerpApproach = targetPos;
                //Y成分に相当するところをキャンセルしておく
                lerpApproach -= keyboardUp * Vector3.Dot(lerpApproach - keyboardRootPos, keyboardUp);

                //離れるとき: キーボードから垂直方向に手を引き上げる。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
                    );

                if (rate >= 1.0f)
                {
                    break;
                }

                yield return(null);
            }

            //最後: ピッタリ合わせておしまい
            ikTarget.Position = targetPos + keyboardUp * YOffsetAfterKeyDown;
            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;
        }