2017-09-05 1 views
-2

La partie Cercle met les objets en l'air. Comment puis-je faire qu'ils seront sur le terrain? Ils sont debout dans les airs. En utilisant la formation carrée, ils sont au sol mais avec le cercle ils sont dans l'air.Pourquoi lors de l'instanciation d'objets, ils sont dans l'air et non sur le sol?

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

public class SquadFormation : MonoBehaviour 
{ 
    enum Formation 
    { 
     Square, Circle 
    } 

    public Transform squadMemeber; 
    public int columns = 4; 
    public int space = 10; 
    public int numObjects = 20; 

    // Use this for initialization 
    void Start() 
    { 
     ChangeFormation(); 
    } 

    // Update is called once per frame 
    void Update() 
    { 

    } 

    private void ChangeFormation() 
    { 
     Formation formation = Formation.Square; 

     switch (formation) 
     { 
      /*case Formation.Square: 

       for (int i = 0; i < 23; i++) 
       { 
        Transform go = Instantiate(squadMemeber); 
        Vector3 pos = FormationSquare(i); 
        go.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y); 
        go.Rotate(new Vector3(0, -90, 0)); 
       } 
       break;*/ 

      case Formation.Circle: 

       Vector3 center = transform.position; 
       for (int i = 0; i < numObjects; i++) 
       { 
        Vector3 pos = RandomCircle(center, 5.0f); 
        var rot = Quaternion.LookRotation(pos - center); 
        Instantiate(squadMemeber, pos, rot); 
       } 
       break; 
     } 
    } 

    Vector2 FormationSquare(int index) // call this func for all your objects 
    { 
     float posX = (index % columns) * space; 
     float posY = (index/columns) * space; 
     return new Vector2(posX, posY); 
    } 

    Vector3 RandomCircle(Vector3 center, float radius) 
    { 
     float ang = Random.value * 360; 
     Vector3 pos; 
     pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad); 
     pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad); 
     pos.y = center.y; 
     return pos; 
    } 
} 

In air

Ils devraient être l'instanciation sur le terrain (Terrain). Besoin de les positionner au sol.

Mise à jour:

C'est ce que j'ai essayé maintenant.

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

public class SquadFormation : MonoBehaviour 
{ 
    enum Formation 
    { 
     Square, Circle 
    } 

    public Transform squadMemeber; 
    public int columns = 4; 
    public int space = 10; 
    public int numObjects = 20; 
    public float yOffset = 1; 

    // Use this for initialization 
    void Start() 
    { 
     ChangeFormation(); 
    } 

    // Update is called once per frame 
    void Update() 
    { 

    } 

    private void ChangeFormation() 
    { 
     Formation formation = Formation.Circle; 

     switch (formation) 
     { 
      /*case Formation.Square: 

       for (int i = 0; i < 23; i++) 
       { 
        Transform go = Instantiate(squadMemeber); 
        Vector3 pos = FormationSquare(i); 
        go.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y); 
        go.Rotate(new Vector3(0, -90, 0)); 
       } 
       break;*/ 

      case Formation.Circle: 

       Vector3 center = transform.position; 
       for (int i = 0; i < numObjects; i++) 
       { 
        Vector3 pos = RandomCircle(center, 5.0f); 
        var rot = Quaternion.LookRotation(pos - center); 
        pos.y = Terrain.activeTerrain.SampleHeight(pos); 
        pos.y = pos.y + yOffset; 
        Instantiate(squadMemeber, pos, rot); 
       } 
       break; 
     } 
    } 

    Vector2 FormationSquare(int index) // call this func for all your objects 
    { 
     float posX = (index % columns) * space; 
     float posY = (index/columns) * space; 
     return new Vector2(posX, posY); 
    } 

    Vector3 RandomCircle(Vector3 center, float radius) 
    { 
     float ang = Random.value * 360; 
     Vector3 pos; 
     pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad); 
     pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad); 
     pos.y = center.y; 
     return pos; 
    } 
} 

J'ai ajouté un yOffset offset et ces deux lignes à l'intérieur de la boucle for:

pos.y = Terrain.activeTerrain.SampleHeight(pos); 
pos.y = pos.y + yOffset; 

Maintenant, ils sont sur le terrain, mais se trouvent sur le dos/estomac et non debout comme ils étaient dans la air.

lie down

+1

Vous venez de poser 5 questions .... Cela ne fonctionne pas comme ça et personne ne devrait écrire un code qui peut faire tout cela. Modifiez votre question et choisissez une seule question, puis affichez un code que vous avez essayé. Quand vous obtenez une réponse, vous créez une nouvelle question avec votre deuxième question .... – Programmer

+0

Pour répondre à votre question c'est dans votre titre, les objets instancient à (0,0) je crois. Peut se tromper. – jdmdevdotnet

+0

@jdmdevdotnet No. Terrain ont une hauteur différente dans un endroit différent. Vous devez utiliser Raycast ou SampleHeight pour obtenir la hauteur. 0,0 ne le fera pas, sauf si vous vous attendez à ce que toutes les tailles soient 0,0. – Programmer

Répondre

1

Pourquoi lors de l'instanciation des objets qu'ils sont dans l'air et non sur la terre?

Vous devez trouver un moyen de calculer la hauteur du terrain, puis l'utiliser comme valeur de l'axe des ordonnées.

Après avoir obtenu votre pos, modifiez l'axe y avec la fonction Terrain.activeTerrain.SampleHeight.

Vector3 pos = RandomCircle(center, 5.0f); 
pos.y = Terrain.activeTerrain.SampleHeight(pos); 

Peut-être ajouter un décalage en fonction du type de gameobject (Le yOffset doit être un flotteur)

pos.y = pos.y + yOffset; 

Maintenant, allez-y et instancier avec cette nouvelle pos:

var rot = Quaternion.LookRotation(pos - center); 
Instantiate(squadMemeber, pos, rot); 

Note:

Selon la taille de vous r, vous devez et devez continuer à changer la valeur du yOffset jusqu'à ce que vous obteniez la position désirée. Cette position devrait bien fonctionner pour le même personnage. Si vous voulez faire ceci aux GameObjects avec la taille différente, vous devez également modifier le yOffset jusqu'à ce que vous soyez satisfait.

+0

J'ai ajouté cette ligne au flotteur public supérieur yOffset = 1; alors ces deux lignes dans la boucle for: pos.y = Terrain.activeTerrain.SampleHeight (pos); pos.y = pos.y + yOffset; maintenant ils sont sur le sol mais ils sont couchés sur le dos et ne sont pas debout comme ils étaient en l'air. –

+1

Il serait préférable d'ajouter un autre EDIT dans votre question avec votre nouveau code et capture d'écran de ce qui ressemble maintenant. Cela rendra plus facile de savoir exactement où se situe le problème. – Programmer

+0

Edité ma question originale avec ce que j'ai fait. –

0

Pas une réponse réelle, mais quelques conseils:

Je vois un problème de base ici avec votre code étant genre de confusion de toute façon. Il y a des choses qui devraient être similaires qui ne le sont pas. Je pense que la base ici est que vous avez besoin d'une structure de base.

Tout d'abord, vous devriez commencer par identifier les pièces de base dont vous avez besoin ici.

Il y a trois choses fondamentales à résoudre:

  1. XY positions
  2. rotation position Z

dernier est le problème avec vos personnages gisant sur le sol. Voir la rotation de -90 degrés pour le carré? Je suppose que celui-ci fait cela. Mais une question plus urgente ici, voici une question pour vous: En dehors de la position XY, quelle devrait être la différence entre les carrés et les cercles? Réponse: aucune. Vous traitez les deux cas beaucoup plus différemment qu'ils ne devraient l'être. Le code devrait ressembler à ceci:

Position xyPosition; 
switch (formation) 
    case Circle: xyPosition = randomCirclePosition(someargument) 
    case Square: xyPosition = randomSquarePosition(someargument) 
Position position = rotateUpright(xyPosition) 
position = adjustZ(position) 

Voyez comment la différence est appliquée seulement à une partie?

La chose qui saute à mes yeux immédiatement sont les signatures: Vector2 FormationSquare et Vector3 RandomCircle. En particulier, Vector2 et Vector3. Ce sont deux approches complètement différentes. Pourquoi? Cela rend votre code inutilement hétérogène, le rend plus difficile à lire. Ne permet pas la structure claire que j'ai écrit ci-dessus. Pourquoi en avez-vous tiré autant? Pourquoi n'avez-vous pas copié l'ancien code du carré et l'avez-vous ajusté au besoin?

Ai-je raison de dire que vous avez copié le code carré à partir d'Internet? Et que vous avez des difficultés à le comprendre pour une raison quelconque? Peut-être parce que vous n'êtes pas familier avec les mathématiques derrière cela? Si oui, ma "réponse" est la suivante: Prenez le code carré et ne continuez pas jusqu'à ce que vous compreniez une seule ligne. Qu'est-ce qu'il fait, pourquoi il est nécessaire, ce qui se passe sans. Parfaitement bien si vous allez simplement et les lignes de sortie, alors regardez ce qui se passe dans le moteur. Ou demander à quelqu'un. Mais il est très important que vous compreniez chaque ligne à la fin.

Vous pourriez également vouloir mettre le code sur CodeReview quand il fonctionne. Je vois des problèmes ici et là dans le style. Comme le mystérieux 23 qui sort de rien.

Désolé si cela semblait un peu entêté ou similaire, ou si je me trompe la situation ici.