private void Control()
    {
        Controller.ControlType = ControlType;

        //Update Past
        RootSeries.Increment(0, TimeSeries.Samples.Length - 1);
        StyleSeries.Increment(0, TimeSeries.Samples.Length - 1);
        DribbleSeries.Increment(0, TimeSeries.Samples.Length - 1);

        //Update User Controller Inputs
        Controller.Update();

        //Ball Vectors
        Vector3 control = Vector3.Lerp(
            Controller.QueryRightJoystickVector(),                                                                                                                                    //User Control
            (DribbleSeries.BallTransformations[TimeSeries.Pivot].GetPosition() - transform.position).ZeroY().normalized.GetRelativeDirectionTo(Actor.GetRoot().GetWorldMatrix(true)), //Game State
            Carrier ? 0f : 1f
            );
        float height = DribbleSeries.GetBallAmplitude();
        float speed  = Mathf.Abs(DribbleSeries.BallVelocities[TimeSeries.Pivot].y);

        if (Carrier && Controller.QueryLogic("Dribble"))
        {
            if (DribbleSeries.Pivots[TimeSeries.Pivot].y > HeightDribbleThreshold)
            {
                height -= 2f * HeightDribbleThreshold;
            }
            if (DribbleSeries.Momentums[TimeSeries.Pivot].y < SpeedDribbleThreshold)
            {
                speed += 2f * SpeedDribbleThreshold;
            }
        }
        if (Carrier && Controller.QueryLogic("Hold") && Controller.QueryLogic("HorizontalControl"))
        {
            control = ToHoldTarget(control);
            height  = control.y;
            speed   = (height - DribbleSeries.BallTransformations[TimeSeries.Pivot].GetPosition().y) * Framerate;
        }

        //Locomotion
        Vector3 move = Controller.QueryLeftJoystickVector().ZeroY();
        float   turn = Controller.QueryRadialController();
        float   spin = Controller.QueryLogic("Move") ? Controller.QueryButtonController() : 0f;

        //Amplify Factors
        move  = Quaternion.LookRotation(Vector3.ProjectOnPlane(transform.position - GetCamera().transform.position, Vector3.up).normalized, Vector3.up) * move;
        move *= WalkFactor;
        if (Controller.QueryLogic("Sprint"))
        {
            move *= SprintFactor;
        }
        spin *= SpinFactor;
        turn  = Mathf.Sign(turn) * Mathf.Pow(Mathf.Abs(turn), 1f / TurnFactor);

        //Keyboard Adjustments
        if (ControlType == Controller.TYPE.Keyboard)
        {
            float length = move.magnitude;
            if (move.x != 0f && move.z < 0f && Mathf.Abs(turn) > 0.1f)
            {
                move.z *= 0f;
                move.x *= 0.5f;
            }
            if (move.x != 0f && move.z == 0f && Mathf.Abs(turn) > 0.1f)
            {
                move.z = Mathf.Abs(move.x);
            }
            if (move.z < 0f && Mathf.Abs(turn) < 0.1f)
            {
                move.z *= 0.5f;
            }
            if (move.z < 0f && move.x == 0f && Mathf.Abs(turn) < 0.1f)
            {
                move.z = -1f;
                float left  = ContactSeries.GetContacts("Left Hand").Mean();
                float right = ContactSeries.GetContacts("Right Hand").Mean();
                if (left > right)
                {
                    move.x = 1f;
                }
                if (right > left)
                {
                    move.x = -1f;
                }
            }
            move = move.ClampMagnitudeXZ(length);
            move = Quaternion.AngleAxis(60f * turn, Vector3.up) * move.GetRelativeDirectionFrom(transform.GetWorldMatrix(true));
            if (control.magnitude > 0.1f)
            {
                control = control.normalized;
            }
            else
            {
                control = Vector3.zero;
            }
        }

        //Ball Shooting
        if (Carrier && Controller.QueryLogic("Shoot"))
        {
            move = Vector3.zero;
            if (
                DribbleSeries.BallVelocities[TimeSeries.Pivot].magnitude <DribbleSeries.BallVelocities[TimeSeries.Pivot - 1].magnitude &&
                                                                          DribbleSeries.BallTransformations[TimeSeries.Pivot].GetPosition().y> 1.5f && ContactSeries.GetContacts(TimeSeries.Pivot, "Left Hand", "Right Hand").Sum() < 0.1f
                )
            {
                Carrier = false;
            }
        }

        //Holding, Picking & Catching
        if (Controller.QueryLogic("Hold"))
        {
            if (Carrier)
            {
                move = Vector3.zero;
                turn = 0f;
                spin = 0f;
            }
            else
            {
                if ((HasBallContact(LeftHandIK.Bones.Last().Transform.position) || HasBallContact(RightHandIK.Bones.Last().Transform.position)))
                {
                    Carrier = true;
                }
                else
                {
                    move = Vector3.Lerp(move, move.magnitude * (DribbleSeries.BallTransformations[TimeSeries.Pivot].GetPosition() - Actor.GetRoot().position).normalized, GetBallInteractionWeight(Actor.GetRoot().position));
                }
            }
        }

        //Trajectory
        for (int i = TimeSeries.Pivot; i < TimeSeries.Samples.Length; i++)
        {
            //Root Positions
            RootSeries.SetPosition(i,
                                   Vector3.Lerp(
                                       RootSeries.GetPosition(i),
                                       Actor.GetRoot().position + i.Ratio(TimeSeries.Pivot, TimeSeries.Samples.Length - 1) * move,
                                       Controller.QueryFunction("RootPositionControl", i)
                                       )
                                   );

            //Root Rotations
            RootSeries.SetRotation(i,
                                   Quaternion.Slerp(
                                       RootSeries.GetRotation(i),
                                       Controller.QueryLogic("Move") && move != Vector3.zero ?  Quaternion.LookRotation(move, Vector3.up) : Actor.GetRoot().rotation,
                                       Mathf.Abs(turn) * Controller.QueryFunction("RootRotationControl", i)
                                       )
                                   );
            if (ControlType == Controller.TYPE.Keyboard && !Controller.QueryLogic("Sprint"))
            {
                if (turn != 0f)
                {
                    float w = i.Ratio(TimeSeries.Pivot, TimeSeries.Samples.Length - 1).ActivateCurve(0.75f, 0f, 1f);
                    RootSeries.SetRotation(i, RootSeries.GetRotation(TimeSeries.Pivot) * Quaternion.AngleAxis(60f * turn * w, Vector3.up));
                }
            }

            //Spin Rotations
            if (spin != 0f)
            {
                float w = i.Ratio(TimeSeries.Pivot, TimeSeries.Samples.Length - 1).ActivateCurve(0.25f, 0.75f, 0f);
                RootSeries.SetRotation(i, RootSeries.GetRotation(i) * Quaternion.AngleAxis(spin * w, Vector3.up));
            }

            //Root Velocities
            RootSeries.SetVelocity(i,
                                   Vector3.Lerp(
                                       RootSeries.GetVelocity(i),
                                       move,
                                       Controller.QueryFunction("RootVelocityControl", i)
                                       )
                                   );

            //Ball Control
            DribbleSeries.Target    = new Vector4(control.x, height, control.z, speed);
            DribbleSeries.Pivots[i] = DribbleSeries.InterpolatePivot(
                DribbleSeries.Pivots[i],
                new Vector3(DribbleSeries.Target.x, DribbleSeries.Target.y, DribbleSeries.Target.z),
                Controller.QueryFunction("BallHorizontalControl", i),
                Controller.QueryFunction("BallHeightControl", i)
                );
            DribbleSeries.Momentums[i] = DribbleSeries.InterpolateMomentum(
                DribbleSeries.Momentums[i],
                new Vector3(
                    0.5f * Framerate * (DribbleSeries.Target.x - DribbleSeries.Pivots[i].x),
                    DribbleSeries.Target.w,
                    0.5f * Framerate * (DribbleSeries.Target.z - DribbleSeries.Pivots[i].z)
                    ),
                Controller.QueryFunction("BallHorizontalControl", i),
                Controller.QueryFunction("BallSpeedControl", i)
                );
        }

        //Resolve Trajectory Collisions
        RootSeries.ResolveCollisions(Collider.radius, CollisionMask);

        //Action Values
        float[] actions = Controller.PoolLogics(StyleSeries.Styles);
        for (int i = TimeSeries.Pivot; i < TimeSeries.Samples.Length; i++)
        {
            for (int j = 0; j < StyleSeries.Styles.Length; j++)
            {
                StyleSeries.Values[i][j] = Mathf.Lerp(
                    StyleSeries.Values[i][j],
                    actions[j],
                    Controller.QueryFunction(StyleSeries.Styles[j] + "Control", i)
                    );
            }
        }
    }
Beispiel #2
0
    private void Control()
    {
        float KeyboardTurnAngle()
        {
            return(Controller.QueryLogic("Sprint") ? 45f : 60f);
        }

        Controller.ControlType = ControlType;

        //Update Past
        RootSeries.Increment(0, TimeSeries.Samples.Length - 1);
        StyleSeries.Increment(0, TimeSeries.Samples.Length - 1);

        //Update User Controller Inputs
        Controller.Update();

        //Locomotion
        Vector3 move = Controller.QueryLeftJoystickVector().ZeroY();
        float   turn = Controller.QueryRadialController();
        float   spin = Controller.QueryLogic("Move") ? Controller.QueryButtonController() : 0f;

        //Amplify Factors
        move = Quaternion.LookRotation(Vector3.ProjectOnPlane(transform.position - GetCamera().transform.position, Vector3.up).normalized, Vector3.up) * move;
        if (Controller.QueryLogic("Sprint"))
        {
            move *= SprintSpeed;
        }
        else
        {
            move *= WalkSpeed;
        }

        //Keyboard Adjustments
        if (ControlType == Controller.TYPE.Keyboard)
        {
            if (!Controller.QueryLogic("Sprint"))
            {
                move /= 1.25f;
            }
            float length = move.magnitude;
            if (move.x != 0f && move.z < 0f && Mathf.Abs(turn) > 0.1f)
            {
                move.z *= 0f;
                move.x *= 0.5f;
            }
            if (move.x != 0f && move.z == 0f && Mathf.Abs(turn) > 0.1f)
            {
                move.z = Mathf.Abs(move.x);
            }
            if (move.z < 0f && Mathf.Abs(turn) < 0.1f)
            {
                move.z *= 0.5f;
            }
            if (move.z < 0f && move.x == 0f && Mathf.Abs(turn) < 0.1f)
            {
                move.z = 0f;
            }
            if (Controller.QueryLogic("Sprint"))
            {
                move.z = Mathf.Max(move.z, 0f);
            }
            move = move.ClampMagnitudeXZ(length);
            move = Quaternion.AngleAxis(KeyboardTurnAngle() * turn, Vector3.up) * move.GetRelativeDirectionFrom(transform.GetWorldMatrix(true));
        }

        //Trajectory
        for (int i = TimeSeries.Pivot; i < TimeSeries.Samples.Length; i++)
        {
            //Root Positions
            RootSeries.SetPosition(i,
                                   Vector3.Lerp(
                                       RootSeries.GetPosition(i),
                                       Actor.GetRoot().position + i.Ratio(TimeSeries.Pivot, TimeSeries.Samples.Length - 1) * move,
                                       Controller.QueryFunction("RootPositionControl", i)
                                       )
                                   );

            //Root Rotations
            if (ControlType == Controller.TYPE.Gamepad)
            {
                RootSeries.SetRotation(i,
                                       Quaternion.Slerp(
                                           RootSeries.GetRotation(i),
                                           Controller.QueryLogic("Move") && move != Vector3.zero ? Quaternion.LookRotation(move, Vector3.up) : Actor.GetRoot().rotation,
                                           Mathf.Clamp(move.magnitude, 0f, 1f) * Controller.QueryFunction("RootRotationControl", i)
                                           )
                                       );
            }
            if (ControlType == Controller.TYPE.Keyboard)
            {
                RootSeries.SetRotation(i,
                                       Quaternion.Slerp(
                                           RootSeries.GetRotation(i),
                                           Controller.QueryLogic("Move") && move != Vector3.zero ? Quaternion.LookRotation(move, Vector3.up) : Actor.GetRoot().rotation,
                                           Controller.QueryLogic("Sprint") ? Mathf.Pow(i.Ratio(TimeSeries.Pivot, TimeSeries.Samples.Length - 1), 0.1f) : Mathf.Clamp(move.magnitude, 0f, 1f) * Controller.QueryFunction("RootRotationControl", i)
                                           )
                                       );
            }

            //Root Velocities
            RootSeries.SetVelocity(i,
                                   Vector3.Lerp(
                                       RootSeries.GetVelocity(i),
                                       move,
                                       Controller.QueryFunction("RootVelocityControl", i)
                                       )
                                   );
        }

        //Resolve Trajectory Collisions
        RootSeries.ResolveCollisions(Collider.radius, CollisionMask);

        //Action Values
        float[] actions = Controller.PoolLogics(StyleSeries.Styles);
        actions[StyleSeries.Styles.FindIndex("Speed")] *= move.magnitude;
        for (int i = TimeSeries.Pivot; i < TimeSeries.Samples.Length; i++)
        {
            for (int j = 0; j < StyleSeries.Styles.Length; j++)
            {
                StyleSeries.Values[i][j] = Mathf.Lerp(
                    StyleSeries.Values[i][j],
                    actions[j],
                    Controller.QueryFunction(StyleSeries.Styles[j] + "Control", i)
                    );
            }
        }
    }