AlICe

Research →
Teaching →
Media →
Filters : Code[x]
The Missing Camera or: How I Learned to Stop Worrying and Love Oblique Projection
2024
Code Tracing
2023
Formal Analysis and Computer Process - Algorithmic Music II/II
2022
Misreading, once again...
2022
Formal Analysis and Computer Process - Algorithmic Music I/II
2021
[x] Noise
2021
Pohlke: One-Click Standard Orthographic and Oblique Projection Cameras
2021
Perspectiva Virtualis
2021
Formal Analysis and Computer Process - The Algorists
2020
Formal Analysis and Computer Process - Medley II/II
2019
Building Drawings : Decoding and Recoding the Graphic Projection Algorithm in Architectural Representation
2019
Places Royales Françaises. Réflexion d’une logique d’édification à travers une corrélation entre une analyse sémantique et un signal géométrique
2018
Formal Analysis and Computer Process - Medley I/II
2018
Jean-Nicolas-Louis Durand’s Clockwork
2018
Caractérisation de formes architecturales. Une approche expérimentale intégrant complexité et intelligibilité des représentations numériques
2016
Architectural Analysis & Computer Process IV
2016
Architectural Analysis & Computer Process III
2015
Jean-Nicolas-Louis Durand - Representation as Instrument
2015
Architectural Analysis & Computer Process II
2014
Education in Architectural Analysis through Hybrid Graphic Means: a Setup for Critical Thinking
2014
Architectural Analysis & Computer Process I
2013

Noise

Author(s): Julien Rippinger, Raphael Ridder, Jan Schweizer

Contribution to the VOLUPTAS World At Play Summer School // Professur Charbonnet/Heiz (ETH Zurich D-ARCH) // 21-26 June 2021.

Download Link

// Noise Video Game Script: switch to bird eye and zoom out on certain events.
// Copyright (C) 2021 Julien Rippinger
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.


//  _   _  ___ ___ ____  _____
// | \ | |/ _ \_ _/ ___|| ____|
// |  \| | | | | |\___ \|  _|
// | |\  | |_| | | ___) | |___
// |_| \_|\___/___|____/|_____|
//

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SwitchCamera : MonoBehaviour
{

//                  _       _     _
// __   ____ _ _ __(_) __ _| |__ | | ___  ___
// \ \ / / _` | '__| |/ _` | '_ \| |/ _ \/ __|
//  \ V / (_| | |  | | (_| | |_) | |  __/\__ \
//   \_/ \__,_|_|  |_|\__,_|_.__/|_|\___||___/
//

    public Camera CameraPerspective;
    public Camera CameraAxonometry;
    public GameObject Avatar;
    public Light Sun;
    public AudioSource AudioSourceAxono;
    public AudioSource AudioSourceSoundtrack;
    public AudioSource AudioSourceVoice;
    public Text m_MyText;
    public Text title_Text;

    private GameObject[] points;
    private GameObject[] portals;
    private Collider[] collision_objects;
    private Vector3 newPosition;
    private int index;
    private int newindex;
    private bool startZoom = true;
    private bool zoomOut;
    private bool game_finished;
    private bool already_run;
    private float timeLeft;
    // private int nbrPoints;

    // Game Parameters
    private float maxTime = 109.0f; // +10 = 120
    private float timeIncrease = 10.0f;

    // Start is called before the first frame update

//  _       _ _   _       _   _
// (_)_ __ (_) |_(_) __ _| |_(_) ___  _ __
// | | '_ \| | __| |/ _` | __| |/ _ \| '_ \
// | | | | | | |_| | (_| | |_| | (_) | | | |
// |_|_| |_|_|\__|_|\__,_|\__|_|\___/|_| |_|
//

    void Start()
    {
        // AudioSourceAxono.Stop();
        CameraPerspective.enabled = true;
        CameraAxonometry.enabled = false;
        CameraAxonometry.orthographicSize = 1f;
        // teleportation points list
        points = GameObject.FindGameObjectsWithTag("Point");
        portals = GameObject.FindGameObjectsWithTag("Portal");
        // nbrPoints = points.Length;
        // initial index for teleportation
        // index = Random.Range(0,nbrPoints);
        // m_MyText.text = "";
        timeLeft = maxTime;
        //Zoom();
    }

//                  _       _
//  _   _ _ __   __| | __ _| |_ ___  ___
// | | | | '_ \ / _` |/ _` | __/ _ \/ __|
// | |_| | |_) | (_| | (_| | ||  __/\__ \
// \__,_ | .__/ \__,_|\__,_|\__\___||___/
//       |_|
//

    // Update is called once per frame
    void Update()
    {
        // countdown display
        float seconds = timeLeft%60;
        float minutes = Mathf.Floor(timeLeft / 60);
        if(!game_finished)
        {
            string time = minutes.ToString("00") + ":" + seconds.ToString("00.00");
            m_MyText.text = time;
        }
        // countdown
        timeLeft -= Time.deltaTime;
        if((timeLeft < 0) && (!already_run) &&(!game_finished))
        {
            startZoom = true;
        }
        Zoom();
    }

    void FixedUpdate()
    {
        collision_objects = Physics.OverlapSphere(transform.position, 1.0f);

        if(collision_objects.Length > 0)
        {
            foreach(Collider obj in collision_objects)
            {
                // check if player reached an antenna/portal
                if((obj.tag == "Portal") && (!already_run))
                {
                    title_Text.text = "Citizen of Proteus\nYou have contributed to our shared vision";
                    game_finished = true;
                    startZoom = true;
                    Zoom();
                }
                //Debug.Log("collision with:" + obj.tag);
            }
            //Debug.Log("collision : " + Physics.OverlapSphere(transform.position, 2.0f));
        }
    }

//                _
//  ___ _   _ ___| |_ ___  _ __ ___
// / __| | | / __| __/ _ \| '_ ` _  \
// |( _| |_| \__ \ || (_) | | | | | |
// \___|\__,_|___/\__\___/|_| |_| |_|
//

    void Zoom()
    {
        // initiate zoom out
        if(startZoom)
        {
            // start shepard sound
            AudioSourceAxono.Play();
            AudioSourceSoundtrack.Pause();
            AudioSourceVoice.Pause();

            // set sun for axo convetion
            PositionSun();
            // make the switch
            CameraPerspective.enabled = false;
            CameraAxonometry.enabled = true;
            zoomOut = true;
            already_run = true;
            // increment timer
            maxTime += timeIncrease;
            // force execute once
        }

        // perform zoom out
        if (zoomOut)
        {
            // zoom out
            CameraAxonometry.orthographicSize += 0.1f;
            m_MyText.text = "";
            startZoom = false;
        }

        // terminate zoom
        if (CameraAxonometry.orthographicSize > 240) //175
        {
            if(game_finished)
            {
                //quit game or switch to next scene
                Application.Quit();
            }

            // earase title
            title_Text.text = "";
            //stop zoom
            already_run = false;
            zoomOut = false;
            // stop shepard sound
            AudioSourceVoice.Play();
            AudioSourceSoundtrack.Play();
            AudioSourceAxono.Stop();
            // switch back to 1st person
            CameraAxonometry.enabled = false;
            CameraPerspective.enabled = true;
            // switch cast shadows on
            Sun.shadows = LightShadows.Soft;
            // reset axono
            CameraAxonometry.orthographicSize = 1f;
            // teleport player
            Teleportation();
            // reset timer
            timeLeft = maxTime;
        }

    }

    void PositionSun()
    {
        // no shadows
        // Sun.transform.forward = CameraAxonometry.transform.forward;

        // conventional shadows
        Sun.transform.forward = CameraAxonometry.transform.forward;
        Sun.transform.Rotate(0.0f, 135.0f , 0.0f, Space.World);
        Sun.shadows = LightShadows.None;
    }

    void Teleportation()
    {
        // random index selection
        // newPosition = new Vector3(points[index].transform.position.x, points[index].transform.position.y, points[index].transform.position.z);
        newPosition = GetClosestPoint(points);
        // move avatar into new position
        Avatar.transform.position = newPosition;
        int roatation = Random.Range(0, 360);
        Avatar.transform.Rotate(0.0f, roatation , 0.0f, Space.Self);
        //nex index different than previous one
        // newindex = Random.Range(0,nbrPoints); // between 0 and 31
        // while(newindex == index)
        // {
        //    newindex = Random.Range(0,nbrPoints);
        // }
        // index = newindex;
        // reset shadows
        //Sun.shadows = LightShadows.Soft;
    }

//        _   _ _
//  _   _| |_(_) |___
// | | | | __| | / __|
// | |_| | |_| | \__ \
//  \__,_|\__|_|_|___/
//

    Vector3 GetClosestPoint(GameObject[] point_list)
    {
        Vector3 tMin = new Vector3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity);
        float minDist = Mathf.Infinity;
        Vector3 currentPos = transform.position;
    	foreach (GameObject point in point_list)
            {
                float dist = Vector3.Distance(point.transform.position, currentPos);
                if (dist < minDist)
                {
                    tMin = new Vector3(point.transform.position.x,
                                       point.transform.position.y,
                                       point.transform.position.z);
                    minDist = dist;
                }
            }
        return tMin;
    }

}