using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
//------------------------------------------------------------------------
//Perlin Noise Agents v1.0 - Controller Class
//--Controller Class is the main controller and organizer of the data, most other classes will be accessed by the controller and vice versa
//Mode Lab - Written by Luis Quinones
//------------------------------------------------------------------------
public class Controller : MonoBehaviour {
//Variables Assignment
public GameObject mapGeo,spawnGeo,reboot,agentSet;
public Vector3 spawnValues;
public int AgentCount = 1000;
public float lifetime = 5.0f;
public float sWidth = 1.0f;
public float eWidth = 0.1f;
public float mP = 1.0f;
public float dimensionBarValue,physicsBarValue,agentDisplay,agentDynamicSpawnState;
public int sceneAgentCount,runTimesCheck;
private float RSliderValue, GSliderValue, BSliderValue, spawnBarValue;
//-----------------------------------------------------
public Slider strengthSlider,scaleSlider,speedSlider,agentCountSlider,trailTimeSlider,trailStartWSlider,trailEndWSlider,multiplierSlider;
//-----------------------------------------------------
public Slider RSlider,GSlider,BSlider;
//-----------------------------------------------------
public Button resetButton, runImageButton, colorEnableButton, colorDisableButton, runSpawnImageButton;
//-----------------------------------------------------
public Canvas mainCanvas, visualCanvas, optCanvas;
//-----------------------------------------------------
public Scrollbar spawnScrollBar,dimensionScrollBar,physicsScrollBar,agentHeadBar,dynamicAgentSpawnScrollBar, gradientTextureScrollBar;
//-----------------------------------------------------
public Toggle strengthToggle, scaleToggle, speedToggle, trailSWToggle, trailEWToggle;
//-----------------------------------------------------
public Camera flatCamera,dimensionCamera;
//-----------------------------------------------------
public GameObject cube;
//-----------------------------------------------------
public Gradient newGradient;
//-----------------------------------------------------
private bool hideCanvas,showCanvas,hideVisualCanvas,showVisualCanvas,isOutside, runButtonOn, showOptCanvas, runSpawnButton, pause, pauseHold, reload;
private bool testThis;
public bool sTenaled { get; set; }
public bool scTenaled { get; set; }
public bool speedTenaled { get; set; }
public bool trailSW { get; set; }
public bool trailEW { get; set; }
public bool colorEnable { get; set; }
public bool colorDisable { get; set; }
//-----------------------------------------------------
void Start()
{
flatCamera.enabled = true; //2d Camera
dimensionCamera.enabled = false; //3d Camera
cube.GetComponent<MeshRenderer>().enabled = false; //Physics Cube Renderer Disabled
//-----------------------------------------------------
//This is where we check for the Spawn Map Enable Button
//if its pressed we kill the existing agents and call the SpawnMapAgents Funct.
//-----------------------------------------------------
runSpawnButton = false;
runSpawnImageButton.onClick.AddListener(delegate{
runSpawnButton = true;
if (!runSpawnButton) {
SpawnAgents ();
} else if (runSpawnButton) {
GameObject[] Instances = GameObject.FindGameObjectsWithTag("AGENTDUDE");
foreach(GameObject t in Instances){
Destroy(t);
}
SpawnMapAgents();
}
});
//-----------------------------------------------------
if (!runSpawnButton) {
SpawnAgents(); //if our SpawnButton Isnt enabled just run the regular spawn protocol
}
//-----------------------------------------------------
mainCanvas.enabled = true;
visualCanvas.enabled = true;
isOutside = false;
runButtonOn = false;
optCanvas.enabled = false;
//-----------------------------------------------------
agentCountSlider.onValueChanged.AddListener (delegate {
AgentCount = Mathf.RoundToInt(agentCountSlider.value);
if(Mathf.RoundToInt(agentDynamicSpawnState) == 1){
if(sceneAgentCount < 1500){
SpawnAgents ();
}else{
Debug.Log ("REACHED MAX AGENT COUNT, RESET SIM"); //Set Max Approx Agent Count
}
}
});
dynamicAgentSpawnScrollBar.onValueChanged.AddListener (delegate {
agentDynamicSpawnState = dynamicAgentSpawnScrollBar.value; //Update the dAS Scrollbar value when its changed
});
trailTimeSlider.onValueChanged.AddListener (delegate {
lifetime = trailTimeSlider.value; //Update the trail time scrollbar value when its changed
});
trailStartWSlider.onValueChanged.AddListener (delegate {
sWidth = trailStartWSlider.value; //Update the trail start width value when its changed
});
trailEndWSlider.onValueChanged.AddListener (delegate {
eWidth = trailEndWSlider.value; //Update the trail end width value when its changed
});
multiplierSlider.onValueChanged.AddListener (delegate {
mP = multiplierSlider.value; //Update the mutiplier slider value when its changed
});
spawnScrollBar.onValueChanged.AddListener (delegate {
spawnBarValue = spawnScrollBar.value; //Update the spawn value scrollbar when its changed
});
dimensionScrollBar.onValueChanged.AddListener (delegate {
dimensionBarValue = dimensionScrollBar.value; //Update the 2d/3d scrollbar value when its changed
});
physicsScrollBar.onValueChanged.AddListener (delegate {
physicsBarValue = physicsScrollBar.value; //Update the physics scrollbar value when its changed
});
agentHeadBar.onValueChanged.AddListener (delegate {
agentDisplay = agentHeadBar.value; //Update the display agent head value when its changed
});
//-----------------------------------------------------
RSlider.onValueChanged.AddListener (delegate {
RSliderValue = RSlider.value; //Update the R color Slider value when its changed
});
GSlider.onValueChanged.AddListener (delegate {
GSliderValue = GSlider.value; //Update the G color slider value when its changed
});
BSlider.onValueChanged.AddListener (delegate {
BSliderValue = BSlider.value; //Update the B color slider value when its changed
});
//-----------------------------------------------------
runImageButton.onClick.AddListener(delegate{
runButtonOn = true; //Ensures the Behavior Map is activated when the Enable button is pressed
optCanvas.enabled = true; //Turns on the components canvas for behavioral map
});
}
void SpawnAgents()
{
for (int i = 0; i < AgentCount; i++)
{
Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, 161), 0, Random.Range(-spawnValues.z, spawnValues.z)); //Set random pos to spawn
Quaternion spawnRotation = Quaternion.identity;
Instantiate(agentSet, spawnPosition, spawnRotation); //create instance of the agent
}
}
void SpawnMapAgents(){
//Function to Spawn Agents when using the spawnMap
for (int i = 0; i < AgentCount; i++)
{
Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, 161), 0, Random.Range(-spawnValues.z, spawnValues.z));
Quaternion spawnRotation = Quaternion.identity;
float lumCast = spawnCastHit(spawnPosition); //Call the castHit Function to retreive the pixel color value from the spawned pos
if(lumCast < 0.5){
i -=1 ;
}else{
Instantiate(agentSet, spawnPosition, spawnRotation); //Create instance only if the grayscale value is > than specified value above
}
}
}
public float behaviorCastHit(Vector3 pos){
Color c;
Vector3 currentpos = pos; //current passed position
RaycastHit hit;
var hitPoint = currentpos;
Physics.Raycast (hitPoint,Vector3.down, out hit,Mathf.Infinity);
Renderer rend = hit.transform.GetComponent<Renderer>(); //Retreive the rendered component from the hit object
Texture2D test = mapGeo.GetComponent<MapBehavior> ().texture; //if we are using the behavior map retrieve the code component from the inherited geo then retreive texture
c = test.GetPixelBilinear(hit.textureCoord2.x,hit.textureCoord2.y); //Get the color info at the hit coordinates
float gScale = c.grayscale; //set grayscale
return gScale;
}
public float spawnCastHit(Vector3 pos){
Color c;
Vector3 currentpos = pos; //current passed position
RaycastHit hit;
var hitPoint = currentpos;
Physics.Raycast (hitPoint,Vector3.down, out hit,Mathf.Infinity);
Renderer rend = hit.transform.GetComponent<Renderer>(); //Retreive the rendered component from the hit object
Texture2D test = spawnGeo.GetComponent<SpawnBehavior>().text; //if we are using the behavior map retrieve the code component from the inherited geo then retreive texture
c = test.GetPixelBilinear(hit.textureCoord2.x,hit.textureCoord2.y); //Get the color info at the hit coordinates
float gScale = c.grayscale; //set grayscale
return gScale;
}
void OnGUI(){
//Behavior Canvas
if (!hideCanvas) {
mainCanvas.enabled = true;
} else {
mainCanvas.enabled = false;
}
//VisualCanvas Canvas
if (!hideVisualCanvas) {
visualCanvas.enabled = true;
} else {
visualCanvas.enabled = false;
}
}
void Update(){
//----------------------------------
//Pause the Simulation using the P Key
if(Input.GetKeyDown("p")){
pause = !pause;
if (pause){
pauseHold = true;
}else if(!pause){
pauseHold = false;
}
}
//R key will reload the application with the default values
if (Input.GetKey ("r")) {
reload = true;
}
if (reload) {
reload = false;
Application.LoadLevel (Application.loadedLevel);
}
//----------------------------------
//Toggles the Component Canvas by pressing space bar
if(Input.GetKeyDown("space")){
showOptCanvas = !showOptCanvas;
if (showOptCanvas)
optCanvas.enabled = true;
else if(!showOptCanvas)
optCanvas.enabled = false;
}
//----------------------------------
//Behavior Canvas
if(Input.GetKeyDown("c")){
hideCanvas = !hideCanvas;
if (hideCanvas)
showCanvas = true;
else if(!hideCanvas)
showCanvas = false;
}
if (Input.GetKeyDown ("w")) {
mainCanvas.enabled = false;
visualCanvas.enabled = false;
optCanvas.enabled = false;
}
//----------------------------------
//Visual Canvas
if(Input.GetKeyDown("v")){
hideVisualCanvas = !hideVisualCanvas;
if (hideVisualCanvas)
hideVisualCanvas = true;
else if(!hideVisualCanvas)
hideVisualCanvas = false;
}
//----------------------------------
//Checks if we are resetting if not then proceed normally.
if (reboot.GetComponent<DataPreserve>().fireUp == true ) { //Checks referenced class and components for trigger to reset
Start ();
reboot.GetComponent<DataPreserve>().restart = false; //restores that classes values for next run
reboot.GetComponent<DataPreserve>().fireUp = false;
}else {
GameObject[] test = GameObject.FindGameObjectsWithTag ("AGENTDUDE"); //Get All objects with same tag
sceneAgentCount = test.Length;
foreach (GameObject t in test) { //Go Through each instance
if (t == null) {
Debug.Log ("Cant Find Instance");
} else {
if (Mathf.RoundToInt(agentDisplay) == 1) {
t.GetComponentInChildren<MeshRenderer>().enabled = false; //turns on or off agent head inherits value from scrollbar listener
} else if (Mathf.RoundToInt(agentDisplay) == 0) {
t.GetComponentInChildren<MeshRenderer>().enabled = true;
}
//----------------------------------
//Only if physics is enabled in the scrollbar
if(t.GetComponent<Rigidbody>()){
if(Mathf.RoundToInt(physicsBarValue) == 0){
t.GetComponent<Rigidbody>().mass = 0.01f;
t.GetComponent<BoxCollider>().enabled = false;
}else if(Mathf.RoundToInt(physicsBarValue) == 1){
cube.GetComponent<MeshRenderer>().enabled = true;
t.GetComponent<Rigidbody>().mass = 1f;
t.GetComponent<BoxCollider>().enabled = true;
}
}
if(Mathf.RoundToInt(dimensionBarValue) == 0){ //IF we set scrollbar to 3d we swap cameras and pass flag to the PerlinNoise Class
flatCamera.enabled = true;
dimensionCamera.enabled = false;
t.GetComponent<PerlinNoiseMovement>().dimension = true;
}else if(Mathf.RoundToInt(dimensionBarValue) == 1){
flatCamera.enabled = false;
dimensionCamera.enabled = true;
t.GetComponent<PerlinNoiseMovement>().dimension = false;
}
if (pauseHold) {
t.GetComponent<PerlinNoiseMovement>().proceed = false; //if key is pressed pass flag to perlin noise class to freeze agents.
}else if(!pauseHold){
t.GetComponent<PerlinNoiseMovement>().proceed = true; //if key is pressed pass flag to perlin noise class to freeze agents.
}
if(runButtonOn){ //if the Behavior Map Enable button is on
float lumValue = behaviorCastHit(t.transform.position); //call cast ray function to get color pixel value
if(sTenaled){ //if Strength Checkbox is enabled for map then use the grayscale value as multiplier to current settings for strength
t.GetComponent<PerlinNoiseMovement> ().noiseStrength = strengthSlider.value * mP * lumValue ;
}else{
t.GetComponent<PerlinNoiseMovement> ().noiseStrength = strengthSlider.value * mP;
}
//---------------------------------------------------------------------------------------------
if(scTenaled){//if scale Checkbox is enabled for map then use the grayscale value as multiplier to current settings for scale
float lumAdjusted;
if(lumValue == 0.0f){
lumAdjusted = 0.1f;
}else{
lumAdjusted = lumValue;
}
t.GetComponent<PerlinNoiseMovement> ().noiseScale = scaleSlider.value * mP * lumAdjusted ;
}else{
t.GetComponent<PerlinNoiseMovement> ().noiseScale = scaleSlider.value * mP ;
}
//---------------------------------------------------------------------------------------------
if(speedTenaled){ //if speed Checkbox is enabled for map then use the grayscale value as multiplier to current settings for speed
t.GetComponent<PerlinNoiseMovement> ().minSpeed = speedSlider.value * lumValue;
}else{
t.GetComponent<PerlinNoiseMovement> ().minSpeed = speedSlider.value;
}
//---------------------------------------------------------------------------------------------
if(trailSW){ //if trail Start Width Checkbox is enabled for map then use the grayscale value as multiplier to current settings
t.GetComponent<TrailRenderer>().startWidth = sWidth * lumValue;
}else{
t.GetComponent<TrailRenderer>().startWidth = sWidth ;
}
//---------------------------------------------------------------------------------------------
if(trailEW){ //if trail End Width Checkbox is enabled for map then use the grayscale value as multiplier to current settings
t.GetComponent<TrailRenderer>().endWidth = eWidth * lumValue;
}else{
t.GetComponent<TrailRenderer>().endWidth = eWidth;
}
t.GetComponent<TrailRenderer>().time = lifetime; //for each instance grab the trail component and set the trail time to the current slider value
if(colorEnable && !colorDisable){ //If color enable button is pressed then adjust the tint of the trail
Color nColor = new Color(RSliderValue,GSliderValue,BSliderValue);
Material trail = t.GetComponent<TrailRenderer>().material;
trail.SetColor("_TintColor",nColor);
}
}else if(!runButtonOn){ //If we are not using an image to drive values then run below
t.GetComponent<PerlinNoiseMovement> ().noiseStrength = strengthSlider.value * mP;//For each instance we go into the Perlin Noise Class and set its variables to our slider values
t.GetComponent<PerlinNoiseMovement> ().noiseScale = scaleSlider.value * mP;//For each instance we go into the Perlin Noise Class and set its variables to our slider values
t.GetComponent<PerlinNoiseMovement> ().minSpeed = speedSlider.value;//For each instance we go into the Perlin Noise Class and set its variables to our slider values
t.GetComponent<TrailRenderer>().startWidth = sWidth;//For each instance we go into the Perlin Noise Class and set its variables to our slider values
t.GetComponent<TrailRenderer>().endWidth = eWidth;//For each instance we go into the Perlin Noise Class and set its variables to our slider values
t.GetComponent<TrailRenderer>().time = lifetime;//For each instance we go into the Perlin Noise Class and set its variables to our slider values
if(colorEnable && !colorDisable){ //If color enable button is pressed then adjust the tint of the trail
Color nColor = new Color(RSliderValue,GSliderValue,BSliderValue);
Material trail = t.GetComponent<TrailRenderer>().material;
trail.SetColor("_TintColor",nColor);
}
}
if(t.transform.position.x < -spawnValues.x || t.transform.position.x > 161 || t.transform.position.y < -spawnValues.y || t.transform.position.y > spawnValues.y || t.transform.position.z < -spawnValues.z || t.transform.position.z > spawnValues.z){
isOutside = true; //if agent position is outside the bounds we set the flag to pass along
}else{
isOutside = false;
}
if(isOutside){ //if its outside the bounds kill it and respawn a new one randomly inside the bounds
if(Mathf.RoundToInt(spawnBarValue) == 0){ //Value for constant spawn, here they will keep spawning as they go off frame
Destroy(t);
Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, 161), 0, Random.Range(-spawnValues.z, spawnValues.z));
Quaternion spawnRotation = Quaternion.identity;
Instantiate(agentSet, spawnPosition, spawnRotation);
}else if(Mathf.RoundToInt(spawnBarValue) == 1){ //value for die off, here they will stop moving once they are outside the bounds and will die once their trail time expires
t.GetComponent<PerlinNoiseMovement>().proceed = false;
Destroy(t,lifetime);
}
}
}
}
}
}
}