- Home /
OP posted same thing twice; closing
OnTriggerEnter is called too late (after Start)
I am creating a simple room-based level generator. On adding a room to the level, I check if the new room is touching any colliders (new room has trigger collider and kinematic-rigidbody, old rooms just have normal colliders).
The problem is that immediately after adding a room, when I check whether the room is overlapping another room, the new room's OnTriggerEnter has not yet been called so it always returns as not triggered. How do I set up my code so that OnTriggerEnter has a chance to test the new room before I check whether OnTriggerEnter has been called?
Trigger code (on the new Room)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Room : MonoBehaviour {
[HideInInspector] public bool isColliding = false;
private void OnCollisionEnter(Collision collision) {
//Debug.Log("Colliding");
isColliding = true;
}
private void OnCollisionExit(Collision collision) {
//Debug.Log("Not Colliding");
isColliding = false;
}
private void OnTriggerEnter(Collider collision) {
Debug.Log("Triggered");
isColliding = true;
}
private void OnTriggerExit(Collider collision) {
Debug.Log("Not triggered");
isColliding = false;
}
// Use this for initialization
void Start () {
Debug.Log("ontrigger is: " + isColliding);
}
// Update is called once per frame
void Update () {
}
}
Check code (see line 39, it always logs "False", even when it should be true. After it logs false, OnTriggerEnter is called and logs "Triggered") using System.Collections; using System.Collections.Generic; using UnityEngine;
public class levelGen : MonoBehaviour {
public Room[] rooms;
public int roomCount = 10;
int currentRoomCount = 0;
// Add a Room
void AddRoom() {
bool success = false;
Room newRoom;
GameObject newRoomObject;
Door[] endDoors;
Door endDoor;
Door[] newDoors;
Door newDoor;
endDoors = ShuffleDoors(GetComponentsInChildren<Door>());
while (!success) {
newRoomObject = Instantiate(rooms[Random.Range(0, rooms.Length)].gameObject,new Vector3(100,100,100),transform.rotation) as GameObject;
newRoom = newRoomObject.GetComponent<Room>();
newDoors = ShuffleDoors(newRoom.GetComponentsInChildren<Door>());
for (int i = 0; i < endDoors.Length && !success; i++) {
endDoor = endDoors[i];
if (!endDoor.isConnected) {
for (int ii = 0; ii < newDoors.Length && !success; ii++) {
newDoor = newDoors[ii];
// place room at endDoor
newRoom.transform.SetPositionAndRotation(endDoor.transform.position - newDoor.transform.localPosition, endDoor.transform.rotation);
// rotate room to fit on endDoor
newRoom.transform.RotateAround(endDoor.transform.position, Vector3.up, 180 -Quaternion.Angle(Quaternion.Euler(Vector3.zero), newDoor.transform.localRotation));
// try to rotate in case the door is backkwards
Debug.Log(newRoom.isColliding);
if (newRoom.isColliding) {
Debug.Log("Tried it the other way around (rotate 180d)");
newRoom.transform.RotateAround(endDoor.transform.position, Vector3.up, 180);
}
if (!newRoom.isColliding) {
success = true;
currentRoomCount += 1;
//newRoomObject.transform.parent = gameObject.transform;
//newRoomObject.GetComponent<Collider>().isTrigger = false;
//Destroy(newRoom.gameObject.GetComponent<Rigidbody>());
// ?
//endDoor.deadEnd = false;
//endDoor.isConnected = true;
//newDoor.deadEnd = false;
}
}
}
}
}
}
// Use this for initialization
void Start () {
for (int i = 0; i < roomCount; i++) {
AddRoom();
}
}
// Update is called once per frame
void Update () {
}
//stuff
Door[] ShuffleDoors(Door[] arr) {
for (int i = 0; i < arr.Length; i++) {
int rnd = Random.Range(0, arr.Length);
Door tempGO = arr[rnd];
arr[rnd] = arr[i];
arr[i] = tempGO;
}
return arr;
}
Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 angles) {
return Quaternion.Euler(angles) * (point - pivot) + pivot;
}
}
Follow this Question
Related Questions
Initialising List array for use in a custom Editor 1 Answer
Multiple Cars not working 1 Answer
OnTriggerEnter is called too late (after Start) 2 Answers
Distribute terrain in zones 3 Answers