spawn points from a .txt file?

So I’m trying to figure this out in unity. I’ve seen it done in production games, but am unfamiliar with how the back end of it is done. Rather then create manually each spawn point for each mob in the editor, as an example you have your world made and there is a large area that pertains to a city.

I’ll use L2 as an example as it’s the easiest to use because it has a setup similar to what I am trying to accomplish.(most people probably know where this is from).

So the npcloc.txt would contain the xyz of each mob, seperated into commented sections. Here is an example

//starter town

npc_begin [Gremlin] pos={-18216;110597;-2500;16384} total=1 respawn=5 mins npc_end

//starter town end

//dungeon 1

npc_begin [Gremlin] pos={-92234;344532;-89475;16384} total=1 respawn=24hours npc_end

//dungeon1 end

So the question is how to make an npc generator recognize the outside text.

and would this be more efficient then running each spawn through the editor. I guess it’s more of an efficiency type problem.
so beyond having a npc generator and manually doing each spawn point, can this be done?

I would recommend to use xml instead.

Small example link

not sure that is the way to go anymore.

I was thinking if I create an array of all mobs/npc’s on startup I could then grab the npc from there and instantiate the npc’s vector3 to where I want it.

something like

using UnityEngine;
using System.Collections;

public class NPCPOS : MonoBehaviour {
//find all the gamebojects tagged as npc.

    public GameObject NPC;
    void NPCPOS() {
        NPC = GameObject.Find("NPC");
        
    }
}

// this is how I could do spawn locations
    void FixedUpdate()
    {
    npc = Instantiate(gremlin, new Vector3(40, 2, 0), Quaternion.identity) as GameObject;
     }

just trying to think of speed and efficiency. Does this make sense?

thanks for your time.

anything?

Says the guy wanting to use a txt file. :wink:

I have some example XML code for loading game objects from a text file I can show you tomorrow (after I wake up, as it has a lot of editing that needs to be done to show a snippet). Till then, good night.

Okay, bright and early in the morning. For reading and writing gameobjects to an xml file, this is what I use (well, with loads of stuff cut out to simplify it).

public class FileMonster : MonoBehaviour 
{

	//Objects we can save or load
	public GameObject[] saveLoadables;
	private string levelDirectory;

	void Start()
	{
		//Set directory for data files
		levelDirectory = Application.persistentDataPath + "/Levels/";
		
		//Check to see if directory exists, and create if not
		if(!Directory.Exists(levelDirectory))
			Directory.CreateDirectory(levelDirectory);
	}
	
	public void SaveLevel(string levelName)
	{
		using(XmlTextWriter xml = new XmlTextWriter(levelDirectory + levelName + ".lvl", Encoding.ASCII))
		{
			//Start her up
			xml.WriteStartDocument();
			xml.WriteWhitespace("\n");
			xml.WriteStartElement("Level");
			xml.WriteWhitespace("\n");
			
			//Write GameObject stuff		
			xml.WriteStartElement("GameObjects");
			foreach(GameObject levelPiece in GameObject.FindObjectsOfType(typeof(GameObject)))
			{
				//Make sure the object has the ObjectName monobehaviour
				if(levelPiece.GetComponent<ObjectName>() != null)
				{
					foreach(GameObject saveable in saveLoadables)
					{
						//Check if the object name in saveLoadables is the same as the object we are trying to save
						if(levelPiece.GetComponent<ObjectName>().objName.Equals(saveable.GetComponent<ObjectName>().objName))
						{
							xml.WriteStartElement(levelPiece.GetComponent<ObjectName>().objName);
							{
								//Position
								xml.WriteElementString("POSX", levelPiece.transform.position.x.ToString());
								xml.WriteElementString("POSY", levelPiece.transform.position.y.ToString());
								xml.WriteElementString("POSZ", "0");
								
								//Rotation
								xml.WriteElementString("ROTX", levelPiece.transform.rotation.x.ToString());
								xml.WriteElementString("ROTY", levelPiece.transform.rotation.y.ToString());
								xml.WriteElementString("ROTZ", levelPiece.transform.rotation.z.ToString());
								xml.WriteElementString("ROTW", levelPiece.transform.rotation.w.ToString());
							}
							xml.WriteEndElement();
							xml.WriteWhitespace("\n");
						}
					}
				}
			}
			xml.WriteEndElement();
			xml.WriteWhitespace("\n");
			
			xml.WriteEndElement();
			xml.WriteWhitespace("\n");
			xml.WriteEndDocument();
		}
	}
	
	public void loadLevel(string levelName)
	{
		
		//Delete EVERYTHING
		foreach(GameObject levelPiece in GameObject.FindObjectsOfType(typeof(GameObject)))
		{
			Destroy(levelPiece);
		}
		
		Vector3 pos = new Vector3(0, 0, 0);
		Quaternion rot = new Quaternion(0, 0, 0, 0);
		using(XmlTextReader reader = new XmlTextReader(levelDirectory + levelName + ".lvl"))
		{
			while(reader.Read())
			{
				if(reader.IsStartElement())
				{				
					foreach(GameObject obj in saveLoadables)
					{
						if(obj.GetComponent<ObjectName>() != null)
						{
							if(reader.Name.Equals(obj.GetComponent<ObjectName>().objName))
							{
								objectCount++;
								//Position
								pos.x = float.Parse(reader.ReadElementString());
								pos.y = float.Parse(reader.ReadElementString());
								pos.z = float.Parse(reader.ReadElementString());
								//Rotation
								rot.x = float.Parse(reader.ReadElementString());
								rot.y = float.Parse(reader.ReadElementString());
								rot.z = float.Parse(reader.ReadElementString());
								rot.w = float.Parse(reader.ReadElementString());
								
								Instantiate(obj, pos, rot);
							}
						}
					}						
				}
			}
		}
	}
}

Now, something you need to know is that the script ‘ObjectName’ is a script, that literally only holds the objects name. I used it because I didn’t want to have to parse the object name with (clone). Any questions just ask.