private bool CheckGround(CharacterControllerMotor motor, Transform transform)
        {
            var controller = motor.CharacterController;

            var worldCenter = transform.position + controller.center;
            var lowPoint    = worldCenter - new Vector3(0, controller.height * 0.5f, 0);

            Profiler.BeginSample("RaycastNonAlloc");
            var layerMask = CPhysicSettings.PhysicInteractionLayerMask;
            var rayLength = Physics.RaycastNonAlloc(lowPoint, Vector3.down, s_RaycastHits, 0.0001f, layerMask);

            Profiler.EndSample();

            for (int i = 0; i != rayLength; i++)
            {
                var ray = s_RaycastHits[i];
                if (ray.transform == transform)
                {
                    continue;
                }

                var velocityToAdd = ray.point - lowPoint;

                CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, true);
                motor.MoveBy(velocityToAdd);
                CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, false);

                return(true);
            }

            return(false);
        }
        private Vector3 ProbeGround(CharacterControllerMotor motor, Transform transform, Vector3 previousDirection, float maxAngle, float globalMaxAngle)
        {
            var controller = motor.CharacterController;

            var worldCenter = transform.position + controller.center;
            var lowPoint    = worldCenter - new Vector3(0, controller.height * 0.5f, 0);
            var highPoint   = lowPoint + new Vector3(0, controller.height, 0);

            Profiler.BeginSample("RaycastNonAlloc");
            var layerMask = CPhysicSettings.PhysicInteractionLayerMask;
            var rayLength = Physics.RaycastNonAlloc(lowPoint, Vector3.down, s_RaycastHits, controller.stepOffset, layerMask);

            Profiler.EndSample();

            if (previousDirection == Vector3.zero)
            {
                previousDirection = Vector3.up;
            }

            var highestAngle = 0f;
            var highestDir   = previousDirection;
            var highestY     = float.MinValue;

            for (int i = 0; i != rayLength; i++)
            {
                var ray = s_RaycastHits[i];
                if (ray.transform == transform)
                {
                    continue;
                }

                //ray.normal = RepairHitSurfaceNormal(ray);

                var angle = Vector3.Angle(previousDirection, ray.normal);
                if (angle > highestAngle)
                {
                    highestAngle = angle;
                    highestDir   = ray.normal;
                }

                if (angle > maxAngle || Vector3.Angle(Vector3.up, ray.normal) > globalMaxAngle &&
                    highestY > ray.point.y)
                {
                    continue;
                }

                var velocityToAdd = ray.point - lowPoint;

                CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, true);
                motor.MoveBy(velocityToAdd);
                CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, false);

                highestY = ray.point.y;

                motor.IsGroundForcedThisFrame = true;
            }

            return(highestDir);
        }
    void Start()
    {
        velocity = Vector3.zero;
        angularVelocity = Vector3.zero;
        xform = transform;
        motor = GetComponent<CharacterControllerMotor>();

        oldPosition = xform.position;
        oldRotation = xform.rotation.eulerAngles;
    }
Esempio n. 4
0
    void Start()
    {
        velocity        = Vector3.zero;
        angularVelocity = Vector3.zero;
        xform           = transform;
        motor           = GetComponent <CharacterControllerMotor>();

        oldPosition = xform.position;
        oldRotation = xform.rotation.eulerAngles;
    }
        private bool OnControllerHasHitACollider(ControllerColliderHit hit,
                                                 float plannedDistance,
                                                 Vector3 oldPos,
                                                 CharacterControllerMotor motor,
                                                 Transform transform,
                                                 ref Vector3 correctedVelocity)
        {
            var controller  = motor.CharacterController;
            var worldCenter = transform.position + controller.center;
            var lowPoint    = worldCenter - new Vector3(0, controller.height * 0.5f, 0);
            var highPoint   = lowPoint + new Vector3(0, controller.height, 0);

            var angle = Vector3.Angle(hit.normal, Vector3.down);

            if (hit.point.y > lowPoint.y + controller.stepOffset)
            {
                var flatVelocity = correctedVelocity.ToGrid(1);
                var flatNormal   = hit.normal.ToGrid(1);

                var undesiredMotion = flatNormal * Vector3.Dot(flatVelocity, flatNormal);
                var desiredMotion   = flatVelocity - undesiredMotion;
                var desiredY        = desiredMotion.y;

                desiredMotion.y = 0;

                desiredMotion = Vector3.ClampMagnitude(desiredMotion, flatVelocity.magnitude);

                desiredMotion.y   = correctedVelocity.y;
                correctedVelocity = desiredMotion;

                // Floor
                if ((controller.collisionFlags == CollisionFlags.Above ||
                     (int)controller.collisionFlags == 3) &&
                    angle < 90f && correctedVelocity.y > 0)
                {
                    correctedVelocity.y = desiredY;
                }

                return(true);
            }

            return(false);
        }
        private Vector3 GetAngleDir(CharacterControllerMotor motor, Transform transform)
        {
            var controller = motor.CharacterController;
            var height     = controller.height;
            var radius     = controller.radius;

            var worldCenter = transform.position + controller.center;
            var lowPoint    = worldCenter - new Vector3(0, height * 0.5f, 0);
            var highPoint   = lowPoint + new Vector3(0, height, 0);
            var distance    = height * 0.25f + 0.1f + (controller.skinWidth * 4);

            var layerMask     = CPhysicSettings.PhysicInteractionLayerMask;
            var rayLength     = Physics.CapsuleCastNonAlloc(worldCenter, highPoint, radius, Vector3.down, s_RaycastHits, distance, layerMask);
            var smallestAngle = float.MaxValue;
            var smallestDir   = Vector3.down;

            if (rayLength > 0)
            {
                motor.IsGroundForcedThisFrame = true;
            }

            for (int i = 0; i != rayLength; i++)
            {
                var ray = s_RaycastHits[i];
                Physics.Raycast(ray.point + Vector3.up * 0.01f, Vector3.down, out ray, ray.distance + 0.02f);

                var normal = ray.normal;
                //var normal = RepairHitSurfaceNormal(ray);
                var angle = Vector3.Angle(Vector3.up, normal);

                Debug.DrawRay(ray.point, normal, Color.green, 5);

                if (angle < smallestAngle)
                {
                    smallestAngle = angle;
                    smallestDir   = normal;
                }
            }

            return(smallestDir);
        }
Esempio n. 7
0
 public static bool OnGround(CharacterControllerMotor controllerMotor, StVelocity velocity)
 {
     return(velocity.Value.y <= 0 && controllerMotor.IsGrounded(CPhysicSettings.PhysicInteractionLayerMask));
 }
        private bool ProcessItem
        (
            ref Entity entity,
            ref StVelocity velocity,
            ref DefStDodgeOnGroundSettings setting,
            ref DefStRunInput runInput,
            ref DefStDodgeInput input,
            ref DefStWallDodgeProcessData process,
            ref DefStDodgeOnGroundProcessData groundProcess,
            CharacterControllerMotor motor
        )
        {
            var action = input.State != InputState.None && !MvUtils.OnGround(motor, velocity) && Time.time > process.TimeBeforeNextWD;

            DiffuseCommand(m_CmdDoDodge, m_CmdDoDodgeResult, action, CmdState.Begin);

            if (!m_CmdDoDodgeResult.GetComponentData <EntityCommandResult>().AsBool())
            {
                DiffuseCommand(m_CmdDoDodge, m_CmdDoDodgeResult, action, CmdState.End);

                return(false);
            }

            var originalVelocity = velocity.Value;
            var fwd       = motor.transform.forward;
            var pos       = motor.transform.position + new Vector3(0, motor.CharacterController.stepOffset + 0.1f);
            var rot       = motor.transform.rotation;
            var rd        = motor.CharacterController.radius + 0.075f;
            var sw        = motor.CharacterController.skinWidth + 0.025f;
            var height    = motor.CharacterController.height - motor.CharacterController.stepOffset;
            var subheight = (height * 0.75f) - 0.005f;

            CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, false);

            var direction = (Vector3)SrtComputeDirection(fwd, rot, runInput.Direction);

            direction = (velocity.Value.ToGrid(1).normalized + direction * 2).normalized;
            var rayTrace = UtilityWallRayTrace.RayTrace(ref direction, ref pos, ref rd, ref sw, ref height, ref subheight, motor.CharacterController);

            CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, true);

            var success = rayTrace.normal != Vector3.zero && Mathf.Abs(rayTrace.normal.y) < 0.2f;

            if (success)
            {
                rayTrace.normal = rayTrace.normal.ToGrid(1).normalized;

                var reflected  = (Vector3.Reflect(direction, rayTrace.normal) + rayTrace.normal).normalized;
                var oldY       = velocity.Value.y;
                var dirInertie = (reflected * (velocity.Value.magnitude + 1)) + rayTrace.normal * 3.5f;
                dirInertie = RaycastUtilities.SlideVelocityNoYChange(velocity.Value, rayTrace.normal) + rayTrace.normal * 10;

                var minSpeed = Mathf.Max(velocity.Value.ToGrid(1).magnitude + setting.AdditiveSpeed, setting.MinSpeed);

                velocity.Value = dirInertie.ToGrid(1).normalized *(minSpeed);

                velocity.Value.y = Mathf.Max(oldY + 2, 0);

                process.TimeBeforeNextWD = Time.time + DefaultCooldown;

                input.TimeBeforeResetState = -1f;
                input.State = InputState.None;

                groundProcess.CooldownBeforeNextDodge = 0.25f;
                //groundProcess.InertieDelta            = 0.5f;
                groundProcess.Direction = dirInertie.normalized;

                BroadcastNewEntity(PostUpdateCommands, true);
                PostUpdateCommands.AddComponent(new DefStWallJumpEvent(Time.time, Time.frameCount, entity, originalVelocity, rayTrace.normal));
            }

            DiffuseCommand(m_CmdDoDodge, m_CmdDoDodgeResult, action, CmdState.End);

            return(success);
        }