I have a room where I am trying to randomly instantiate portals on the walls of the room at specific points.
So far, I have been able to destroy and randomly instantiate portal prefabs but it only works once when I first run the application. I have two scripts in which ABChecker is used to detect two collisions against a cube and then it calls the Reset() sub-routine in the other script. And then shrinkRoom is used to destroy the current portal prefab and instantiate another portal randomly onto a specific point.
One thing to note is that there are two portals in the room, directly opposite to each other. Currently the main problem that I am facing is that SelectPortals() in shrinkRoom only randomizes the location of instantiation once.
Thanks in advance.
The scripts are as follows:
shrinkRoom
public class shrinkRoom : MonoBehaviour {
public float countDown;// this is a timer for each room
public static int PortalNum;
public GameObject player;
//the booleans are to check which walls need to be shrinked
public bool ABshrink;
//these are other scripts that get activated when the booleans are pressed
public ABChecker ABChecker_portalA;
public ABChecker ABChecker_portalB;
public GameObject Portal; // portal gameobject that gets spawned
public GameObject[] SpawnedPortal; // contains all portals
public GameObject[] A_portalPos; // array containing six possible portal positions for wall A
public GameObject[] B_portalPos; // array containing six possible portal positions for wall B
int size;
float roomX;
float roomY;
float shrinkSpeed;
float playerSize;
//this float is just the rate of the room getting shrinked
void Awake() {
roomX = transform.localScale.x;
roomY = transform.localScale.y;
//picked X scale because its the same and Y could also be used with same effect (room is a cube)
shrinkSpeed = (roomX - 1 / countDown) * Time.deltaTime;
size = A_portalPos.Length;
SpawnedPortal = new GameObject;
PortalNum = Random.Range (0, size);
SelectPortals();
}
void Update() {
if (countDown > 0) {
//as long as the timer is not
//time.detaTime records the time taken for one frame.complete...
countDown -= Time.deltaTime; //it needs to deduct one second from the timer
//clamps the variable so that negative scaling (which would result in room increasing in size) is not possible
// 1 is the minimum possible value and the one that we need NOTE: Must be changed to player width using bounds of camera box collider
//8 is the maximum possible value that is not needed so 8 is just a random number to suit the parameters
if (ABshrink == true) {
ABChecker_portalA.enabled = true;
ABChecker_portalB.enabled = true;
}
//this makes it scale down as long as the current scale co ordinates are still in the range of the clamp values
float scaleX; //stored the scale of the gameObject's x co-ordinate in a variable
float scaleY; //stored the scale of the gameObject's y co-ordinate in a variable
scaleX = Mathf.Clamp(transform.localScale.x, 1, 8);
scaleY = Mathf.Clamp(transform.localScale.y, 1, 8);
if (transform.localScale.x == scaleX && ABshrink == true) {
transform.localScale -= new Vector3(shrinkSpeed, 0, 0);
}
}
}
public void Reset() {
Debug.Log("Reset");
player = GameObject.Find("Cube");
transform.position = player.transform.position;
transform.localScale = new Vector3(roomX, roomY, transform.localScale.z);
Destroy(SpawnedPortal[0]);
Destroy(SpawnedPortal[1]);
SelectPortals();
}
public void SelectPortals() {
Debug.Log("Select Portals");
//PortalNum = Random.Range(0, size );
Debug.Log ("Random no. is " + PortalNum);
GameObject[] PortalChoosenAB; // these contain the correct portals
GameObject wallA;
GameObject wallB;
wallA = GameObject.FindGameObjectWithTag("WallA");
wallB = GameObject.FindGameObjectWithTag("WallB");
if (ABshrink == true) {
Debug.Log("PORTAL NUM" + PortalNum);
PortalChoosenAB = new GameObject[2];
PortalChoosenAB[0] = A_portalPos[PortalNum];
PortalChoosenAB[1] = B_portalPos[PortalNum];
SpawnedPortal[0] = Instantiate(Portal, PortalChoosenAB[0].transform.position, Quaternion.identity);
SpawnedPortal[0].transform.parent = wallA.transform;
SpawnedPortal[1] = Instantiate(Portal, PortalChoosenAB[1].transform.position, Quaternion.identity);
SpawnedPortal[1].transform.parent = wallB.transform;
ABChecker_portalA = SpawnedPortal[0].AddComponent<ABChecker>() as ABChecker;
ABChecker_portalB = SpawnedPortal[1].AddComponent<ABChecker>() as ABChecker;
PortalNum = Random.Range (0, size);
}
}
}
And ABChecker :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// summary of script: to make sure both shrinking walls are colliding and only then remove the room
public class ABChecker : MonoBehaviour {
public static int hits;//this counts the hits it makes with the walls
public GameObject newRoom;
public shrinkRoom scriptShrinkRoom;
void Awake() {
newRoom = GameObject.Find("newRoom");
scriptShrinkRoom = newRoom.AddComponent < shrinkRoom >() as shrinkRoom;
}
void OnCollisionEnter(Collision col) { //this function is called the first frame a collision is detected
if (col.gameObject.name == "Cube"){//if the gameobject that is being collided with has the name "Cube"
hits++; // add one to hits
Debug.Log(hits); //testing
Debug.Log(col.gameObject.name);
}
}
void OnCollisionExit(Collision col) {// this is called the frame when it no longer collides with a game object
hits--; // it deducts from the number of DIFFERENT collisions with walls as it no is not colliding with a wall
}
void Update() {
if (hits == 2) { //so only when BOTH walls A and B are colliding with the gameobject it will create a new room
scriptShrinkRoom.Reset();
}
}
}