• Character Movement

  • Camera

WHAT I WORKED ON

Role:

Gameplay Programmer

Language:

C#

Engine:

Unity 6

Team Size:

14

Project Duration:

3 weeks

Little Sprout

  • Little Sprout is a side scrolling platformer where the player has to reach the top of a tree.


  • The game for this project was supposed to be designed to work with the Xbox adaptive controller for accessibility. It was decided that the game would have only two controls - jumping and obstacle toggles.


  • The player character moves on it's own, along a face of a tree, and when they reach a corner, they rotate to a new face, similar to how the indie game "Fez" works.


  • You can jump and toggle vines to make them appear and disappear. If you hit a wall, you start moving in the opposite direction, similar to how "Super Mario Run" works.


OVERVIEW

  • I implemented a simple state machine for both the game state and the player state.


  • The player state machine contained states for moving, jumping, pause and being idle.


  • The game state machine contained states for pausing, playing and a state for when the player would turn around a corner.



CHARACTER MOVEMENT

  • Designers wanted a camera that would rotate around a corner to a new face, similar to how it behaves in the indie game, "Fez".


  • I programmed a simple camera follow that followed the player with a lerp for a smooth effect.


  • As for the camera rotating around the corner, I used simple unit circle calculations to estimate the world position of the camera on a unit circle.


  • The camera would rotate around the unit circle until it would face the player in the intended facing axis. To ensure there are no bugs related to rotation, I made sure that the maximum rotation that the camera would achieve around the unit circle would be no more than 90 degrees, after which it would stop rotating and resume following the player.



CAMERA

(C#) Rotating Around a Corner

//Coroutine that updates camera position around unit circle
    private IEnumerator RotateAroundCorner()
    {
        float currentTimeStep = 0f;
        float startingPosOnUnitCircle = _currentCamPosOnUnitCircle;
        while (currentTimeStep/_timeToFinishRotation <= 1f)
        {
            _currentCamPosOnUnitCircle = Mathf.Lerp(startingPosOnUnitCircle,
                                                    _finalCamPosOnUnitCircle,
                                                    currentTimeStep/_timeToFinishRotation);
            UpdateCameraPositionAroundCorner();
            AlignCameraWithPlayer();
            currentTimeStep += Time.deltaTime;
            yield return null;
        }
        OnCameraFinishedRotating();
    }
    private void UpdateCameraPositionAroundCorner()
    {
        Vector3 currentRotPosition =
            new Vector3(Mathf.Cos(_currentCamPosOnUnitCircle), 0f,
                Mathf.Sin(_currentCamPosOnUnitCircle)) * _rotationRadius;
        transform.position += currentRotPosition * Time.deltaTime;
    }

    private void AlignCameraWithPlayer()
    {
        //Maintains height offset and X-axis rotational offset while rotating along the corner.
        Vector3 camPositionInWorldSpaceWithHeight = transform.position;
        camPositionInWorldSpaceWithHeight.y = _target.transform.position.y + _yOffset;

        transform.position = camPositionInWorldSpaceWithHeight;
        transform.LookAt(_target.gameObject.transform.position);
        transform.eulerAngles =
            new Vector3(_rotationOffsetAlongXAxis,
                transform.eulerAngles.y, transform.eulerAngles.z

gaurdian.kiran@gmail.com

+46 769666977

Contact: