You can also Instantiate in your custom serialized class you don't need the FireBallBehaviour.
Best way to do it i found is making a custom serialized Player class that has instances of your Weapon class which has an instance of an Ammo class.
the Player class could look something like this:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class PlayerCharacter
{
//public NetworkPlayer newtWorkPlayer;
public int playerID;
public GameObject characterObject;
public string characterName;
public float walkSpeed;
public int health;
public Vector3 spawnPosition;
public List<Weapon> weapons = new List<Weapon>();
public Weapon equipedWeapon;
public PlayerCharacter()
{
playerID = 0;
characterObject = null;
characterName = "";
walkSpeed = 0;
health = 0;
}
public PlayerCharacter(/*NetworkPlayer nP,*/ int pID, GameObject cO, string cN, float wS, int h, Vector3 sP)
{
//newtWorkPlayer = nP;
playerID = pID;
characterObject = Network.Instantiate(cO, sP, Quaternion.identity, 0)as GameObject;//GameObject.Instantiate(cO,sP,Quaternion.identity)as GameObject;
characterName = cN;
walkSpeed = wS;
health = h;
spawnPosition = sP;
}
public void TakeDamage (int takeDamage)
{
health -= takeDamage;
}
public void Movement (Vector3 target)
{
characterObject.transform.position += target;
}
}
Your Weapon class:
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Weapon
{
public GameObject weaponObject;
public WeaponType typeOfWeapon;
public Ammo ammo;
public Weapon (GameObject wO, WeaponType tOW, Ammo a)
{
weaponObject = wO;
typeOfWeapon = tOW;
ammo = a;
}
public void UseWeapon()
{
switch(typeOfWeapon)
{
case WeaponType.FireBall:
//some weapon code here
break;
case WeaponType.RidiculousHugeGun:
//some weapon code here
break;
case WeaponType.MegaAwesomeMagicPower:
//some weapon code here
break;
case WeaponType.Knife:
//some weapon code here
break;
}
}
}
public enum WeaponType
{
FireBall,
RidiculousHugeGun,
MegaAwesomeMagicPower,
Knife
}
Your Ammo class:
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Ammo
{
public GameObject ammoObject;
public int damage;
public float moveSpeed;
public Ammo(GameObject aO, int d, float mS)
{
ammoObject = GameObject.Instantiate(aO)as GameObject;
damage = d;
moveSpeed = mS;
}
public IEnumerator Movement (Vector3 target)
{
while(ammoObject != null)
{
ammoObject.transform.position = ammoObject.transform.forward+target*moveSpeed*Time.deltaTime;
yield return null;
}
}
}
public enum AmmoType
{
FireBallBall,
RidiculousHugeBullet,
MegaAwesomeMagicPowerEffect,
None
}
Then you would have a PlayerController thats Monobehaviour to handle all the Input and Collision detection:
I only give a movement example here because its getting to much code here already, but i guess you can imagine how you would do the same with the weapons. Since you're weapon is accessible through the player instance as player.currentWeapon or the ammo through player.currentWeapon.ammo
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
public PlayerCharacter player;
void Update ()
{
if(Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
{
player.Movement(new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"))*player.walkSpeed*Time.deltaTime);
}
}
}
In multiplayer the player gets his instance from the GameServer:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GameServer : MonoBehaviour
{
public List<PlayerCharacter> players = new List<PlayerCharacter>();
private int playerCount = 0;
void OnPlayerConnected(NetworkPlayer player)
{
networkView.RPC("CreatePlayer", player);
Debug.Log("Player " + playerCount + " connected from " + player.ipAddress + ":" + player.port);
}
[RPC]
void CreatePlayer()
{
playerCount++;
PlayerCharacter playerChar = new PlayerCharacter(/*player,*/ playerCount, (GameObject)Resources.Load("Player"), "Player"+playerCount, 5, 100, Vector3.zero);
playerChar.characterObject.AddComponent<PlayerController>().player = playerChar;
players.Add(playerChar);
}
}
one last thing @ Géry Arduino : I don't see how your example is generic at all? It's not typesafe anywhere, since you are committing the actual data type. for reference about generics read this