Rave Cage Carnage.

Rave Cage Carnage (RCC) is a Rhythm-based action slasher with roguelike progression and dynamic intensity. For this game I developed a beat detection script which should allow us to Player inputs and objects to respond to the music.




My tasks:

-Gameplay Programmierer: Enemy K.I., Skillsets implemented, Items implemented.

-System Programmer: Beat detection script created. A script that allows us different objects respond to the beat of the music and match player input to the beat.

Trailer: Rave Cage Carnage Trailer






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

public class BeatAnalyse : Singleton(BeatAnalyse)
{
	float[] spectrum;
	public static List beatStarts = new List();


	[SerializeField] float drawWidth;
	[SerializeField] float limit, waitSamples;
	[SerializeField] AudioClip wave;
	

	void Start()
	{
		int amount = wave.samples;
		spectrum = new float[amount];
		wave.GetData(spectrum, 0);

		for (int i = 0; i < spectrum.Length; i++)
		{
			spectrum[i] = Mathf.Abs(spectrum[i]);
		}

		for (int i = 1; i < spectrum.Length -1; i++)
		{
			if (spectrum[i] > limit)
			{
				if(spectrum[i] <= spectrum[i-1] && spectrum[i] >= spectrum[i+1])
				{                    
					beatStarts.Add(i);
					i += (int)waitSamples;
				}
			}
		}
	}

	private void OnDrawGizmos()
	{
		if(spectrum == null)
		{
			return;
		}
		if (PlayerController.show)
		{
			Vector3 displacement = Camera.main.ScreenToWorldPoint(new Vector3(100, 100, 5));
			float heightMulti = 1;
			float widthMulti = 0.000005f;
			Gizmos.color = new Color(0.5f, 0, 0.5f, 1);

			for (int i = 0; i < spectrum.Length; i += 100)
			{
				Gizmos.DrawLine(displacement + new Vector3(i * widthMulti, 0, 0),
								displacement + new Vector3(i * widthMulti, heightMulti * spectrum[i], 0));
			}
		}
	}

}

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


public class BeatStrike : MonoBehaviour
{
    private Slider juiceMeter;

    private AudioSource wave;

    [SerializeField] VisualEffect particleLeft;
    [SerializeField] VisualEffect particleRight;

    [SerializeField] int reactionTime;
    [Header("Time in Samples (10.000 = 0,25sec)")]
    [SerializeField] int windowTrigger;
    float timeSample;

    bool action = false;
    bool punish = false;
    public static bool beatAttack = false;

    [Header("Juice Reward in int")]
    [SerializeField] int dashReward;
    [SerializeField] int attackReward;
    [SerializeField] int danceReward;

    [Header("Juice Punish in int")]
    [SerializeField] int dashPunish;
    [SerializeField] int attackPunish;
    [SerializeField] int dancePunish;
    [SerializeField] int idlePunish;

    void Start()
    {

        wave = GameObject.FindWithTag("Beat").GetComponent();
        juiceMeter = GameObject.FindWithTag("JuiceMeter").GetComponent();
        particleLeft.Stop();
        particleRight.Stop();
    }

    void Update()
    {

        if (Input.GetButtonDown("Dash"))
        {
            if(IsOnBeat())
            {
                juiceMeter.value += dashReward;
                particleLeft.Play();
                particleRight.Play();
                action = true;
            }else
            {
                juiceMeter.value -= dashPunish;
            }
        }
        else if (Input.GetButtonDown("Attack"))
        {
            if(IsOnBeat())
            {
                juiceMeter.value += attackReward;
                beatAttack = true;
                action = true;
            }
            else
            {
                juiceMeter.value -= attackPunish;
            }
        }
        else if(Input.GetButtonDown("Dance"))
        {
            if(IsOnBeat())
            {
                juiceMeter.value += danceReward;
                action = true;
            }
            else
            {
                juiceMeter.value -= dancePunish;
            }
        }
        Punishing();
    }

    private void Punishing()
    {
        if(!IsOnBeat() && !action && !punish)
        {
            juiceMeter.value -= idlePunish;
            punish = true;
        }else if(!IsOnBeat() && action && !punish)
        {
            punish = true;
            action = false;
        }else if(IsOnBeat())
        {
            punish = false;
        }

        if (PlayerController.dashTime <= 0)
        {
            particleLeft.Stop();
            particleRight.Stop();
        }

    }

    public bool IsOnBeat()
    {
        timeSample = wave.timeSamples - reactionTime;
        for (int i = 0; i < BeatAnalyse.beatStarts.Count; i++)
        {
            if (timeSample >= (BeatAnalyse.beatStarts[i] - windowTrigger) &&
                timeSample <= (BeatAnalyse.beatStarts[i] + windowTrigger))
            {
                return true;
            }
        }
        return false;
    }

    private void OnDrawGizmos()
    {

        if(BeatAnalyse.beatStarts == null)
        {
            return;
        }
        if (PlayerController.show)
        {
            Vector3 displacement = Camera.main.ScreenToWorldPoint(new Vector3(100, 100, 5));
            float heightMulti = 1;
            float widthMulti = 0.000005f;
            Gizmos.color = new Color(0.5f, 0, 0.5f, 1);

            Gizmos.color = Color.green;
            for (int i = 0; i < BeatAnalyse.beatStarts.Count; i++)
            {
                Gizmos.DrawLine(displacement + new Vector3((BeatAnalyse.beatStarts[i] - windowTrigger + reactionTime) * widthMulti, 0, 0),
                                displacement + new Vector3((BeatAnalyse.beatStarts[i] + windowTrigger + reactionTime) * widthMulti, 0, 0));
            }
            Gizmos.color = Color.red;
            Gizmos.DrawLine(displacement + new Vector3(wave.timeSamples * widthMulti, 0, 0), displacement + new Vector3(wave.timeSamples * widthMulti, heightMulti, 0));
        }
    }
    private void OnGUI()
    {
        if (PlayerController.show)
        {
            GUI.color = Color.magenta;
            GUI.Label(new Rect(10, 10, 200, 30), "Beat: " + IsOnBeat());
        }
        if (BeatAnalyse.beatStarts == null)
        {
            return;
        }
        if (PlayerController.show)
        {
            Vector3 displacement = Camera.main.ScreenToWorldPoint(new Vector3(100, 100, 5));
            float heightMulti = 1;
            float widthMulti = 0.000005f;
            Gizmos.color = new Color(0.5f, 0, 0.5f, 1);

            Gizmos.color = Color.green;
            for (int i = 0; i < BeatAnalyse.beatStarts.Count; i++)
            {
                Gizmos.DrawLine(displacement + new Vector3((BeatAnalyse.beatStarts[i] - windowTrigger + reactionTime) * widthMulti, 0, 0),
                                displacement + new Vector3((BeatAnalyse.beatStarts[i] + windowTrigger + reactionTime) * widthMulti, 0, 0));
            }
            Gizmos.color = Color.red;
            Gizmos.DrawLine(displacement + new Vector3(wave.timeSamples * widthMulti, 0, 0), displacement + new Vector3(wave.timeSamples * widthMulti, heightMulti, 0));
        }

    }
}