PROJECT DESCRIPTION

Alternate Projections is another one of my intresting ideas I had for a platformer, instead of switching gravity (which I did for gravikinesis), I also wanted to experiment with something further, perspective and projection. Utilising 3D and 2D based gameplay in this game with the help of Unity's different camera types.

 

This game is still under development and will be put away for some time as most of my focus will go towards college work and ROLLCORE REMASTERED. However do keep an eye out for changes when they do come and arrive!

! PLAY HERE !

This is only a prototype of the game, assume updates to be launched here

GAME DESIGN DOCUMENT

HIGHLIGHT IDEAS GENERATION

MAIN MECHANIC

 

The flow chart above shows my rough plan on how I would plan out the implemntation of the main mechanic for Alternate Projections, that being how I will be able to switch from a 3D to 2D and vice versa. The main keybind to execute this will be "e" and if the player was to press it I plan to use cinemachine functionalities to help move the main camera to the oposing cinemachine camera and can do this with changing the priorities of the two cameras. Once thats complete I plan to toggle a boolean that locks 3D movement, restricting it to only left, right up and down. 

 

My idea to implement 2D and 3D manipulated feels was to have a copy of the 3D level and have it lay exactly on the same Y and Z level but move it abit away, with the help of orthographoc views, I would be able to hide the two levels and make them look as one. 

HIGHLIGHT CODE SNIPPETS


        public class SwitchProjection : MonoBehaviour
{
    [SerializeField] Transform _transform2D;
    [SerializeField] public CinemachineCamera _2Dcam;
    [SerializeField] CinemachineCamera _3Dcam;

    [SerializeField] FirstPersonController _firstPersonController;
    [SerializeField] Generate2DWorld _generate2DWorld;

    private CinemachineBrain _CinemachineBrain;
    private bool _InTransition = false;
    private float _BlendDuration;

    private float _tempPosStorage;

    private void Start()
    {
        _firstPersonController = GetComponent(); 
        _CinemachineBrain = Camera.main.GetComponent();

        _BlendDuration = _CinemachineBrain.DefaultBlend.Time;

        _tempPosStorage = transform.position.z;
    }
    public void AlternateProjection()
    {
        if(_InTransition) // cancel switch if already switching
        { return; }

        if(_3Dcam.IsLive)
        {
            // Switching to 2D
            _2Dcam.Priority = 1;
            _3Dcam.Priority = 0;
        }
        else
        {
            // Switching to 3D
            _2Dcam.Priority = 0;
            _3Dcam.Priority = 1;

            _generate2DWorld.HideWorld(); // hides the 2D Copy of the level

            _firstPersonController._controller.enabled = false;
            transform.position = new Vector3(transform.position.x, transform.position.y, _tempPosStorage); // moves player back to the 3D level
            _firstPersonController._controller.enabled = true;

            Camera.main.orthographic = false;  // turns off 2D manipulation
        }
        StartCoroutine(TransitionDuration(_BlendDuration)); // starts switch transition countdown
        _firstPersonController.Lock3DMovement = !_firstPersonController.Lock3DMovement; // maniupulates movement allowence
    }

    private IEnumerator TransitionDuration(float Time)
    {
        _InTransition = true; // switch started
        yield return new WaitForSeconds(Time);
        _InTransition = false; // switch finihsed

        if(_2Dcam.IsLive)
        {
            Camera.main.orthographic = true; // further 2D manipulation
            _generate2DWorld.ShowWorld(); // shows copy of 2D world for user interaction

            _firstPersonController._controller.enabled = false; 
            transform.position = new Vector3(transform.position.x, transform.position.y, _transform2D.position.z); // moves player to the 2D Copy of the level
            _firstPersonController._controller.enabled = true;
        }
    }
}
        

         public class Generate2DWorld : MonoBehaviour
{
    [SerializeField] Transform Teleport2D;
    [SerializeField] Transform Parent3D;
    [SerializeField] bool Starts2D;
    private void Start()
    {
        if (!Starts2D)
        {
            gameObject.SetActive(false);
        }

        foreach (Transform child in Parent3D)
        {
            GameObject CurrentObject = Instantiate(child.gameObject, new Vector3(child.transform.position.x, child.transform.position.y, Teleport2D.position.z), child.transform.rotation, transform);
        }
    }

    public void HideWorld()
    {
        gameObject.SetActive(false);
    }

    public void ShowWorld()
    {
        gameObject.SetActive(true);
    }
}

          

         public class Kill : MonoBehaviour
{
    [SerializeField] Transform StartPos;
    private SwitchProjection switchProjection;
    private FirstPersonController firstPersonController;
    private CharacterController CharacterController;

    private void Start()
    {
        switchProjection = GetComponent();
        firstPersonController = GetComponent();
        CharacterController = GetComponent();

    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Kill"))
        {
            Debug.Log("Dead");

            CharacterController.enabled = false;
            firstPersonController.enabled = false;
            transform.position = StartPos.position;

            if (switchProjection._2Dcam.IsLive)
            {
                Vector3 holdPosition = new Vector3(transform.position.x, transform.position.y, switchProjection._transform2D.position.z);
                transform.position = holdPosition;
            }

            firstPersonController.enabled = true;
            CharacterController.enabled = true;
        }
    }
}
          

ASSETS/TEXTURES/AUDIO USED

Animations present in the prototype was found on mixamo, and part of the Mixamo Action Adventrurethought of going with this animation pack due to its simplicity and ease of implementation.  

I thought for a prototype a voxel-ish model would look nice and would really go well in both the style of game that Alternate Projections could be set on. I just used this persons model and discluded the animations they created as well as any other scripts or assets attached to it, this belongs to Explosive and found on the unity asset store.

This is a simple a modular kit that I used to decorate and gather insight on what environments I will want to implement, these assets belong to and were created by Neon3D.