bool UpdateSlidingPlanes(CollisionInfo collisionInfo, ref Vector3 slidingPlaneNormal, ref Vector3 groundPlaneNormal, ref Vector3 displacement)
        {
            Vector3 normal = collisionInfo.hitInfo.normal;

            if (collisionInfo.contactSlopeAngle > slopeLimit)
            {
                if (slidingPlaneNormal != Vector3.zero)
                {
                    float correlation = Vector3.Dot(normal, slidingPlaneNormal);

                    if (correlation > 0)
                    {
                        displacement = CustomUtilities.DeflectVector(displacement, groundPlaneNormal, normal);
                    }
                    else
                    {
                        displacement = Vector3.zero;
                    }
                }
                else
                {
                    displacement = CustomUtilities.DeflectVector(displacement, groundPlaneNormal, normal);
                }

                slidingPlaneNormal = normal;
            }
            else
            {
                displacement = CustomUtilities.ProjectVectorOnPlane(
                    displacement,
                    normal,
                    Up
                    );

                groundPlaneNormal  = normal;
                slidingPlaneNormal = Vector3.zero;
            }

            return(displacement == Vector3.zero);
        }
        public void CheckVelocityProjection(ref Vector3 displacement)
        {
            bool upwardsDisplacement = transform.InverseTransformVectorUnscaled(displacement).y > 0f;

            if (!upwardsDisplacement)
            {
                return;
            }

            Vector3 modifiedDisplacement = CustomUtilities.ProjectVectorOnPlane(
                displacement,
                Up,
                Up
                );

            // HitInfoFilter filter = new HitInfoFilter(
            //  PhysicsComponent.CollisionLayerMask ,
            //  false ,
            //  true
            // );

            // HitInfo projectionHitInfo;
            // PhysicsComponent.SphereCast(
            //  out projectionHitInfo ,
            //  OffsettedBottomCenter ,
            //  BodySize.x - CharacterConstants.SkinWidth ,
            //  modifiedDisplacement.normalized * ( modifiedDisplacement.magnitude + CharacterConstants.SkinWidth ) ,
            //  filter
            // );

            // if( projectionHitInfo.hit )
            //  return;

            displacement = modifiedDisplacement;

            // if( displacement != Vector3.zero )
        }
        void HandlePosition(float dt)
        {
            Vector3 position = Position;

            if (alwaysNotGrounded)
            {
                ForceNotGrounded();
            }

            if (IsKinematic)
            {
                // Process Attached Rigidbody
                if (!IsGrounded)
                {
                    // Check if a "Move" call has been made, if so then use the desiredPosition (RigidbodyComponent)
                    if (moveFlag)
                    {
                        position = RigidbodyComponent.DesiredPosition;
                    }

                    // WIP
                    //ReferenceRigidbodyDisplacement( ref position , attachedRigidbody );

                    Move(position);
                }
            }
            else
            {
                if (IsStable)
                {
                    VerticalVelocity = Vector3.zero;


                    // Weight ----------------------------------------------------------------------------------------------
                    ApplyWeight(GroundContactPoint);


                    Vector3 displacement = CustomUtilities.ProjectVectorOnPlane(
                        Velocity * dt,
                        GroundStableNormal,
                        Up
                        );

                    CollideAndSlide(ref position, displacement, false);

                    ProbeGround(ref position, dt);

                    ProcessDynamicGround(ref position, dt);

                    if (!IsStable)
                    {
                        CurrentTerrain           = null;
                        groundRigidbodyComponent = null;
                    }
                }
                else
                {
                    CollideAndSlideUnstable(ref position, Velocity * dt);
                }

                Move(position);
            }

            moveFlag = false;
        }
Exemple #4
0
        void ProbeGround(ref Vector3 position, float dt)
        {
            Vector3 preProbeGroundPosition = position;

            float groundCheckDistance = edgeCompensation ?
                                        BodySize.x / 2f + CharacterConstants.GroundCheckDistance :
                                        CharacterConstants.GroundCheckDistance;

            Vector3 displacement = -Up *Mathf.Max(groundCheckDistance, stepDownDistance);

            HitInfoFilter filter = new HitInfoFilter(PhysicsComponent.CollisionLayerMask, false, true);


            CollisionInfo collisionInfo;
            bool          hit = characterCollisions.CheckForGround(
                out collisionInfo,
                position,
                StepOffset,
                stepDownDistance,
                filter
                );

            if (hit)
            {
                float slopeAngle = Vector3.Angle(Up, GetGroundSlopeNormal(collisionInfo));

                if (slopeAngle <= slopeLimit)
                {
                    // Stable hit ---------------------------------------------------
                    ProcessNewGround(collisionInfo.hitInfo.transform, collisionInfo);

                    // Save the ground collision info
                    characterCollisionInfo.SetGroundInfo(collisionInfo, this);



                    // Calculate the final position
                    position += collisionInfo.displacement;


                    if (edgeCompensation && IsAStableEdge(collisionInfo))
                    {
                        // calculate the edge compensation and apply that to the final position
                        Vector3 compensation = Vector3.Project((collisionInfo.hitInfo.point - position), Up);
                        position += compensation;
                    }

                    stableProbeGroundVelocity = (position - preProbeGroundPosition) / dt;
                }
                else
                {
                    // Unstable Hit

                    // If the unstable ground is far enough then force not grounded
                    float castSkinDistance = StepOffset + 2f * CharacterConstants.SkinWidth;
                    if (collisionInfo.hitInfo.distance > castSkinDistance)
                    {
                        ForceNotGrounded();
                        return;
                    }


                    if (preventBadSteps)
                    {
                        // If the unstable ground is close enough then do a new collide and slide
                        if (WasGrounded)
                        {
                            position = Position;

                            Vector3 unstableDisplacement = CustomUtilities.ProjectVectorOnPlane(
                                Velocity * dt,
                                GroundStableNormal,
                                Up
                                );

                            CollideAndSlide(ref position, unstableDisplacement, true);
                        }
                    }


                    characterCollisions.CheckForGroundRay(
                        out collisionInfo,
                        position,
                        StepOffset,
                        stepDownDistance,
                        filter
                        );

                    ProcessNewGround(collisionInfo.hitInfo.transform, collisionInfo);

                    characterCollisionInfo.SetGroundInfo(collisionInfo, this);
                    Debug.DrawRay(collisionInfo.hitInfo.point, collisionInfo.hitInfo.normal);
                    stableProbeGroundVelocity = (position - preProbeGroundPosition) / dt;
                }
            }
            else
            {
                ForceNotGrounded();
            }
        }