Je fais un jeu basé sur une grille. Pour cela, j'ai besoin de déboguer certaines tuiles, par exemple où il y a une collision et où le joueur vise. J'ai créé une classe de débogueur qui dessine un maillage carré à une position en utilisant une couleur.

public class GridDebugger : MonoBehaviour {

    [SerializeField] private float alpha;

    private Mesh mesh;
    private Material mat;

    void Start() {
        mat = new Material(Shader.Find("Sprites/Default"));
        mesh = new Mesh();
        mesh.vertices = new Vector3[] { new Vector3(.5f, .5f, 0), new Vector3(.5f, -.5f), new Vector3(-.5f, -.5f), new Vector3(-.5f, .5f) };
        mesh.triangles = new int[] { 0, 1, 2, 2, 3, 0 };
    }

    public void Debug(Vector3 position, Color color) {
        color.a = alpha;
        mat.color = color;
        Graphics.DrawMesh(mesh, position, Quaternion.identity, mat, 0);
    }
}

Actuellement, la classe a deux utilisateurs :

[RequireComponent(typeof(GridDebugger))]
public class CollisionSystem : GridSystem {
    private List<Node>[,] grid;
    private GridDebugger debugger;

    void Awake() {
        debugger = GetComponent<GridDebugger>();
    }

    //Logic....

    void Update() {
        if (grid != null) {
            for (int x = 0; x < grid.GetLength(0); x++) {
                for (int y = 0; y < grid.GetLength(1); y++) {
                    if (grid[x, y] != null) {
                        for (int i = 0; i < grid[x, y].Count; i++) {
                            if (grid[x,y][i].Parent.Debug) {
                                Vector3 worldPos = GridToWorldPos(new Vector2Int(x, y), grid.GetLength(0), grid.GetLength(1));
                                worldPos.z = -0.0001f;
                                debugger.Debug(worldPos, Color.Red);
                            }
                        }
                    }
                }
            }
        }
    }     
}

Et

public class GridMeleeWeapon : MonoBehaviour {
    private GridDebugger debugger;

    void Awake() {
        debugger = FindObjectOfType<GridDebugger>();
    }    

    public void Aim(Vector2 dir) {
        Vector3 position = transform.position + dir;
        debugger.Debug(position, Color.blue);                 
    }
}

Dans CollisionSystem, je boucle chaque collisionneur et dessine un carré rouge à chaque position. Dans GridMeleeWeapon, je dessine juste un carré bleu où le joueur vise.

Le problème est que chaque carré est dessiné avec la couleur utilisée dans CollisionSystem, c'est-à-dire le rouge. Lorsque vous dessinez les carrés bleus dans GridMeleeWeapon, ils deviennent rouges. Si je supprime debugger.Debug(worldPos, Color.Red) dans CollisionSystem, les carrés que je dessine à partir de GridMeleeWeapon s'affichent en bleu.

Avec le code actuel, je n'arrive pas à dessiner des maillages de différentes couleurs. Ce que je pense, c'est que la couleur spécifiée par le premier appelant est utilisée pour les appels consécutifs, même si la couleur du matériel est modifiée, mais pourquoi je n'en ai aucune idée.

Comment régler correctement la couleur ?

2
Tagor 23 sept. 2018 à 04:17

1 réponse

Meilleure réponse

Le matériau dans Unity 3D est un type de référence.

Votre code dans GridMeleeWeapon et CollisionSystem utilise la même instance de GridDebugger et le même matériel. Ce qui se passe, c'est que puisque vous changez la couleur du matériau OnUpdate(), la couleur passera du bleu au rouge instantanément (à chaque image) sur chaque objet utilisant ce matériau.

Au lieu de passer une couleur à votre méthode debugger().Debug(), passez un matériau avec une couleur différente. Par exemple, créez un matériau de couleur rouge et un autre de couleur bleue. Utilisez ces matériaux pour définir la couleur.

0
Dave 23 sept. 2018 à 15:11