public void Update(GenericMotionConfig config, Rigidbody body) { UpdateCurrentState(config, body); // Flat land control var current = Velocity - Vector3.Project(Velocity, config.Up(body)); var target = Direction.AsVector(body, config) * config.MaxSpeed * SpeedMultiplier * Direction.Magnitude(); var fallingAccelerationMultiplier = Falling ? 0.0f : 1.0f; var delta = (target - current).normalized * config.Acceleration * fallingAccelerationMultiplier * Time.deltaTime; Velocity += delta; // Convery velocity into force to apply. current = body.velocity - Vector3.Project(body.velocity, config.Up(body)); target = Velocity - current; Force = target.magnitude * target.magnitude * target.normalized * body.mass; // Jumping DetectGround(config, body); if (Jumping) { if (Grounded && !Falling) { if (_elapsedSinceLastJump > config.MinJumpInterval) { Impulse = config.Up(body) * Direction.Jump * config.JumpSpeed * body.mass; Jumping = false; _elapsedSinceLastJump = 0f; } } } _elapsedSinceLastJump += Time.deltaTime; HaltMinimumVelocities(); }
private void DetectGround(GenericMotionConfig config, Rigidbody body) { if (!config.EnableGroundDetection) { return; } var root = config.GroundDetectionPoint != null ? config.GroundDetectionPoint : body.gameObject; var hits = Physics.RaycastAll(root.transform.position, -config.Up(body), config.GroundDetectionDistance, config.GroundCollisionMask); Grounded = hits.Any(i => i.collider.gameObject != body.gameObject); }