Game programmer on Exodroid
Wednesday, April 8th, 2009While doing my MSc in Medialogy, I took part in two productions at DADIU (Danish Academy for Digital Interactive Entertainment).
My second production was called Exodroid and was made in Unity3D using C# and Visual Studio Express. This production took place in March 2009 while I was writing my essay and master thesis , so these are somewhat interconnected.
As game programmer on this project, I gained experience using C# with Unity3D. Furthermore, I took an active part in developing the design and the production itself.
I participated in the project while writing my master thesis, therefore much of the discussion and conclusion is somewhat related to this project.
Simple C# script to trigger theme music at certain points in the game:
using System.Collections;
public enum ThemeFader
{
FirstToSecond = 0,
SecondToThird = 1
}
// Put this script on the triggerbox that has to change the theme music
public class AudioThemeTrigger : MonoBehaviour
{
// enable these controls in the editor
public float fadeTime = 5.0f;
public ThemeFader themeFader;
private bool triggered = false;
private GameObject player;
private Transform AudioTheme1;
private Transform AudioTheme2;
private Transform AudioTheme3;
void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
AudioTheme1 = Helper.getChildByName(player.transform, "AudioTheme1");
AudioTheme2 = Helper.getChildByName(player.transform, "AudioTheme2");
AudioTheme3 = Helper.getChildByName(player.transform, "AudioTheme3");
switch (themeFader)
{
case ThemeFader.FirstToSecond:
AudioTheme1.transform.audio.volume = 0.7f;
AudioTheme2.transform.audio.volume = 0.0f;
AudioTheme3.transform.audio.volume = 0.0f;
break;
case ThemeFader.SecondToThird:
AudioTheme2.transform.audio.volume = 0.7f;
AudioTheme3.transform.audio.volume = 0.0f;
break;
default:
break;
}
}
void Update()
{
if (triggered)
{
switch (themeFader)
{
case ThemeFader.FirstToSecond:
CrossfadeAudio(AudioTheme1,AudioTheme2);
break;
case ThemeFader.SecondToThird:
CrossfadeAudio(AudioTheme2,AudioTheme3);
break;
default:
break;
}
}
}
private void CrossfadeAudio(Transform t1, Transform t2)
{
if (t1.transform.audio.volume > t1.transform.audio.minVolume)
{
//fade out
t1.transform.audio.volume -= t1.transform.audio.maxVolume * Time.deltaTime / fadeTime;
}
else
{
t1.transform.audio.volume = 0.0f;
t1.transform.audio.Stop();
}
if (!t2.transform.audio.isPlaying)
{
//start the new sound if it is not allready running
t2.transform.audio.Play();
}
if (t2.transform.audio.volume < t2.transform.audio.maxVolume)
{
//fade in
t2.transform.audio.volume += t2.transform.audio.maxVolume * Time.deltaTime / fadeTime;
}
else if (t1.transform.audio.volume <= t1.transform.audio.minVolume) triggered = false;
}
void OnTriggerEnter(Collider collider)
{
if (collider.gameObject.tag == "Player")
{
triggered = true;
}
}
}
A little C# helper for some tedious tasks:
using System.Collections;
using System;
using System.Collections.Generic;
public static class Helper
{
static AudioClip lastClip;
// Get the first child transform with the speified name
public static Transform getChildByName(Transform transform, string name)
{
for (int i = 0; i < transform.GetChildCount(); i++)
{
if (transform.GetChild(i).name == name) return transform.GetChild(i);
}
throw new Exception("Cound not find child " + name + " in " + transform.name);
}
// Returns a random audio clip from the specified array of AudioClips
public static AudioClip getRandomAudioClip(AudioClip[] clips)
{
if (clips != null)
{
// Create a list with available clips
List<AudioClip> clipsToChoose = new List<AudioClip>(clips);
// Remove the previous clip from the list if it is there
if (lastClip != null)
{
for (int i = 0; i < clipsToChoose.Count; i++)
{
if (clipsToChoose[i].name == lastClip.name)
{
clipsToChoose.RemoveAt(i);
break;
}
}
}
if (clipsToChoose.Count > 0)
{
int randomNb = UnityEngine.Random.Range(0, clipsToChoose.Count);
lastClip = clipsToChoose[randomNb];
return clipsToChoose[randomNb];
}
else throw new Exception("At least one audioclip has to be passed");
}
else
{
throw new Exception("At least one audioclip has to be passed");
}
}
public static float adjustVolumeToDistance(GameObject soundSource, float distanceToZeroVol)
{
GameObject player = GameObject.FindGameObjectWithTag("Player");
//getting distance to camera
float distance = Vector3.Distance(soundSource.transform.position, player.transform.position);
//calculate newVolume
float newVol = 1 - (distance / distanceToZeroVol);
//scale according to maxVolume
newVol *= soundSource.audio.maxVolume;
//make sure volume is positive or zero
if (newVol > 0.0f) soundSource.audio.volume = newVol;
else newVol = 0.0f;
return newVol;
}
public static float adjustVolumeToDistance(GameObject soundSource)
{
return adjustVolumeToDistance(soundSource, 1000.0f);
}
// Sets layer for a given transform and for all its children recursively
public static void setLayer(Transform t, int layer)
{
t.gameObject.layer = layer;
for (int i = 0; i < t.GetChildCount(); i++)
setLayer(t.GetChild(i), layer);
}
}