Exemplo n.º 1
0
    private void GetMoveInput()
    {
        //Description: Updates MoveInput variable in base class (using player inputActions)

        //Initializations & Validations:
        MoveInput newMoveInput     = new MoveInput(); //Declare variable for storing new input data
        Vector2   directionalInput = new Vector2();   //Initialize vector for finding and storing directional input
        float     rotationalInput;                    //Initialize variable for finding and storing rotational input

        //DIRECTION: Get directional input vector
        if (Input.GetKey(KeyCode.W))
        {
            directionalInput.y += 1;                          //Get upward directional input
        }
        if (Input.GetKey(KeyCode.S))
        {
            directionalInput.y -= 1;                          //Get downward directional input
        }
        if (Input.GetKey(KeyCode.A))
        {
            directionalInput.x -= 1;                          //Get leftward directional input
        }
        if (Input.GetKey(KeyCode.D))
        {
            directionalInput.x += 1;                          //Get rightward directional input
        }
        //ROTATION: Get rotational input vector
        Vector2 mousePos       = Input.mousePosition;                               //Get mouse position in screen space
        Vector2 playerPos      = mainCamera.WorldToScreenPoint(transform.position); //Get player position in screen space
        Vector2 rotInputVector = HotteMath.AngleBetween(playerPos, mousePos);       //Get vector for angle between player and mouse position

        rotationalInput  = -HotteMath.LookAt2D(Vector2.zero, rotInputVector);       //Get angle from found vector
        rotationalInput += transform.rotation.eulerAngles.z;                        //Factor in rotation of player
        while (rotationalInput > 180)
        {
            rotationalInput -= 360;                               //Wrap input around until it fits within -180-180 scale
        }
        rotationalInput = -rotationalInput.Map(-180, 180, -1, 1); //Remap found value to more easily-readable scale

        //Create and Apply Movement Data:
        newMoveInput.moveDirection = directionalInput; //Set directional input data in new struct
        newMoveInput.spinDirection = rotationalInput;  //Set rotational input data in new struct
        moveInput = newMoveInput;                      //Apply new moveInput data

        //..Xx Debuggers xX.................................................................................
        //Debug.Log("Player FaceDirection = " + rotationalInput); //Check that angle of mouseInput is correct
        //Debug.Log("Mouse angle to player = " + rotationalInput.ToString()); //Check that angle of mouse input is correct
        //Debug.Log("Player rotation = " + transform.rotation.eulerAngles.z); //Check actual rotation of player
    }
Exemplo n.º 2
0
    private void UpdatePhysics()
    {
        //Description: Update player physics properties based on input, settings, and environmental factors

        //LINEAR VELOCITY:
        //Initialization & Validation:
        Vector2 newVelocity = velocity;     //Initialize vector for calculating final updated velocity
        Vector2 inputAccelDirection;        //Initialize vector for factoring direction into acceleration vector
        float   strafeModifier = 1;         //Initialize variable for factoring strafe direction into velocity calculations

        //Calculate Strafing Modifier:
        if (rotationMode == RotationMode.Controlled)
        {
            Vector2 moveDirection = moveInput.moveDirection.normalized;                         //Get direction of input
            Vector2 faceDirection = Vector2.up.Rotate(transform.rotation.eulerAngles.z);        //Get player entity is pointing
            float   strafeAngle   = -Vector2.SignedAngle(faceDirection, moveDirection);         //Get angle disparity between facing direction and direction of acceleration
            strafeAngle    = strafeAngle.Map(-180, 180, -1, 1);                                 //Map angle into more AnimationCurve-friendly values
            strafeModifier = physicsSettings.strafeVelFalloff.Evaluate(Mathf.Abs(strafeAngle)); //Get modifier from physicsSettings
        }

        //Calculate Input:
        if (moveInput.moveDirection != Vector2.zero)                   //If directional input from player is detected...
        {
            float actualAccel = ScaleAccel(physicsSettings.baseAccel); //Get relevant accel value from player settings (scaled appropriately to runtime properties)
            inputAccelDirection  = moveInput.moveDirection;            //Set vector direction equal to direction of input
            inputAccelDirection *= actualAccel;                        //Apply found acceleration to direction vector to get working acceleration vector
        }
        else                                                           //If no directional input from player is detected...
        {
            float actualAccel = ScaleAccel(physicsSettings.idleDecel); //Get relevant accel value from player settings (scaled appropriately to runtime properties)
            inputAccelDirection  = velocity.normalized * -1;           //Set input vector to reverse of current movement direction
            inputAccelDirection *= actualAccel;                        //Apply found acceleration to direction vector to get working acceleration vector
        }

        //Apply Factors to New Velocity:
        inputAccelDirection *= strafeModifier;                                                               //Apply strafing velocity curve to change in acceleration
        newVelocity         += inputAccelDirection;                                                          //Apply acceleration due to input
        float maxVelocity = physicsSettings.maxVelocity;                                                     //Get maximum velocity

        if (newVelocity.magnitude > maxVelocity)                                                             //If new velocity exceeds maximum velocity setting...
        {
            newVelocity = newVelocity.normalized * maxVelocity;                                              //Cap velocity at maximum
        }
        if (moveInput.moveDirection == Vector2.zero && newVelocity.magnitude < physicsSettings.decelSnapVel) //If player is coasting and has reached snap velocity...
        {
            newVelocity = Vector2.zero;                                                                      //Set velocity to zero
        }

        //ANGULAR VELOCITY:
        //Initialization & Validation:
        float newAngVelocity = angularVelocity;     //Initializa variable for calculating final velocity

        //Calculate Input:
        if (rotationMode == RotationMode.Controlled)     //CONTROLLED: If player rotation is currently locked to mouse...
        {
            //Find Target Change:
            float targetChange = moveInput.spinDirection.Map(-1, 1, -180, 180);                                   //Initialize variable for finding target change in degrees for this rotation (starting with current mouse angle from player)
            targetChange = Mathf.Lerp(0, targetChange, physicsSettings.mouseTurnStiffness);                       //Find actual target change (in degrees) based on player physics settings
            if (Mathf.Abs(targetChange) > physicsSettings.maxControlAngVel * Time.fixedDeltaTime)                 //If target change exceeds maximum controlled angular velocity...
            {
                targetChange = physicsSettings.maxControlAngVel * Time.fixedDeltaTime * Mathf.Sign(targetChange); //Set change to max
            }
            //Apply to Velocity:
            newAngVelocity = targetChange;                                                                      //Set found change in degrees as new angular velocity
        }
        else if (rotationMode == RotationMode.Free)                                                             //FREE: If player rotation is currently unlocked...
        {
            float targetVel = GetMomentumTierVel(momentumTier) * Time.fixedDeltaTime;                           //Get shorthand for target velocity
            if (!HotteMath.Approx(angularVelocity, targetVel, physicsSettings.momentumSnapThresh))              //If velocity is not currently where it should be for player's momentum tier...
            {
                newAngVelocity = Mathf.Lerp(angularVelocity, targetVel, physicsSettings.momentumSnapStiffness); //Lerp velocity toward target for given tier
            }
            else                                                                                                //If angular velocity is more-or-less aligned with momentum tier...
            {
                newAngVelocity = targetVel;                                                                     //Set velocity to exact value for tier
            }
        }

        //Cleanup:
        velocity        = newVelocity;    //Update velocity vector
        angularVelocity = newAngVelocity; //Update angular velocity vector

        //..Xx Sub-Methods xX...............................................................................
        float ScaleAccel(float givenAccel)
        {
            //Description: Scales actualAccel to universal game factors, ensuring stability and reliability

            //Initialization & Validation:
            float actualAccel = givenAccel; //Initialize value to scale and return

            //Apply Scaling Factors:
            actualAccel *= Time.fixedDeltaTime;                                                            //Scale acceleration to game time (UpdatePhysics should be called in FixedUpdate)
            actualAccel *= HotteMath.Mean(new float[] { transform.localScale.x, transform.localScale.y }); //Scale acceleration to actual size of player object (preventing settings from being fixed to character scale)

            //Cleanup
            return(actualAccel); //Return scaled acceleration value
        }

        float GetMomentumTierVel(int tier)
        {
            //Description: Finds velocity of given momentum tier in player physics settings

            //Initialization & Validation:
            if (tier == 0)
            {
                return(0);                                                                 //Teir zero will always have a velocity of 0, allowing the rest of the method to be skipped
            }
            float[] momentumTeirVels = physicsSettings.momentumTierVels;                   //Get shorthand for tier velocities
            if (momentumTeirVels.Length == 0)                                              //Check to make sure physicsSettings contain minimum data requirements...
            {
                Debug.LogError("Player does not have assigned momentum teir velocities."); //Log error
                return(0);                                                                 //Return zero to prevent crash
            }
            float foundVel = momentumTeirVels[momentumTeirVels.Length - 1];                //Initialize return variable to last item in given array (max momentum)

            //Find Corresponding Velocity:
            if (Mathf.Abs(tier) < momentumTeirVels.Length)        //If tier has a corresponding velocity in given settings list...
            {
                foundVel = momentumTeirVels[Mathf.Abs(tier) - 1]; //Get velocity from corresponding item in array
            }

            //Cleanup:
            foundVel *= Mathf.Sign(tier); //Carry over sign from tier (for negative rotation)
            return(foundVel);             //Return found velocity corresponding with given momentum tier
        }

        //..Xx Debuggers xX.................................................................................
        //Debug.Log("RotInputAccelDirection = " + rotInputAccelDirection); //Check angular acceleration factor
        //Debug.Log("NewAngularVelocity = " + newAngVelocity); //Check newly-calculated angular velocity
        //Debug.Log("Angular Acceleration = " + actualAngAccel); //Check how much player is trying to accelerate based on input
    }