Reputation: 21
Disclaimer: So the title may not be overly accurate but its the closest I could get.
So I am making a strategy game in Unity and the idea is that there will be several types of 'unit' and they can choose out of a pool of weapons. These different 'units' all in inherit from their unit type then unit type inherits from a basic 'unit' abstract class and on the other side it is a similar story, weapon inherits from weapon type which then inherits from a basic 'weapon' abstract class. This isn't the problem, the problem is making the relationship between the specific unit and it's assigned weapon, in order for the unit class to see what weapon it has and to base its attack on the weapon assigned, accessing the varibles contained within, such as; range, damage, etc.
Because I work best visually I have drawn out a diagram showing what I mean to help those who are still confused as to my question
So unit at the top is the unit abstract class i have previously mentioned, then human is the unit type then soldier is the specific unit that will be instanciated later on, this (again as previously mentioned) is mirrored for weapon.
Upvotes: 2
Views: 107
Reputation: 1237
I would suggest you inject the weapons onto soldier when they initialise, then let the soldier to decide what weapon they want to use.
For example:
public class Solider : Human {
IEnumerable<IWeapons> _allAvailableWeapons;
IWeapon _selectedWeapon;
public Soldier(IEnumerable<IWeapon> weapons)
{
_allAvailableWeapons = weapons;
// some conditions
// Select the correct weapon for this soldier
_selectedWeapon = _allAvailableWeapons.Single(x => x.Id == "Something");
}
}
public class Civilian : Human
{
public Civilian()
{
}
}
Upvotes: 0
Reputation: 5920
Unity is Component based engine so it means that you should use Component
which can or cannot be inherited ( depending on the needs ). But basically without inheritance you can do this like such :
// Unit.cs
public class Unit : Component {
// logic for your Unit Component
}
// Human.cs
[RequireComponent(typeof (Unit))]
public class Human : Component {
Unit _parent;
public void Initialize(){
_parent = (Unit)GetComponentInParent(typeof(Unit));
}
}
// Soldier.cs
[RequireComponent(typeof (Human))]
public class Soldier: Component {
Human _parent;
Weapon _meWeapon;
public void Initialize(){
_parent = (Human)GetComponentInParent(typeof(Human));
}
public void AttachWeapon(Weapon wpn){
_meWeapon = wpn;
}
public void DetachWeapon(){
if(_meWeapon != null) {
Destroy(_meWeapon);
_meWeapon = null;
}
}
}
Then you can do the same with your Weapon
, RangedWeapon
and AK47
. But this method is basically not efficient because you're relating to other Component
s and have to change code in every single Component
when you want to improve something. Better way would be to inherit from each of these :
public class Unit : Component {
// logic for your Unit Component
}
public class Human : Unit {
}
public class Soldier : Human {
Weapon _weapon;
public void AttachWeapon(Weapon wpn){
_meWeapon = wpn;
}
public void DetachWeapon(){
if(_meWeapon != null) {
Destroy(_meWeapon);
_meWeapon = null;
}
}
}
Now you have to deal only with one Component
and you can ensure that Weapon
's type is adequate for this particular Component
:
//Soldier component
if(wpn is AK47) {
_meWeapon = wpn;
}
And of course if you need Unity
's built-in methods like Awake()
, Update()
then you can inherit from MonoBehaviour
instead of base Component
class.
To be then able to switch weapons you can just do simple call like :
Soldier solider = GetComponent<Soldier>();
soldier.AttachWeapon(AddComponent<AK47>());
Then inside your Soldier
component you can use the reference to that particular Weapon
.
And to detach your AK47
you can call :
Soldier soldier = GetComponent<Soldier>();
soldier.DetachWeapon();
Upvotes: 1
Reputation: 41
On thing you can do is having one public property (with getter and private setter) for the current weapon.
public class Soldier : Human
{
public Weapon CurrentWeapon {get; private set;}
[...]
}
You can then access the weapon from the soldier using :
public Soldier mySoldier = new Soldier();
mySoldier.CurrentWeapon;
Hope it helps !
Upvotes: 0