Description:
This game simulates the classic "Trolley Problem" such that the user is tasked with choosing who dies in the given scenario. The user views the scenario and decides whether or not to pull the lever by clicking the corresponding buttons. Doing nothing is "letting 5 die" whereas pulling the lever is like "killing 1 person".
Technical Steps:
1. I created the main game scene and imported necessary assets (ie. trolley, tracks, decor).
2. Outlined out the TrolleySimLogic script for each function in the game.
----includes coroutine to sequentially call each function with added timers for improved experience.
3. Animated the trolley so that it moves on the track based on the input.
4. Added my particle-blood splatter-thingy on the people so that they look like they get run over.
----uses for loop to instantiate a bunch of blocks
5. Added a beginning and ending scene so that the user can play the game in a loop.
Imported Assets:
https://assetstore.unity.com/packages/3d/characters/city-people-lite-260446
https://assetstore.unity.com/packages/3d/environments/railway-sleepers-95855
https://assetstore.unity.com/packages/3d/vehicles/land/industrial-train-dr14-162567
https://assetstore.unity.com/packages/3d/environments/landscapes/polydesert-107196
TrolleySimLogic SCRIPT
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
using UnityEngine.UI;
public class TrolleySimLogic : Singleton<TrolleySimLogic>
{
{
public bool buttonPress = false;
public Button doNothing;
public Button pullLever;
public GameObject inputCanvas;
public Button doNothing;
public Button pullLever;
public GameObject inputCanvas;
private int sceneIndex = 1;
public int[] answers = new int[3];
public int[] answers = new int[3];
private void Awake()
{
DontDestroyOnLoad(this);
}
{
DontDestroyOnLoad(this);
}
void Start()
{
{
StartCoroutine(TrolleySet());
inputCanvas.SetActive(false);
doNothing.onClick.AddListener(answerDN);
pullLever.onClick.AddListener(answerPL);
}
inputCanvas.SetActive(false);
doNothing.onClick.AddListener(answerDN);
pullLever.onClick.AddListener(answerPL);
}
IEnumerator TrolleySet()
{
//moves trolley from off screen to rest position
TrolleyMovement.Instance.initialPositionAnim();
{
//moves trolley from off screen to rest position
TrolleyMovement.Instance.initialPositionAnim();
//waits for animation to be done
yield return new WaitForSeconds(2);
yield return new WaitForSeconds(2);
//starts DisplayUI coroutine
StartCoroutine(DisplayUI());
}
StartCoroutine(DisplayUI());
}
IEnumerator DisplayUI()
{
//set ui active
inputCanvas.SetActive(true);
{
//set ui active
inputCanvas.SetActive(true);
//wait until button gets pressed
while (!buttonPress) yield return null;
while (!buttonPress) yield return null;
//set ui inactive
inputCanvas.SetActive(false);
inputCanvas.SetActive(false);
//wait then start PlayTrolleyAnimation coroutine
yield return new WaitForSeconds(.2f);
StartCoroutine(PlayTrolleyAnimation());
}
yield return new WaitForSeconds(.2f);
StartCoroutine(PlayTrolleyAnimation());
}
IEnumerator PlayTrolleyAnimation()
{
TrolleyMovement.Instance.mainAnim(answers[sceneIndex]);
yield return new WaitForSeconds(9);
SceneManager.LoadScene("AssignmetEnd");
{
TrolleyMovement.Instance.mainAnim(answers[sceneIndex]);
yield return new WaitForSeconds(9);
SceneManager.LoadScene("AssignmetEnd");
//sceneIndex++;
//Debug.Log(sceneIndex);
//if (SceneManager.GetActiveScene().name.Equals("Prompt01"))
//{
// SceneManager.LoadScene("Prompt02");
//}else if (SceneManager.GetActiveScene().name.Equals("Prompt02"))
//{
// SceneManager.LoadScene("Prompt03");
//}
//else
//{
// SceneManager.LoadScene("End");
//}
//Debug.Log(sceneIndex);
//if (SceneManager.GetActiveScene().name.Equals("Prompt01"))
//{
// SceneManager.LoadScene("Prompt02");
//}else if (SceneManager.GetActiveScene().name.Equals("Prompt02"))
//{
// SceneManager.LoadScene("Prompt03");
//}
//else
//{
// SceneManager.LoadScene("End");
//}
}
//sceneIndex++;
public void answerDN()
{
answers[sceneIndex] = 0;
buttonPress = true;
Debug.Log("0");
}
{
answers[sceneIndex] = 0;
buttonPress = true;
Debug.Log("0");
}
public void answerPL()
{
buttonPress = true;
answers[sceneIndex] = 1;
Debug.Log("1");
}
{
buttonPress = true;
answers[sceneIndex] = 1;
Debug.Log("1");
}
TrolleyMovement Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Collections.Generic;
using UnityEngine;
public class TrolleyMovement : Singleton<TrolleyMovement>
{
private Vector3 trolleyStartPos = new Vector3(0, 0, -53);
private Vector3 trolleyRestPos = new Vector3(0, 0, -5);
{
private Vector3 trolleyStartPos = new Vector3(0, 0, -53);
private Vector3 trolleyRestPos = new Vector3(0, 0, -5);
public GameObject curvedTrack;
public GameObject straightTrack;
public GameObject straightTrack;
public Animator anim;
private void Start()
{
{
//anim = gameObject.GetComponent<Animation>();
transform.position = trolleyStartPos;
straightTrack.SetActive(true);
curvedTrack.SetActive(false);
}
transform.position = trolleyStartPos;
straightTrack.SetActive(true);
curvedTrack.SetActive(false);
}
public void initialPositionAnim()
{
anim.SetTrigger("Get Set");
}
{
anim.SetTrigger("Get Set");
}
public void mainAnim(int i)
{
if(i == 0)
{
//straight animation;
anim.SetTrigger("Straight");
}
if(i == 1)
{
{
if(i == 0)
{
//straight animation;
anim.SetTrigger("Straight");
}
if(i == 1)
{
//set track
straightTrack.SetActive(false);
curvedTrack.SetActive(true);
//curved animation;
anim.SetTrigger("Curved");
}
}
}
straightTrack.SetActive(false);
curvedTrack.SetActive(true);
//curved animation;
anim.SetTrigger("Curved");
}
}
}
personLogic Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Collections.Generic;
using UnityEngine;
using System;
public class personLogic : MonoBehaviour
{
private float xPos, yPos, zPos;
private float xVal, zVal;
private float posModerator, posOffset;
{
private float xPos, yPos, zPos;
private float xVal, zVal;
private float posModerator, posOffset;
private float raidNum = 100;
private float spacing = .1f;
private float spacing = .1f;
private GameObject myPrefab;
private GameObject cubeIndexer;
private GameObject cubeIndexer;
private void Start()
{
myPrefab = Resources.Load("Cube") as GameObject;
posModerator = spacing * (int)Math.Sqrt(raidNum);
posOffset = posModerator / 2;
}
{
myPrefab = Resources.Load("Cube") as GameObject;
posModerator = spacing * (int)Math.Sqrt(raidNum);
posOffset = posModerator / 2;
}
private void OnTriggerEnter(Collider other)
{
{
if (other.gameObject.tag == "Player")
{
Debug.Log("Trigger Entered");
{
Debug.Log("Trigger Entered");
xPos = transform.position.x;
yPos = transform.position.y;
zPos = transform.position.z;
xVal = 0;
zVal = -posOffset;
System.Random rndm = new System.Random();
for (int i = 0; i < raidNum; i++)
{
Vector3 spawnPos = new Vector3((xVal % posModerator) - posOffset + xPos, yPos, zVal + zPos);
cubeIndexer = Instantiate(myPrefab, spawnPos, Quaternion.identity);
Debug.Log(spawnPos);
//cubeIndexer.transform.GetComponent<Renderer>().material.color = Color.red;
xVal += spacing;
if (xVal % posModerator == 0)
{
zVal += spacing;
}
}
destroySelf();
if (xVal % posModerator == 0)
{
zVal += spacing;
}
}
destroySelf();
}
}
}
void destroySelf()
{
Destroy(this.gameObject);
}
}
{
Destroy(this.gameObject);
}
}
StartLogic Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
using UnityEngine.UI;
public class StartLogic : MonoBehaviour
{
public Button startButton;
{
public Button startButton;
// Start is called before the first frame update
void Start()
{
startButton.onClick.AddListener(switchScene);
}
void Start()
{
startButton.onClick.AddListener(switchScene);
}
void switchScene()
{
SceneManager.LoadScene("Prompt01");
}
}
{
SceneManager.LoadScene("Prompt01");
}
}
EndLogic Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
using UnityEngine.UI;
public class endLogicScript : MonoBehaviour
{
public Button restartButton;
{
public Button restartButton;
// Start is called before the first frame update
void Start()
{
restartButton.onClick.AddListener(backToStart);
//StartCoroutine(DisplayUI());
}
void Start()
{
restartButton.onClick.AddListener(backToStart);
//StartCoroutine(DisplayUI());
}
IEnumerator DisplayUI()
{
yield return new WaitForSeconds(1);
{
yield return new WaitForSeconds(1);
}
void backToStart()
{
SceneManager.LoadScene("Start");
}
}
{
SceneManager.LoadScene("Start");
}
}