2017-07-22 6 views
1

Je travaille sur des choses pour un moteur de jeu simple dans xna que je vais utiliser pour de futurs projets. C'est définitivement inspiré par le framework Unity. Je travaille sur un système de composants gameobject & en ce moment et je suis resté bloqué sur le clonage d'un gameobject.Récupère un type de variable et l'utilise comme argument pour la méthode générique

Voilà comment je suis en train de le mettre en œuvre,

public static GameObject CloneGameObject(GameObject obj, Vector2 position, float scale) 
{ 
    var clone = new GameObject(); //Create a entirely new gameobject 
    foreach (var comp in obj.components) //Clone all the components 
    { 
     Type t = comp.GetType(); 
     clone.components.Add(Component.CloneComponent<t>()); //This obviously doesn't work 
    } 
    clone.position = position; 
    clone.scale = scale; 

    AllGameObjects.Add(clone); 
    return clone; 
} 

Ce que je veux est coincé à la façon d'obtenir le type de composants à utiliser comme un argument générique.

Tout ce que je fais avec le composant à cloner est actuellement en train de changer simplement le propriétaire du clone: ​​

public static TComponent CloneComponent<TComponent>(Component toClone) where TComponent : Component, new() 
{ 
    var clone = new TComponent(); 

    clone.gameObject = toClone.gameObject; 

    return clone; 
} 

Le système de composants est simple, tous les composants héritent de la classe de composants.

Exemple:

class PlayerController : Component 
 
{ 
 
    public float jumpForce = 5; 
 
    public float walkSpeed = 2; 
 

 
    RigidBody rb; 
 
    Collider col; 
 

 
    public override void Start() 
 
    { 
 
     base.Start(); 
 

 
     rb = gameObject.GetComponent<RigidBody>(); 
 
     col = gameObject.GetComponent<Collider>(); 
 
    } 
 

 
    bool canJump { get { return jumps > 0; } } 
 
    int jumps = 1; 
 
    int maxJumps = 1; 
 
    public override void Update(GameTime gameTime) 
 
    { 
 
     rb.velocity = new Vector2(Input.GetAxisInputs(Keyboard.GetState(), "Horizontal") * walkSpeed, rb.velocity.Y); 
 
     if (Input.GetKeyOnDown(Keyboard.GetState(), Keys.Space) && canJump) 
 
     { 
 
      rb.velocity = new Vector2(rb.velocity.X, -jumpForce); 
 
      jumps--; 
 
     } 
 

 
     if (!col.PlaceIsFree(new Vector2(0, 1))) 
 
      jumps = maxJumps; 
 
      
 
     base.Update(gameTime); 
 
    } 
 
}

(ne peux pas obtenir à formater correctement des exemples de code si je viens d'utiliser un extrait de css: //)

Im ne demande pas quoi que ce soit sur lui-même le clonage , simplement comment je peux obtenir l'argument générique correct ou s'il y a une autre façon de l'implémenter.

Répondre

1

Vous devez modifier une signature de CloneComponent fonction:

public static TComponent CloneComponent<TComponent>(TComponent toClone) where TComponent : Component, new() 

Et alors vous devriez appeler cette fonction comme:

foreach (var comp in obj.components) //Clone all the components 
{ 
    clone.components.Add(Component.CloneComponent(comp)); 
} 

Vous pouvez également utiliser le sucre syntaxique pour simplifier le code d'invocation:

public static TComponent Clone<TComponent>(this TComponent toClone) where TComponent : Component, new() 
{ 
    if (toClone == null) 
    { 
     throw new ArgumentNullException(nameof(toClone)); 
    } 

    var clone = new TComponent(); 

    clone.gameObject = toClone.gameObject; 

    return clone; 
} 

Et la boucle serait:

foreach (var comp in obj.components) //Clone all the components 
{ 
    clone.components.Add(comp.Clone()); 
}