1 using UnityEngine;
2 using System.Collections;
3
4 public class LandGenerator : MonoBehaviour {
5
6 public GameObject landTile; // the current tile nearest the player
7 public GameObject newTile; // the tile prefab
8 float tileSize = 20000; // the default size of the prefab tile
9 float tileGenerationThreshold = 2500; // the component distance from center past which a new tile instantiates
10 bool[] tileChecklist; // a checklist to track whether tiles around the landTile have been laid
11
12 enum Axis
13 {
14 x,
15 z,
16 both
17 }
18
19 /// <summary>
20 /// Instantiate the tile checklist.
21 /// </summary>
22 void Start()
23 {
24 tileChecklist = new bool[8];
25 for (int i=0; i<8; i++) {
26 tileChecklist[i] = false;
27 }
28 }
29
30
31
32 /// <summary>
33 /// Every frame, determine whether to lay a new tile based upon the player's position.
34 /// Also, update the landTile object if it is no longer the nearest to the player.
35 /// </summary>
36 void Update () {
37
38 if (!TilesAreFull ()) {
39
40 // If the player is near enough to a corner, draw a corner tile if it hasn't yet been drawn
41 if (PlaneIsFarEnoughAwayFromTileCenter (Axis.x) && PlaneIsFarEnoughAwayFromTileCenter (Axis.z)) {
42 GenerateNewTileIfNecessary (Axis.both);
43 } else {
44
45 // If the player is near an adjacent tile, draw it if it hasn't yet been drawn
46 if (PlaneIsFarEnoughAwayFromTileCenter(Axis.x)) {
47 GenerateNewTileIfNecessary (Axis.x);
48 }
49 if (PlaneIsFarEnoughAwayFromTileCenter(Axis.z)) {
50 GenerateNewTileIfNecessary (Axis.z);
51 }
52 }
53 }
54
55 // Check to see if the current landTile is still the closest one to the player.
56 // If not, find the closest tile and set that as landTile.
57 SwitchCurrentTileIfNecessary ();
58
59 }
60
61 /// <summary>
62 /// Flag a boolean true for each tile around landTile as each is drawn.
63 /// </summary>
64 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
65 void FlagChecklistTile(Axis currentAxis)
66 {
67 switch (currentAxis) {
68 case Axis.x:
69 if (PlaneDirectionFromTileCenter (Axis.x) > 0) {
70 tileChecklist [0] = true;
71 } else {
72 tileChecklist [1] = true;
73 }
74 break;
75 case Axis.z:
76 if (PlaneDirectionFromTileCenter (Axis.z) > 0) {
77 tileChecklist [2] = true;
78 } else {
79 tileChecklist [3] = true;
80 }
81 break;
82 case Axis.both:
83 if (PlaneDirectionFromTileCenter (Axis.x) > 0) {
84 if (PlaneDirectionFromTileCenter (Axis.z) > 0) {
85 tileChecklist [4] = true;
86 } else {
87 tileChecklist [5] = true;
88 }
89
90 } else {
91 if (PlaneDirectionFromTileCenter (Axis.z) > 0) {
92 tileChecklist [6] = true;
93 } else {
94 tileChecklist [7] = true;
95 }
96 }
97 break;
98 }
99
100 }
101
102 /// <summary>
103 /// Check whether all the tiles around the landTile are drawn.
104 /// </summary>
105 /// <returns><c>true</c>, if all tiles in tileChecklist are true, <c>false</c> otherwise.</returns>
106 bool TilesAreFull()
107 {
108 bool retVal = true;
109 foreach (bool item in tileChecklist)
110 if (!item)
111 retVal = false;
112 return retVal;
113 }
114
115 /// <summary>
116 /// Check whether the plane is far enough away from landTile's center. The tileGenerationThreshold defines that amount.
117 /// </summary>
118 /// <returns><c>true</c>, if the plane has crossed beyond the tileGenerationThreshold, <c>false</c> otherwise.</returns>
119 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
120 bool PlaneIsFarEnoughAwayFromTileCenter(Axis currentAxis)
121 {
122 return Mathf.Abs (GetPlaneDistanceFromTileCenter(currentAxis)) > tileGenerationThreshold;
123 }
124
125 /// <summary>
126 /// Check whether the player the has crossed over to a new tile.
127 /// </summary>
128 /// <returns><c>true</c>, if the player is no longer directly above landTile, <c>false</c> otherwise.</returns>
129 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
130 bool PlayerHasCrossedOverToANewTile(Axis currentAxis)
131 {
132 return false;
133 }
134
135 /// <summary>
136 /// Generates the new tile ahead of the player if one doesn't exist in that space yet.
137 /// </summary>
138 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
139 void GenerateNewTileIfNecessary(Axis currentAxis)
140 {
141
142 if (NewTileDoesNotYetExist (currentAxis)) {
143
144 Vector3 newPosition = new Vector3();
145
146 switch (currentAxis) {
147 case Axis.x:
148 newPosition = landTile.transform.position + new Vector3 (tileSize * PlaneDirectionFromTileCenter (Axis.x), 0, 0);
149 break;
150 case Axis.z:
151 newPosition = landTile.transform.position + new Vector3 (0, 0, tileSize * PlaneDirectionFromTileCenter (Axis.x));
152 break;
153 case Axis.both:
154 newPosition = landTile.transform.position +
155 new Vector3 (
156 tileSize * PlaneDirectionFromTileCenter (Axis.x),
157 0,
158 tileSize * PlaneDirectionFromTileCenter (Axis.z)
159 );
160 break;
161 }
162
163 Instantiate(newTile, newPosition, landTile.transform.rotation);
164 FlagChecklistTile (currentAxis);
165 }
166 }
167
168 /// <summary>
169 /// Check whether a tile exists in the spot we want to create one.
170 /// </summary>
171 /// <returns><c>true</c>, if a tile already occupies the space where we want to create one, <c>false</c> otherwise.</returns>
172 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
173 bool NewTileDoesNotYetExist(Axis currentAxis)
174 {
175 bool retVal = true; // return value assumes there is no tile in our way unless proven otherwise
176 GameObject[] tiles = GameObject.FindGameObjectsWithTag("LandTile"); // all tiles currently instantiated in the scene
177 float currentTilePosition = 0, // single-axis landTile position for x or z, double-axis position for x only
178 nextTilePosition = 0, // single-axis tile position for x or z, double-axis position for x only
179 altCurrentPos = 0, // double-axis landTile position for z
180 altNextPos = 0; // double-axis tile position for z
181
182
183 // iterate through all instantiated tiles
184 foreach (GameObject tile in tiles) {
185
186 switch (currentAxis) {
187 case Axis.x:
188 currentTilePosition = landTile.transform.position.x;
189 nextTilePosition = tile.transform.position.x;
190 break;
191 case Axis.z:
192 currentTilePosition = landTile.transform.position.z;
193 nextTilePosition = tile.transform.position.z;
194 break;
195 case Axis.both:
196 currentTilePosition = landTile.transform.position.x;
197 nextTilePosition = tile.transform.position.x;
198 altCurrentPos = landTile.transform.position.z;
199 altNextPos = tile.transform.position.z;
200 break;
201 }
202
203 // if the tile's single-axis position or first double-axis position is
204 // located at the coordinates where we want to create a new tile...
205 if (nextTilePosition == currentTilePosition + tileSize * PlaneDirectionFromTileCenter(Axis.x)) {
206
207 // if we're dealing with a corner piece (i.e. double-axis both x and z)...
208 if (currentAxis == Axis.both) {
209
210 // if tile's second double-axis position is
211 // located at the coordinates where we want to create a new tile...
212 if (altNextPos == altCurrentPos + tileSize * PlaneDirectionFromTileCenter (Axis.z)) {
213
214 // ...then a tile DOES exist where we want to create one, so return false
215 retVal = false;
216 }
217 } else {
218 // we're dealing with an adjacent piece (i.e. single-axis x only or z only)
219 // on the axis in question, a tile DOES exist where we want to create one, so return false
220 retVal = false;
221 }
222
223 }
224 }
225 return retVal;
226 }
227
228
229 /// <summary>
230 /// Gets the plane distance from tile center.
231 /// </summary>
232 /// <returns>The plane distance from tile center.</returns>
233 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
234 float GetPlaneDistanceFromTileCenter(Axis currentAxis)
235 {
236 float planePosition, landTilePosition;
237
238 if (currentAxis == Axis.x) {
239 planePosition = transform.position.x;
240 landTilePosition = landTile.transform.position.x;
241 }
242 else {
243 planePosition = transform.position.z;
244 landTilePosition = landTile.transform.position.z;
245 }
246 Debug.Log ("Distance: " + (planePosition - landTilePosition));
247 return planePosition - landTilePosition;
248 }
249
250 /// <summary>
251 /// Planes the direction from tile center.
252 /// </summary>
253 /// <returns>The direction from tile center.</returns>
254 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
255 float PlaneDirectionFromTileCenter(Axis currentAxis)
256 {
257
258 float distance = GetPlaneDistanceFromTileCenter (currentAxis);
259 float retVal = 0;
260 if (distance > 0)
261 retVal = 1;
262 else
263 retVal = -1;
264 return retVal;
265 }
266
267 /// <summary>
268 /// Switch the current landTile to a new tile if landTile is no longer the closest tile to the player.
269 /// </summary>
270 void SwitchCurrentTileIfNecessary()
271 {
272 if (Mathf.Abs(GetPlaneDistanceFromTileCenter (Axis.x)) > tileSize / 2 // if the player is no longer over landTile on x
273 || Mathf.Abs(GetPlaneDistanceFromTileCenter(Axis.z)) > tileSize / 2) // if the player is no longer over landTile on z
274 {
275 SwitchCurrentTile();
276 }
277
278 }
279
280 /// <summary>
281 /// Reassign landTile to be the closest tile to the player.
282 /// </summary>
283 void SwitchCurrentTile()
284 {
285 // all currently instantiated tiles
286 GameObject[] tiles = GameObject.FindGameObjectsWithTag("LandTile");
287
288 // iterate through all tiles
289 foreach (GameObject tile in tiles) {
290
291 Debug.Log ("Distance between current tile and others: " + (tile.transform.position - landTile.transform.position).magnitude);
292 // if the distance between the player and a given tile is less than that of the player and landTile
293 if (Mathf.Abs((transform.position - tile.transform.position).magnitude) < Mathf.Abs((transform.position - landTile.transform.position).magnitude)) {
294
295 // Reassign landTile to be the tile that is nearer the player.
296 landTile = tile;
297 }
298 }
299 }
300
301 }
2 using System.Collections;
3
4 public class LandGenerator : MonoBehaviour {
5
6 public GameObject landTile; // the current tile nearest the player
7 public GameObject newTile; // the tile prefab
8 float tileSize = 20000; // the default size of the prefab tile
9 float tileGenerationThreshold = 2500; // the component distance from center past which a new tile instantiates
10 bool[] tileChecklist; // a checklist to track whether tiles around the landTile have been laid
11
12 enum Axis
13 {
14 x,
15 z,
16 both
17 }
18
19 /// <summary>
20 /// Instantiate the tile checklist.
21 /// </summary>
22 void Start()
23 {
24 tileChecklist = new bool[8];
25 for (int i=0; i<8; i++) {
26 tileChecklist[i] = false;
27 }
28 }
29
30
31
32 /// <summary>
33 /// Every frame, determine whether to lay a new tile based upon the player's position.
34 /// Also, update the landTile object if it is no longer the nearest to the player.
35 /// </summary>
36 void Update () {
37
38 if (!TilesAreFull ()) {
39
40 // If the player is near enough to a corner, draw a corner tile if it hasn't yet been drawn
41 if (PlaneIsFarEnoughAwayFromTileCenter (Axis.x) && PlaneIsFarEnoughAwayFromTileCenter (Axis.z)) {
42 GenerateNewTileIfNecessary (Axis.both);
43 } else {
44
45 // If the player is near an adjacent tile, draw it if it hasn't yet been drawn
46 if (PlaneIsFarEnoughAwayFromTileCenter(Axis.x)) {
47 GenerateNewTileIfNecessary (Axis.x);
48 }
49 if (PlaneIsFarEnoughAwayFromTileCenter(Axis.z)) {
50 GenerateNewTileIfNecessary (Axis.z);
51 }
52 }
53 }
54
55 // Check to see if the current landTile is still the closest one to the player.
56 // If not, find the closest tile and set that as landTile.
57 SwitchCurrentTileIfNecessary ();
58
59 }
60
61 /// <summary>
62 /// Flag a boolean true for each tile around landTile as each is drawn.
63 /// </summary>
64 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
65 void FlagChecklistTile(Axis currentAxis)
66 {
67 switch (currentAxis) {
68 case Axis.x:
69 if (PlaneDirectionFromTileCenter (Axis.x) > 0) {
70 tileChecklist [0] = true;
71 } else {
72 tileChecklist [1] = true;
73 }
74 break;
75 case Axis.z:
76 if (PlaneDirectionFromTileCenter (Axis.z) > 0) {
77 tileChecklist [2] = true;
78 } else {
79 tileChecklist [3] = true;
80 }
81 break;
82 case Axis.both:
83 if (PlaneDirectionFromTileCenter (Axis.x) > 0) {
84 if (PlaneDirectionFromTileCenter (Axis.z) > 0) {
85 tileChecklist [4] = true;
86 } else {
87 tileChecklist [5] = true;
88 }
89
90 } else {
91 if (PlaneDirectionFromTileCenter (Axis.z) > 0) {
92 tileChecklist [6] = true;
93 } else {
94 tileChecklist [7] = true;
95 }
96 }
97 break;
98 }
99
100 }
101
102 /// <summary>
103 /// Check whether all the tiles around the landTile are drawn.
104 /// </summary>
105 /// <returns><c>true</c>, if all tiles in tileChecklist are true, <c>false</c> otherwise.</returns>
106 bool TilesAreFull()
107 {
108 bool retVal = true;
109 foreach (bool item in tileChecklist)
110 if (!item)
111 retVal = false;
112 return retVal;
113 }
114
115 /// <summary>
116 /// Check whether the plane is far enough away from landTile's center. The tileGenerationThreshold defines that amount.
117 /// </summary>
118 /// <returns><c>true</c>, if the plane has crossed beyond the tileGenerationThreshold, <c>false</c> otherwise.</returns>
119 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
120 bool PlaneIsFarEnoughAwayFromTileCenter(Axis currentAxis)
121 {
122 return Mathf.Abs (GetPlaneDistanceFromTileCenter(currentAxis)) > tileGenerationThreshold;
123 }
124
125 /// <summary>
126 /// Check whether the player the has crossed over to a new tile.
127 /// </summary>
128 /// <returns><c>true</c>, if the player is no longer directly above landTile, <c>false</c> otherwise.</returns>
129 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
130 bool PlayerHasCrossedOverToANewTile(Axis currentAxis)
131 {
132 return false;
133 }
134
135 /// <summary>
136 /// Generates the new tile ahead of the player if one doesn't exist in that space yet.
137 /// </summary>
138 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
139 void GenerateNewTileIfNecessary(Axis currentAxis)
140 {
141
142 if (NewTileDoesNotYetExist (currentAxis)) {
143
144 Vector3 newPosition = new Vector3();
145
146 switch (currentAxis) {
147 case Axis.x:
148 newPosition = landTile.transform.position + new Vector3 (tileSize * PlaneDirectionFromTileCenter (Axis.x), 0, 0);
149 break;
150 case Axis.z:
151 newPosition = landTile.transform.position + new Vector3 (0, 0, tileSize * PlaneDirectionFromTileCenter (Axis.x));
152 break;
153 case Axis.both:
154 newPosition = landTile.transform.position +
155 new Vector3 (
156 tileSize * PlaneDirectionFromTileCenter (Axis.x),
157 0,
158 tileSize * PlaneDirectionFromTileCenter (Axis.z)
159 );
160 break;
161 }
162
163 Instantiate(newTile, newPosition, landTile.transform.rotation);
164 FlagChecklistTile (currentAxis);
165 }
166 }
167
168 /// <summary>
169 /// Check whether a tile exists in the spot we want to create one.
170 /// </summary>
171 /// <returns><c>true</c>, if a tile already occupies the space where we want to create one, <c>false</c> otherwise.</returns>
172 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
173 bool NewTileDoesNotYetExist(Axis currentAxis)
174 {
175 bool retVal = true; // return value assumes there is no tile in our way unless proven otherwise
176 GameObject[] tiles = GameObject.FindGameObjectsWithTag("LandTile"); // all tiles currently instantiated in the scene
177 float currentTilePosition = 0, // single-axis landTile position for x or z, double-axis position for x only
178 nextTilePosition = 0, // single-axis tile position for x or z, double-axis position for x only
179 altCurrentPos = 0, // double-axis landTile position for z
180 altNextPos = 0; // double-axis tile position for z
181
182
183 // iterate through all instantiated tiles
184 foreach (GameObject tile in tiles) {
185
186 switch (currentAxis) {
187 case Axis.x:
188 currentTilePosition = landTile.transform.position.x;
189 nextTilePosition = tile.transform.position.x;
190 break;
191 case Axis.z:
192 currentTilePosition = landTile.transform.position.z;
193 nextTilePosition = tile.transform.position.z;
194 break;
195 case Axis.both:
196 currentTilePosition = landTile.transform.position.x;
197 nextTilePosition = tile.transform.position.x;
198 altCurrentPos = landTile.transform.position.z;
199 altNextPos = tile.transform.position.z;
200 break;
201 }
202
203 // if the tile's single-axis position or first double-axis position is
204 // located at the coordinates where we want to create a new tile...
205 if (nextTilePosition == currentTilePosition + tileSize * PlaneDirectionFromTileCenter(Axis.x)) {
206
207 // if we're dealing with a corner piece (i.e. double-axis both x and z)...
208 if (currentAxis == Axis.both) {
209
210 // if tile's second double-axis position is
211 // located at the coordinates where we want to create a new tile...
212 if (altNextPos == altCurrentPos + tileSize * PlaneDirectionFromTileCenter (Axis.z)) {
213
214 // ...then a tile DOES exist where we want to create one, so return false
215 retVal = false;
216 }
217 } else {
218 // we're dealing with an adjacent piece (i.e. single-axis x only or z only)
219 // on the axis in question, a tile DOES exist where we want to create one, so return false
220 retVal = false;
221 }
222
223 }
224 }
225 return retVal;
226 }
227
228
229 /// <summary>
230 /// Gets the plane distance from tile center.
231 /// </summary>
232 /// <returns>The plane distance from tile center.</returns>
233 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
234 float GetPlaneDistanceFromTileCenter(Axis currentAxis)
235 {
236 float planePosition, landTilePosition;
237
238 if (currentAxis == Axis.x) {
239 planePosition = transform.position.x;
240 landTilePosition = landTile.transform.position.x;
241 }
242 else {
243 planePosition = transform.position.z;
244 landTilePosition = landTile.transform.position.z;
245 }
246 Debug.Log ("Distance: " + (planePosition - landTilePosition));
247 return planePosition - landTilePosition;
248 }
249
250 /// <summary>
251 /// Planes the direction from tile center.
252 /// </summary>
253 /// <returns>The direction from tile center.</returns>
254 /// <param name="currentAxis">The axis currently parralel to the player's facing, x or z. Both if the player is facing diagonally.</param>
255 float PlaneDirectionFromTileCenter(Axis currentAxis)
256 {
257
258 float distance = GetPlaneDistanceFromTileCenter (currentAxis);
259 float retVal = 0;
260 if (distance > 0)
261 retVal = 1;
262 else
263 retVal = -1;
264 return retVal;
265 }
266
267 /// <summary>
268 /// Switch the current landTile to a new tile if landTile is no longer the closest tile to the player.
269 /// </summary>
270 void SwitchCurrentTileIfNecessary()
271 {
272 if (Mathf.Abs(GetPlaneDistanceFromTileCenter (Axis.x)) > tileSize / 2 // if the player is no longer over landTile on x
273 || Mathf.Abs(GetPlaneDistanceFromTileCenter(Axis.z)) > tileSize / 2) // if the player is no longer over landTile on z
274 {
275 SwitchCurrentTile();
276 }
277
278 }
279
280 /// <summary>
281 /// Reassign landTile to be the closest tile to the player.
282 /// </summary>
283 void SwitchCurrentTile()
284 {
285 // all currently instantiated tiles
286 GameObject[] tiles = GameObject.FindGameObjectsWithTag("LandTile");
287
288 // iterate through all tiles
289 foreach (GameObject tile in tiles) {
290
291 Debug.Log ("Distance between current tile and others: " + (tile.transform.position - landTile.transform.position).magnitude);
292 // if the distance between the player and a given tile is less than that of the player and landTile
293 if (Mathf.Abs((transform.position - tile.transform.position).magnitude) < Mathf.Abs((transform.position - landTile.transform.position).magnitude)) {
294
295 // Reassign landTile to be the tile that is nearer the player.
296 landTile = tile;
297 }
298 }
299 }
300
301 }