- Home /
How to go about mounting weapons on spaceships and storing these.
I have a space ship game im making that I want to allow mounting of weapons and then firing them in script. I have many different factions and ship classes/types.
I will create my weapons as prefabs and then call the appropriate weaponControl script on each weapon to perform the firing from each ship's central control script.
My question is dealing with my central script on each ship that controls calling the appropriate functions on each weapon. I know i'll have a list of each weapon and its control script to call. The biggest problem is how i populate this list (as each list has a different size compared to other ship classes) and how i can store the wanted locations and rotations for each weapon slot the ship has, when i also have to take into account different ship classes/types. If i add a weapon to the ship, i wnat it to fill the first most weapon slot of its type and is then parented to the ship at local position defined in the weapon transform arrays in the ship's central script.
How do i make different weapon and location/rotation arrays for every ship class? I know I use the inspector, but how do i do this for every ship if the array is of transforms to store position and rotation of each weapon slot?
Can do do this in script and have a separate script per ship? Would it be inefficient if i have empty gameobjects with position/rotation i want for each slot parented to the ship for script reference? How ineffective would this be in mobile?
Answer by dubbreak · Feb 13, 2013 at 04:18 AM
Nothing bad about empty game objects from a performance perspective (no draw calls since it doesn't have a renderer and very low mem overhead, plus you have to store it somehow). There are lots of ways to skin this cat and empty objects is one of them. Create a prefab for each of your ship types with empty objects for the locations. Then reference them in the ship script.
public transform weaponLocationStarboard;
You could also add a script to your "empty" object so that you can add info to your weapon locations.
When I have a lot of objects subbed to something I'll usually have a class/script I attach so I can do something like:
private MyThing[] myThings;
void Start ()
{
//get ALL the things
myThings = this.GetComponentsInChildren<MyThing>().OrderBy(n => n.ID).ToArray ();
}
In some situations it's a lot easier (e.g. 20 slots you need ordered from id 1-20).
ok, so use empty gameobjects as placeholders for the mountpoints, then reference them later in start() and store them and data in arrays? Then use those for weapon mounts? I wasn't sure if empty gameobjects would cause a lot of overhead processing if i have like 50ships iterating over 15 gameobjects and such.
and in this line: myThings = this.GetComponentsInChildren<$$anonymous$$yThing>().OrderBy(n => n.ID).ToArray ();
What does the part that says ".OrderBy(n => n.ID)" mean? If you don't want to explain i can easily look up documentation, i just figured you'd explain it in depth as you seem to have used this before.
Sorry I could have been clearer. So you can reference stuff directly by having a public member in your script (attached to your ship object) that you then drag a reference to. That was my first suggestion.
The second suggestion is making the placeholders/slots have a type. So add a script component to your mountpoint (call it mountpoint even) then just duplicate as many of them as you need. It's probably prudent to make them prefabs incase you need to change something about a mountpoint in general. I really don't think you need to worry about the overhead aspect. References to an object that just has a script doesn't really do anything other than a tiny amount of memory. If you have that many slots it's gonna use some memory anyhow. I mean you could use a config file and load them into structs or an array to $$anonymous$$imize objects, but I think that's a premature optimization. Unless your mountpoint and an Update() and is calculating stuff every frame you shouldn't have an issue (feel free to berate me later if I'm wrong).
As for the line of code: myThings = this.GetComponentsInChildren<$$anonymous$$yThing>().OrderBy(n => n.ID).ToArray ();
I assume you understand the get componentInChildren part (it just gets a list of the children object of that type.. in your case mountpoint). The OrderBy is a piece of linq code I snuck in. You'll have to use
using System.Linq;
To use that. So if I have a member of my $$anonymous$$yThing class called ID
public class $$anonymous$$yThing
{
public int ID;
public string Name;
}
I can then quickly sort then by the ID when grabbing my list. The n=> n.id is a lambda function. There is other syntax for linq, I prefer lambdas. if you read the => as "such that" it usually makes them easier to read. N such that nN's name is used byt the order by. You could do a where clause (like in sql) to do something like public enum $$anonymous$$ountType { weapon, sensor, defense }
this.GetComponentsInChildren<mountpoint>().Where(n => n.mountType == $$anonymous$$ountType.weapon ).ToArray ();
So select all the mount points where N exists such that N's mountType is equal to the weapon $$anonymous$$ountType.
ok. you seemed to have covered all the bases. thanks for the help. I'm glad i got such a quick, thorough and easy to read reply. $$anonymous$$ost people would have been annoyed i asked so many questions or asked about their post. Thanks for being so understanding.
Glad I could help. It made me think about how I'd solve the problem.
I figured I had to explain the linq syntax. I'm a little linq obsessed, but only because it has made my life so much easier. Saying what you want (declarative) is so much easier and clearer when you go back to read it (rather than the imperative style of looping and grabbing what you need into another list). It's well worth the learning curve (which isn't that bad since there are tons of examples out there now).