Random Note Generation

Hello! I would like to know a simple way to generate a specific amount of notes like in the game Slender. I have no idea how I can code this and I can’t find any tutorials. I would like it to be like like you can place out duplicates of a note all around the map and you can like place 20 notes but when you set the amount of notes you want to be placed into the map, you only get that amount. So I can place 20 notes and set the amount to 2. Then only two of the 20 notes will be active and all other notes will be disabled.

So if anyone would know how to do this, please tell me. :slight_smile:

It doesn’t make sense to place them at random locations, instead you place them at pre-set locations and then choose between them in random if you want.

1- Place the notes in your scene, wherever you want.

2- Make a NoteManager or something… just to manage (de)activating the notes.

3- To set this up right, create an empty gameObject call it NoteManager, attach the NoteManager script to it, and then have all your notes be children to it, like so:

[16203-notemanager.png*_|16203]

NoteManager.cs

using System.Collections.Generic;
using UnityEngine;

public class NoteManager : MonoBehaviour
{
	// this will maintain references to your notes after you set their locations in your scene.
	public Transform[] notes { private set; get; }

	// how many notes you wanna be activated at first
	public int nNotesToActivate;

	// whether you wanna activate your notes randomly, or from the start of the notes array
	public bool random;

	void Start()
	{
		InitNotes();
		ActivateRequiredNotes();
	}

	void InitNotes()
	{
		int nNotes = transform.childCount;
		notes = new Transform[nNotes];
		for (int i = 0; i < nNotes; i++) {
			notes *= transform.GetChild(i);*
  •  }*
    
  • }*

  • void ActivateRequiredNotes()*

  • {*

  •  // make sure we stay within the bounds of the array*
    
  •  nNotesToActivate = Mathf.Clamp(nNotesToActivate, 0, notes.Length);*
    
  •  // We'll activate 'nNotesToActivate' notes, and disable the rest*
    
  •  if (random) {*
    
  •  	// choose random locations for our notes (from our preset locations)*
    
  •  	List <int> randLocations = new List<int>();*
    
  •  	for (int i = 0; i < nNotesToActivate; i++)*
    
  •  	{*
    
  •  		   int rand = Random.Range(0, notes.Length);*
    
  •  		   // Make sure we don't get the same rand (Thanks to @tanoshimi for reminding me about it)*
    
  •  		   while (randLocations.Contains(rand))*
    
  •  			  rand = Random.Range(0, notes.Length);*
    
  •  		   randLocations.Add(rand);*
    
  •  	}*
    
  •  	// activate the notes at those random locations and disable the rest*
    
  •  	for (int i = 0, len = notes.Length; i < len; i++)* 
    
  •  	{*
    
  •  		   if (randLocations.Contains(i)) {*
    

_ if (!notes*.gameObject.activeSelf)_
_ notes.gameObject.SetActive(true);
randLocations.Remove(i);
}
else notes.gameObject.SetActive(false);
}
}
else {
// if you chose to activate only 2 notes, then only the first and second note will be active, the rest gets disabled*

* for (int i = 0, len = notes.Length; i < len; i++)
notes.gameObject.SetActive(i < nNotesToActivate);
}
}
}
Thanks to the InitNotes method, now you don’t have to bother yourself and assign the notes to the notes array, it happens automatically for you.
If you want to manually assign the notes (not sure why would you wanna do that), remove the call InitNotes and make your notes a normal public variable, instead of a property to make it visible in the inspector.
Here’s something extra: If you wanted to change the number of notes at runtime and update them, add:
public bool updateNotes = false;
void Update()
{
if (updateNotes)
{
updateNotes = false;
ActivateRequiredNotes();
}
}
Now you can change the number of nNotesToActivate from your inspector, once you’re satisfied just tick updateNotes and it will update it for you :slight_smile:

It really depends do you want the note locations to be random? Or do you want to have 20 preset locations and then assign 2 of them for the note randomly?

It’s not the prettiest solution but would work.

If you want preset locations you could do something like:

//RandomNoteScript

//set the prefab
public GameObject noteObject;

//set all your note positions
//easy way to do this is just to create a bunch of empty game objects in the scene where you want the notes to be able to spawn.

//transform positions of notes (set from the scene to these variables)
public Transform noteSpawnPosition1;
public Transform noteSpawnPosition2;


//do this for all 20 and set them from the scene to the script in inspector

//float for how many notes to be spawned.
float totalNotesSpawned;

//float for how many spawn points in scene
float totalSpawnPositions;

//note counter;
int noteCounter;

//random number float
float randomNumber;


//do one of these for each possible spawned note
//this example needs 2
float firstNoteLocation;
float secondNoteLocation;

void Start()
{
//example of setting the note count for specific levels

if (currentLevel == 1)
{
totalNotesSpawned = 2;
totalSpawnPositions = 20;
}

noteCounter = 0;


noteSpawnFunction();

}

void noteSpawnFunction()
{


if (noteCounter < totalNotesSpawned)
{


//generate random number 1-20
randomNumber = Random.Range(1, totalSpawnPositions + 1);

//detect if you need to roll number again since you already spawned one at that random spawn point
if ((randomNumber == firstNoteLocation) || (randomNumber == secondNoteLocation))
{
//call function again
noteSpawnFunction();
return;
}

if (randomNumber == 1)
{
Instantiate(noteObject, noteSpawnPosition1.position, Quaternion.identity);	
} 

else if (randomNumber == 2)
{
Instantiate(noteObject, noteSpawnPosition2.position, Quaternion.identity);	
} 

//remainder of possible rolls...

if (noteCounter == 0)
{
firstNoteLocation = randomRoll;
}

else if (noteCounter == 1)
{
secondNoteLocation = randomRoll;
}

//add to counter after succesfully spawning Note
++noteCounter;
}



//if you need to spawn another note... calls the function again
if (noteCounter < totalNotesSpawned)
{
noteSpawnFunction();
}

}

[MOD] Work on your formatting skills [/MOD]