Pourquoi alors si je devais initialiser une chaîne ou un entier, je pourrais simplement faire ceci:
Vector3[,] coordsList = new Vector3[11, 11]
{
{new Vector3(-1.32f,1.32f), new Vector3(-1.08f,1.32f), new Vector3(-0.84f,1.32f), new Vector3(-0.6f,1.32f), new Vector3(-0.36f,1.32f), new Vector3(-0.12f,1.32f), new Vector3(0.12f,1.32f), new Vector3(0.36f,1.32f), new Vector3(0.6f,1.32f), new Vector3(0.84f,1.32f), new Vector3(1.08f,1.32f) },
{new Vector3(-1.32f,1.08f), new Vector3(-1.08f,1.08f), new Vector3(-0.84f,1.08f), new Vector3(-0.6f,1.08f), new Vector3(-0.36f,1.08f), new Vector3(-0.12f,1.08f), new Vector3(0.12f,1.08f), new Vector3(0.36f,1.08f), new Vector3(0.6f,1.08f), new Vector3(0.84f,1.08f), new Vector3(1.08f,1.08f) },
{new Vector3(-1.32f,0.84f), new Vector3(-1.08f,0.84f), new Vector3(-0.84f,0.84f), new Vector3(-0.6f,0.84f), new Vector3(-0.36f,0.84f), new Vector3(-0.12f,0.84f), new Vector3(0.12f,0.84f), new Vector3(0.36f,1.32f), new Vector3(0.6f,0.84f), new Vector3(0.84f,0.84f), new Vector3(1.08f,0.84f) },
{new Vector3(-1.32f,0.60f), new Vector3(-1.08f,0.60f), new Vector3(-0.84f,0.60f), new Vector3(-0.6f,0.60f), new Vector3(-0.36f,0.60f), new Vector3(-0.12f,0.60f), new Vector3(0.12f,0.60f), new Vector3(0.36f,0.60f), new Vector3(0.6f,0.60f), new Vector3(0.84f,0.60f), new Vector3(1.08f,0.60f) },
{new Vector3(-1.32f,0.36f), new Vector3(-1.08f,0.36f), new Vector3(-0.84f,0.36f), new Vector3(-0.6f,0.36f), new Vector3(-0.36f,0.36f), new Vector3(-0.12f,0.36f), new Vector3(0.12f,0.36f), new Vector3(0.36f,0.36f), new Vector3(0.6f,0.36f), new Vector3(0.84f,0.36f), new Vector3(1.08f,0.36f) },
{new Vector3(-1.32f,0.12f), new Vector3(-1.08f,0.12f), new Vector3(-0.84f,0.12f), new Vector3(-0.6f,0.12f), new Vector3(-0.36f,0.12f), new Vector3(-0.12f,0.12f), new Vector3(0.12f,0.12f), new Vector3(0.36f,0.12f), new Vector3(0.6f,0.12f), new Vector3(0.84f,0.12f), new Vector3(1.08f,0.12f) },
{new Vector3(-1.32f,-0.12f), new Vector3(-1.08f,-0.12f), new Vector3(-0.84f,-0.12f), new Vector3(-0.6f,-0.12f), new Vector3(-0.36f,-0.12f), new Vector3(-0.12f,-0.12f), new Vector3(0.12f,1.32f), new Vector3(0.36f,-0.12f), new Vector3(0.6f,-0.12f), new Vector3(0.84f,-0.12f), new Vector3(1.08f,-0.12f) },
{new Vector3(-1.32f,-0.36f), new Vector3(-1.08f,-0.36f), new Vector3(-0.84f,-0.36f), new Vector3(-0.6f,-0.36f), new Vector3(-0.36f,-0.36f), new Vector3(-0.12f,-0.36f), new Vector3(0.12f,-0.36f), new Vector3(0.36f,-0.36f), new Vector3(0.6f,-0.36f), new Vector3(0.84f,-0.36f), new Vector3(1.08f,-0.36f) },
{new Vector3(-1.32f,-0.6f), new Vector3(-1.08f,-0.6f), new Vector3(-0.84f,-0.6f), new Vector3(-0.6f,-0.6f), new Vector3(-0.36f,-0.6f), new Vector3(-0.12f,-0.6f), new Vector3(0.12f,-0.6f), new Vector3(0.36f,-0.6f), new Vector3(0.6f,-0.6f), new Vector3(0.84f,-0.6f), new Vector3(1.08f,-0.6f) },
{new Vector3(-1.32f,-0.84f), new Vector3(-1.08f,-0.84f), new Vector3(-0.84f,-0.84f), new Vector3(-0.6f,-0.84f), new Vector3(-0.36f,-0.84f), new Vector3(-0.12f,-0.84f), new Vector3(0.12f,-0.84f), new Vector3(0.36f,-0.84f), new Vector3(0.6f,-0.84f), new Vector3(0.84f,-0.84f), new Vector3(1.08f,-0.84f) },
{new Vector3(-1.32f,-1.08f), new Vector3(-1.08f,-1.08f), new Vector3(-0.84f,-1.08f), new Vector3(-0.6f,-1.08f), new Vector3(-0.36f,-1.08f), new Vector3(-0.12f,-1.08f), new Vector3(0.12f,-1.08f), new Vector3(0.36f,-1.08f), new Vector3(0.6f,-1.08f), new Vector3(0.84f,-1.08f), new Vector3(1.08f,-1.08f) },
};
Mais si je veux initialiser un Vector3 alors je dois faire: p>
Vector3 coordinate = new Vector3(1f,1f,1f);
Le contexte est que je créais un tableau assez grand et que je devais écrire un nouveau Vector3 ... à chaque fois et cela devenait assez fastidieux:
int number = 1; string word = "word";
Mais pourtant, cela aurait été beaucoup plus facile s'il avait été un tableau d'entiers? De quoi s'agit-il avec un Vector3 qui nécessite ce nouveau mot-clé qu'un entier ou une chaîne n'a pas?
4 Réponses :
Sur la base des commentaires récents, je voudrais proposer cette solution (via une méthode d'extension).
Vector3[,] coordsList = new Vector3[2, 2]
{
{(-1.32f,1.32f), (-1.32f,1.32f)},
{(-1.32f,1.32f), (-1.32f,1.32f)}
};
et ensuite vous pourriez utiliser une méthode d'extension ...
public class Vector3
{
public Vector3(float x, float y)
{
this.X = x;
this.Y = y;
}
public float X { get; set; }
public float Y { get; set; }
public static implicit operator (float X, float Y)(Vector3 value)
{
return (value.X, value.Y);
}
public static implicit operator Vector3 ((float X, float Y) value)
{
return new Vector3(value.X, value.Y);
}
}
Certes, la solution originale serait plus efficace, mais je ne savais pas que vous utilisiez une structure d'Unity à l'époque. Cependant, cette solution tente toujours de résoudre le même problème de lisibilité et de code répétitif.
Je suppose que l'objectif de votre question est de faire sur la lisibilité et la refactorisation du code répétitif. Vous pouvez utiliser des tuples à côté de opérateurs implicites pour en faire un peu plus ce que vous voulez ....
public static class Vector3Extensions
{
public static Vector3[,] ToVector3(this (float X, float Y, float Z)[,] value)
{
int columnCount = value.GetUpperBound(0);
int rowCount = value.GetLength(0);
var result = new Vector3[rowCount, columnCount];
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < columnCount; j++)
{
var tuple = ((float X, float Y, float Z))value.GetValue(i, j);
result[i, j] = tuple.ToVector3();
}
}
return result;
}
public static Vector3 ToVector3(this (float X, float Y, float Z) value)
{
return new Vector3(value.X, value.Y, value.Z);
}
}
alors vous pouvez le construire comme ceci ...
var list = new (float X, float Y, float Z)[2, 2]
{
{(-1.32f, 0f, 1.32f), (-1.32f, 0f, 1.32f)},
{(-1.32f, 0f, 1.32f), (-1.32f, 0f, 1.32f)}
};
Vector3[,] coordsList = list.ToVector3();
J'étais sur le point de répondre avec quelque chose comme ça, mais je pense qu'ils utilisent la structure Vector3 d'Unity, et à partir de C # 7, il n'est actuellement pas possible de créer un opérateur personnalisé pour un type de données que vous n'avez pas défini.
@bug - l'héritage de l'objet ne serait-il pas une option?
@Svek C'est une struct , donc non.
Vector3[][] list = new (float x, float y)[][]
{
new[] { (1.5f, 3.4f), (1.5f, 6.8f) },
new[] { (1.5f, 3.4f), (1.5f, 6.8f) },
new[] { (1.5f, 3.4f), (1.5f, 6.8f) },
new[] { (1.5f, 3.4f), (1.5f, 6.8f) },
}.Select(r => r.Select(v => new Vector3(v.x, v.y)).ToArray()).ToArray();
You could use Value Tuples (now supported in the latest version of Unity 2018.3) to construct your data in a readable and less tedious way - then you can use Select to transform these into Vector3s.I think most of the comments adequately cover your questions about the hows and whys of the new keyword here.
La raison pour laquelle Vector3 nécessite le mot clé new est qu'un Vector3 est une structure intégrée à Unity, donc chaque fois que vous utilisez le nouveau mot-clé, vous créez une nouvelle instance d'une structure Vector3 , alors qu'avec une string ou un int , ces types de données de base proviennent de C #.
J'espère que cela aidera à expliquer la différence!
Ce n'est pas une classe mais une struct . new est requis pour appeler le constructeur.
Merci pour l'aide! J'ai modifié la réponse pour être plus correcte.
Vos coordonnées sont une grille en miroir XY, ce qui signifie que vous n'avez qu'environ 6 valeurs uniques. Cependant, pour faciliter les choses, nous garderons également une trace des négatifs.
Vector3[,] coordsList = new Vector3[11,11];
void Init() {
for ( int x = 0; x < coordsList.GetLength(0); x++) {
for ( int y = 0; y < coordsList.GetLength(1); y++ ) {
coordsList[x, y] = new Vector3(-values[x], values[y]);
}
}
}
Maintenant, utilisez une boucle for imbriquée pour remplir votre tableau de coords:
float[] values = new float[] {
1.32f, 1.08f, 0.84f, 0.6f, 0.36f, 0.12f,
-0.12f, -0.36f, -0.6f, -0.84f, -1.08f, -1.32f };
Si vous souhaitez conserver des coordonnées disparates (c'est-à-dire non mappées sur une grille), il existe d'autres moyens de former les données d'entrée, mais la conversion en Vector3 ne se fera pas changer beaucoup du tout.
Parce que C # définit des littéraux pour les types courants tels que les chaînes et les entiers.
C'est probablement peu de confort maintenant, en particulier pour Unity, mais C # 8 combat cette verbosité avec sa fonctionnalité nouvelles-expressions de type cible vu ici .
Remarque: avec la sélection rectangulaire, vous n'avez vraiment pas besoin de taper autant ... Maintenez la touche "Alt" enfoncée lorsque vous faites la sélection et sélectionnez la colonne - la saisie remplira toutes les lignes en même temps ...
En regardant ce vecteur, il n'y a que 11 valeurs flottantes uniques. Je les coderais simplement en tant que tableau et j'écrirais quelques lignes pour générer le tableau vectoriel lui-même.
Et, plus techniquement,
struct System.Int32n'a pas de constructeur autre que celui par défaut, vous ne pouvez donc pas direvar i = new int (42);. Je suppose queVector3est une structure. Quand vous dites:new Vector3 (-1.32f, 1.32f),, vous invoquez son constructeur qui prend deux flottants. S'il s'agit d'unestruct, il a un constructeur par défaut écrit par le système qui initialise simplement tous ses membres à leurs valeurs par défaut.La réponse simple pour OP est que
intest un type primitif etVector3est un type complexe. Avec un tableau de cette taille, vous devriez probablement chercher à le générer par programme, en particulier c'est un modèle de grille défini et constant. Un tableau 1D de valeurs dans lesquelles vous indexez à partir d'une boucle imbriquée pour serait idéal.