1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
| using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
public class LaboratoryGenerator : MonoBehaviour
{
PhotonView view;
public bool GenerateOnStart = true;
[Range(3, 100)]
public int RoomCount = 9;
public LayerMask CellLayer;
public GameObject InsteadDoor;
public GameObject[] DoorPrefabs;
public Cell[] CellPrefabs;
private void Start()
{
view = GetComponent<PhotonView>();
if (GenerateOnStart) StartCoroutine(StartGeneration());
}
private void Update()
{
view.RPC("StartGeneration", RpcTarget.All);
}
[PunRPC]
IEnumerator StartGeneration()
{
List<Transform> CreatedExits = new List<Transform>();
Cell StartRoom = Instantiate(CellPrefabs[Random.Range(0, CellPrefabs.Length)], Vector3.zero, Quaternion.identity);
for (int i = 0; i < StartRoom.Exits.Length; i++) CreatedExits.Add(StartRoom.Exits[i].transform);
StartRoom.TriggerBox.enabled = true;
int limit = 1000, roomsLeft = RoomCount - 1;
while (limit > 0 && roomsLeft > 0)
{
limit--;
Cell selectedPrefab = Instantiate(CellPrefabs[Random.Range(0, CellPrefabs.Length)], Vector3.zero, Quaternion.identity);
int lim = 100;
bool collided;
Transform selectedExit;
Transform createdExit; // из списка созданных входов
selectedPrefab.TriggerBox.enabled = false; // чтобы сам себя не проверял на наличие нахлеста ВЫКЛЮЧИЛ
do
{
lim--;
createdExit = CreatedExits[Random.Range(0, CreatedExits.Count)];
selectedExit = selectedPrefab.Exits[Random.Range(0, selectedPrefab.Exits.Length)].transform;
// rotation
float shiftAngle = createdExit.eulerAngles.y + 180 - selectedExit.eulerAngles.y;
selectedPrefab.transform.Rotate(new Vector3(0, shiftAngle, 0)); // выходы повернуты друг напротив друга
// position
Vector3 shiftPosition = createdExit.position - selectedExit.position;
selectedPrefab.transform.position += shiftPosition; // выходы состыковались
// check
Vector3 center = selectedPrefab.transform.position + selectedPrefab.TriggerBox.center.z * selectedPrefab.transform.forward
+ selectedPrefab.TriggerBox.center.y * selectedPrefab.transform.up
+ selectedPrefab.TriggerBox.center.x * selectedPrefab.transform.right; // selectedPrefab.TriggerBox.center
Vector3 size = selectedPrefab.TriggerBox.size / 2f; // half size
Quaternion rot = selectedPrefab.transform.localRotation;
collided = Physics.CheckBox(center, size, rot, CellLayer, QueryTriggerInteraction.Collide);
yield return new WaitForEndOfFrame();
} while (collided && lim > 0);
selectedPrefab.TriggerBox.enabled = true; // ВКЛЮЧИЛ
if (lim > 0)
{
roomsLeft--;
for (int j = 0; j < selectedPrefab.Exits.Length; j++) CreatedExits.Add(selectedPrefab.Exits[j].transform);
CreatedExits.Remove(createdExit);
CreatedExits.Remove(selectedExit);
Instantiate(DoorPrefabs[Random.Range(0, DoorPrefabs.Length)], createdExit.transform.position, createdExit.transform.rotation);
DestroyImmediate(createdExit.gameObject);
DestroyImmediate(selectedExit.gameObject);
}
else DestroyImmediate(selectedPrefab.gameObject);
yield return new WaitForEndOfFrame();
}
// instead doors
for (int i = 0; i < CreatedExits.Count; i++)
{
Instantiate(InsteadDoor, CreatedExits[i].position, CreatedExits[i].rotation);
DestroyImmediate(CreatedExits[i].gameObject);
}
}
} |