Ejemplo n.º 1
0
            // Updates the pelvis position offset
            public void Process(float lowestOffset, float highestOffset, bool isGrounded)
            {
                if (!initiated)
                {
                    return;
                }

                float deltaTime = Time.time - lastTime;

                lastTime = Time.time;
                if (deltaTime <= 0f)
                {
                    return;
                }

                float offsetTarget = lowestOffset + highestOffset;

                if (!grounding.rootGrounded)
                {
                    offsetTarget = 0f;
                }

                // Interpolating the offset
                heightOffset = Mathf.Lerp(heightOffset, offsetTarget, deltaTime * grounding.pelvisSpeed);

                // Damper
                Vector3 rootDelta = (grounding.root.position - lastRootPosition);

                lastRootPosition = grounding.root.position;

                // Fading out damper when ungrounded
                damperF = Interp.LerpValue(damperF, isGrounded? 1f: 0f, 1f, 10f);

                // Calculating the final damper
                heightOffset -= grounding.GetVerticalOffset(rootDelta, Vector3.zero) * grounding.pelvisDamper * damperF;

                // Update IK value
                IKOffset = grounding.up * heightOffset;
            }
Ejemplo n.º 2
0
            // Raycasting, processing the leg's position
            // 脚位置的计算器. 主要是看 IKPosition 和 IKRotation怎么计算的
            public void Process()
            {
                if (!initiated)
                {
                    return;
                }
                if (grounding.maxStep <= 0)
                {
                    return;
                }

                deltaTime = Time.time - lastTime;
                lastTime  = Time.time;
                if (deltaTime == 0f)
                {
                    return;
                }

                up = grounding.up;
                heightFromGround = Mathf.Infinity;

                // Calculating velocity
                velocity = (transform.position - lastPosition) / deltaTime;
                //速度投影到适合地面的方向(平行?)
                velocity     = grounding.Flatten(velocity);
                lastPosition = transform.position;

                Vector3 prediction = velocity * grounding.prediction;

                if (grounding.footRadius <= 0)
                {
                    grounding.quality = Grounding.Quality.Fastest;
                }

                // Raycasting
                switch (grounding.quality)
                {
                // The fastest, single raycast
                case Grounding.Quality.Fastest:

                    RaycastHit predictedHit = GetRaycastHit(prediction);
                    SetFootToPoint(predictedHit.normal, predictedHit.point);
                    break;

                // Medium, 3 raycasts
                case Grounding.Quality.Simple:

                    heelHit = GetRaycastHit(Vector3.zero);
                    Vector3 f = grounding.GetFootCenterOffset();
                    if (invertFootCenter)
                    {
                        f = -f;
                    }
                    RaycastHit toeHit  = GetRaycastHit(f + prediction);
                    RaycastHit sideHit = GetRaycastHit(grounding.root.right * grounding.footRadius * 0.5f);

                    Vector3 planeNormal = Vector3.Cross(toeHit.point - heelHit.point, sideHit.point - heelHit.point).normalized;
                    if (Vector3.Dot(planeNormal, up) < 0)
                    {
                        planeNormal = -planeNormal;
                    }

                    SetFootToPlane(planeNormal, heelHit.point, heelHit.point);
                    break;

                // The slowest, raycast and a capsule cast
                case Grounding.Quality.Best:
                    heelHit = GetRaycastHit(invertFootCenter? -grounding.GetFootCenterOffset(): Vector3.zero);
                    RaycastHit capsuleHit = GetCapsuleHit(prediction);

                    SetFootToPlane(capsuleHit.normal, capsuleHit.point, heelHit.point);
                    break;
                }


                // Is the foot grounded?
                isGrounded = heightFromGround < grounding.maxStep;

                //获取脚离地的高度. stepHeightFromGround 值是通过:脚上的射线获得 脚transform.position,再 脚transform.position - root.tranform.position
                float offsetTarget = stepHeightFromGround;

                //若不在地面上,这个高度置0
                if (!grounding.rootGrounded)
                {
                    offsetTarget = 0f;
                }

                //脚步IK偏移计算: 线性插值的方式. 将偏移值逐渐修改至离地的高度
                IKOffset = Interp.LerpValue(IKOffset, offsetTarget, grounding.footSpeed, grounding.footSpeed);
                //脚步IK偏移计算: 跟上面的差不多.不知道为啥要用两个
                IKOffset = Mathf.Lerp(IKOffset, offsetTarget, deltaTime * grounding.footSpeed);

                //获取脚离地的实际高度
                float legHeight = grounding.GetVerticalOffset(transform.position, grounding.root.position);
                // 当前脚的高度距离最大离地距离还差多少高度
                float currentMaxOffset = Mathf.Clamp(grounding.maxStep - legHeight, 0f, grounding.maxStep);

                // 限制(在阶梯处会一直脚高一直脚低)
                IKOffset = Mathf.Clamp(IKOffset, -currentMaxOffset, IKOffset);

                RotateFoot();
                // Update IK values
                IKPosition = transform.position - up * IKOffset;

                float rW = grounding.footRotationWeight;

                rotationOffset = rW >= 1? r: Quaternion.Slerp(Quaternion.identity, r, rW);
            }
Ejemplo n.º 3
0
            // Raycasting, processing the leg's position
            public void Process()
            {
                if (!initiated)
                {
                    return;
                }
                if (grounding.maxStep <= 0)
                {
                    return;
                }

                transformPosition      = doOverrideFootPosition ? overrideFootPosition : transform.position;
                doOverrideFootPosition = false;

                deltaTime = Time.time - lastTime;
                lastTime  = Time.time;
                if (deltaTime == 0f)
                {
                    return;
                }

                up = grounding.up;
                heightFromGround = Mathf.Infinity;

                // Calculating velocity
                velocity     = (transformPosition - lastPosition) / deltaTime;
                velocity     = grounding.Flatten(velocity);
                lastPosition = transformPosition;

                Vector3 prediction = velocity * grounding.prediction;

                if (grounding.footRadius <= 0)
                {
                    grounding.quality = Grounding.Quality.Fastest;
                }

                // Raycasting
                switch (grounding.quality)
                {
                // The fastest, single raycast
                case Grounding.Quality.Fastest:

                    RaycastHit predictedHit = GetRaycastHit(prediction);
                    SetFootToPoint(predictedHit.normal, predictedHit.point);
                    break;

                // Medium, 3 raycasts
                case Grounding.Quality.Simple:

                    heelHit = GetRaycastHit(Vector3.zero);
                    Vector3 f = grounding.GetFootCenterOffset();
                    if (invertFootCenter)
                    {
                        f = -f;
                    }
                    RaycastHit toeHit  = GetRaycastHit(f + prediction);
                    RaycastHit sideHit = GetRaycastHit(grounding.root.right * grounding.footRadius * 0.5f);

                    Vector3 planeNormal = Vector3.Cross(toeHit.point - heelHit.point, sideHit.point - heelHit.point).normalized;
                    if (Vector3.Dot(planeNormal, up) < 0)
                    {
                        planeNormal = -planeNormal;
                    }

                    SetFootToPlane(planeNormal, heelHit.point, heelHit.point);
                    break;

                // The slowest, raycast and a capsule cast
                case Grounding.Quality.Best:
                    heelHit    = GetRaycastHit(invertFootCenter? -grounding.GetFootCenterOffset(): Vector3.zero);
                    capsuleHit = GetCapsuleHit(prediction);

                    SetFootToPlane(capsuleHit.normal, capsuleHit.point, heelHit.point);
                    break;
                }

                // Is the foot grounded?
                isGrounded = heightFromGround < grounding.maxStep;

                float offsetTarget = stepHeightFromGround;

                if (!grounding.rootGrounded)
                {
                    offsetTarget = 0f;
                }

                IKOffset = Interp.LerpValue(IKOffset, offsetTarget, grounding.footSpeed, grounding.footSpeed);
                IKOffset = Mathf.Lerp(IKOffset, offsetTarget, deltaTime * grounding.footSpeed);

                float legHeight        = grounding.GetVerticalOffset(transformPosition, grounding.root.position);
                float currentMaxOffset = Mathf.Clamp(grounding.maxStep - legHeight, 0f, grounding.maxStep);

                IKOffset = Mathf.Clamp(IKOffset, -currentMaxOffset, IKOffset);

                RotateFoot();

                // Update IK values
                IKPosition = transformPosition - up * IKOffset;

                float rW = grounding.footRotationWeight;

                rotationOffset = rW >= 1? r: Quaternion.Slerp(Quaternion.identity, r, rW);
            }