- Home /
What do you think of this? List, Vector 3 and Update
Hi there! I know, my question may sound too much generic, let me rush to the point... Here's what I've got:
using UnityEngine;
using System.Collections;
using System.Collections.Generic; // this line is for using a List
//TAG: Respawn --- since this is what it's doing right now...
public class EnemySpawnList : MonoBehaviour {
private List<Vector3> spawnPoint = new List<Vector3>();// The List of Vector 3, since we will need only positions.
private int spawnIndex; // The index to pick a Random Item of the List
public Vector3 spawnDecided; // A variable to declare the Item our Index has picked.
private Vector3[] p = new Vector3[8]; //AWESOME TRICK: I don't wanna store var and then manually say list.add this... so I'm making an array in which I'll store all the Items I want
// Use this for initialization
void Start () {
p[0] = new Vector3(85, 12, 0);
p[1] = new Vector3(-85,12,0);
p[2] = -p[0];
p[3] = -p[1];
p[4] = new Vector3(85, 20, 0);
p[5] = new Vector3(-85,20,0);
p[6] = -p[4];
p[7] = -p[5];
spawnPoint.InsertRange(0, p); // And then I Add all of them in my List, with just this line here... Majestic!
print ("Item's in my List: " + spawnPoint.Count);
}
// Update is called once per frame
void Update () {
spawnIndex = Random.Range (0,7);
TheFinalSpawnPoint();
}
public void TheFinalSpawnPoint(){
spawnDecided = spawnPoint[spawnIndex]; // WATCH IT: SquareBrackets!
}
}
I'm looking forward to make a Shuffle Bag out of this List(spawnPoint). Right now my enemies instantiate at a static vector picked up by my spawnDecided... that's good.
Do you think it would be wise to change every Update the Items of Array p? Say I'd like my enemies to spawn nearby the player, and to keep spawning nearby him even if he moves away, always at the same distances. Right now my enemies are uncapable of doing that, but what if I say that p[0] = new Vector3 ( myTarget.position.x + 85, myTarget.position.y +12, 0) and so on? Is that a wise method to achieve the result? I would have to assign those values in the Update though, wouldn't that be bad?
Could you please point me in the right direction? because at the very moment, I'm clueless... I just have a few suppositions which point to the way of how a MMORPG stores the speed/velocity of every player, predicting their next position and then recalculating possible errors...
Since I don't need to update this spawnIndex every frame, just only everytime an instantiate occurs ( which right now occurs every 5 seconds), I could store both the changing values of array p and spawnIndex into functions that run every n seconds... what about that?
I'm sorry I can't be anymore specific than that, I'm still pretty new to program, and because of that, would you mind being exhaustive in your answers? Please? Many thanks for your time! P.S.: constuctive critics to my code are appreciated too!
Answer by Azrapse · Oct 09, 2013 at 06:46 PM
I would recommend you to learn some all purpose programming tutorials or books, where you can learn the traditional algorithms and data structures. It will make you grow as a programmer and it will pave your mind so that you don't have to reinvent the wheel.
Back on topic, if I understand right your goal is to spawn enemies around the player at random positions, however these random positions are not totally random, but chosen from a list of 'templates'. And you want these template points to be hand picked by the programmer. Right?
This is how I would do it.
using UnityEngine;
using System.Collections.Generic; // We don't need the old .Net 1.1 collections most of the time.
using System.Linq; // I use this a lot for simplifying the work with collections.
public static class EnemySpawnProvider // We don't really need this to be attached to a game object. So no Monobehaviour. Instead, we use a static class.
{
private static List<Vector3> spawnPoints = new List<Vector3>(); // Note the static keyword
// This is run automatically on game launch. It's a static constructor
public static EnemySpawnProvider()
{
// Add some sample points.
spawnPoints.AddRange(new[]
{
new Vector3(85, 12, 0),
new Vector3(-85,12,0),
new Vector3(85, 20, 0),
new Vector3(-85,20,0)
};
// Add opposite points also, as in your example, by using the ones that are already there, but multiplying them by -1.
spawnPoints.AddRange(spawnPoints.Select(p => -p).ToArray());
print ("Item's in my List: " + spawnPoint.Count);
}
// You call this method with EnemySpawnProvider.GetRandomPoint() from anywhere in the code
public static Vector3 GetRandomPoint()
{
var index = Random.Range (0, spawnPoints.Count-1);
return spawnPoints[index];
}
}
Whenever you want to spawn an enemy, you need the position of the player and you add to it one of these random points:
var enemySpawnPoint = player.transform.position + EnemySpawnProvider.GetRandomPoint();
You don't need to reshuffle every frame, only when needing one. And reshuffling every time (without taking out points from the pool) is the same as picking one at random.
Aww! that seems very smart! I know I should read some book on the topic, maybe I should also attend a course... but I'm enjoying this naive approach for the moment, thanks anyway for that suggestion ( oh if you happen to have a couple of titles of book you'd feel to recommend me please let me know, it'd be better for me ins$$anonymous$$d of just picking up the first book I get my hand on); I really like your answer, it shows me some interesting tricks! Would you $$anonymous$$d to explain me some more the line 21? I mean, your .AddRange seems a lot more brief and straight than $$anonymous$$e... sorry to bother you but I'd like to fully understand!
For books, I cannot really recommend any single one in particular, but search for something like Introduction to Object Oriented Program$$anonymous$$g with C# (or even Java).
The method List.AddRange(IEnumerable enumeration)
adds every single element of the enumeration to the list. It's similar to the InsertRange
method you used, only that it just adds them to the end of the list, so no insertion index is needed.
You can declare an array like
var intValues = new[] {1, 2, 3, 4};
The part to the right defines an array whose type is inferred from the values provided between the curly braces. In that case, because all values are int
s, that is an int[]
array.
An array is the most primitive form of enumeration. An enumeration is anything that you can enumerate, that is, loop over while taking elements, and it usually implements IEnumerable
, where T
is the type of the elements. So we can use an array as argument to the call of AddRange()
.
Finally, in line 21 I make use of a Linq query. You should search for a Linq tutorial if you are interested on it. With Linq, basically, you can manipulate enumerations, twist them, combine them, filter them out, sort them, etc, by stating what you want to do, ins$$anonymous$$d of program$$anonymous$$g step-by-steps algorithms to do so.
In that line I take the list of spawn points (a list is also an enumeration), then for each element I generate its opposite (that is what the Select call does), and get all newly generated elements into an array (that is what the ToArray call does) that I finally pass to AddRange.
$$anonymous$$any many thanks Azrapse! Both for the neat explanation and for the patience! I'd thumb up you if I could!
Your answer
Follow this Question
Related Questions
List/Array Not Updating 2 Answers
How to acces the value of List of arrays 0 Answers
Array sub elements setup question 1 Answer
How can you do calculations on two lists? 1 Answer
A node in a childnode? 1 Answer