Unità: come applicare le modifiche programmatiche al prototipo Terrain Splat?


8

Ho una sceneggiatura a cui aggiungo un oggetto Terreno (trascino il terreno nel campo Terreno pubblico).

Il terreno è già configurato in Unity per avere 2 PaintTextures: 1 è un quadrato (impostato con una dimensione delle tessere in modo che formi un motivo a scacchi) e il secondo è un'immagine di erba:

Screenshot di Unity

Inoltre, la forza target del primo PaintTexture viene abbassata in modo tale che il motivo a scacchi riveli anche parte dell'erba sottostante.

Ora voglio, in fase di esecuzione, modificare la dimensione delle tessere del primo PaintTexture, ovvero avere più o meno pedine a seconda delle varie condizioni del tempo di esecuzione. Ho esaminato la documentazione di Unity e ho visto che hai l' Terrain.terrainData.SplatPrototypearray che ti consente di cambiarlo. Inoltre c'è un RefreshPrototypes()metodo terrainDatasull'oggetto e un Flush()metodo Terrainsull'oggetto. Quindi ho realizzato una sceneggiatura come questa:

public class AStarTerrain : MonoBehaviour {

    public int aStarCellColumns, aStarCellRows; 

    public GameObject aStarCellHighlightPrefab;
    public GameObject aStarPathMarkerPrefab;
    public GameObject utilityRobotPrefab;
    public Terrain aStarTerrain;

    void Start () {
            //I've also tried NOT drag and dropping the Terrain on the public field 
            //and instead just using the commented line below, but I get the same results
        //aStarTerrain = this.GetComponents<Terrain>()[0];
        Debug.Log ("Got terrain "+aStarTerrain.name);

        SplatPrototype[] splatPrototypes = aStarTerrain.terrainData.splatPrototypes;
        Debug.Log("Terrain has "+splatPrototypes.Length+" splat prototypes");
        SplatPrototype aStarCellSplat = splatPrototypes[0];
        Debug.Log("Re-tyling splat prototype "+aStarCellSplat.texture.name);
        aStarCellSplat.tileSize = new Vector2(2000,2000);
        Debug.Log("Tyling is now "+aStarCellSplat.tileSize.x+"/"+aStarCellSplat.tileSize.y);
        aStarTerrain.terrainData.RefreshPrototypes();
        aStarTerrain.Flush();
    }

//...

Il problema è che non viene modificato nulla, la mappa del checker non viene ricostruita. Gli output della console mi dicono correttamente che ho l'oggetto Terrain con il nome giusto, che ha il giusto numero di prototipi splat e che sto modificando il tileSize sull'oggetto SplatPrototype corrispondente alla trama giusta. Mi dice anche che il valore è cambiato. Nulla viene aggiornato nella vista grafica effettiva.

Quindi per favore, cosa mi sto perdendo?


se hai uno shader personalizzato e vuoi creare una griglia di linee blu sulla mappa con valori diversi, il modo più economico è farlo nello shader ... le linee blu sono: round (frac (x * .1) ... diamine, mettilo in una risposta
com.prehensible,

Risposte:


1

Sembra che ti sia dimenticato di riassegnare la texture Splat:

public class AStarTerrain : MonoBehaviour {

public int aStarCellColumns, aStarCellRows; 

public GameObject aStarCellHighlightPrefab;
public GameObject aStarPathMarkerPrefab;
public GameObject utilityRobotPrefab;
public Terrain aStarTerrain;

void Start () {
        //I've also tried NOT drag and dropping the Terrain on the public field 
        //and instead just using the commented line below, but I get the same results
    //aStarTerrain = this.GetComponents<Terrain>()[0];
    Debug.Log ("Got terrain "+aStarTerrain.name);

    SplatPrototype[] splatPrototypes = aStarTerrain.terrainData.splatPrototypes;
    Debug.Log("Terrain has "+splatPrototypes.Length+" splat prototypes");
    SplatPrototype aStarCellSplat = splatPrototypes[0];
    Debug.Log("Re-tyling splat prototype "+aStarCellSplat.texture.name);
    aStarCellSplat.tileSize = new Vector2(2000,2000);
    splatPrototypes[0] = aStarCellSplat; // <- here
    Debug.Log("Tyling is now "+aStarCellSplat.tileSize.x+"/"+aStarCellSplat.tileSize.y);
    aStarTerrain.terrainData.RefreshPrototypes();
    aStarTerrain.Flush();
}

//...

Che a proposito avresti potuto fare così:

splatPrototypes[0].tileSize = new Vector2(2000,2000); //No referencing issue this way

(E poi aggiorna ma non sono nemmeno sicuro che sia necessario in questo stato)

MODIFICARE :

Ci sono alcuni parametri negli oggetti a cui non si può fare riferimento e credo

splatPrototype.tileSize

è uno di questi, quindi se lo fai:

SplatPrototype aStarCellSplat = splatPrototypes[0];

quindi aStarCellSplat è un clone di splatPrototypes [0] ma non fa riferimento a esso. a volte la clonazione per ottenere il valore iniziale e iterare da esso è buona soprattutto quando si modifica la struttura complessa, ma in questo caso una semplice chiamata di parametro è più semplice.

E tieni traccia dei tuoi cloni, se cloni non dimenticare di assegnare nuovamente


-1

per creare linee blu tramite shader, devi avere texture_uv nella funzione di superficie o nella funzione di frattura ...

per creare linee griglia blu / grigie in shaderlab, devi aggiungere un totale di 4-5 linee allo shader, all'interno della funzione surf:

xline = ceil (frac (uv.x * .1) -. 75); yline = uguale per y

griglia = max (xline, yline);

o.albedo.blueval = grid.

quindi puoi cambiare la dimensione della tua griglia usando 1 chiamata allo shader, per cambiare il valore dello shader, .l crea una griglia di 10 metri, cambia quel valore per regolare la dimensione della griglia, .75 crea una griglia 3/4 dell'area dello schermo .

quindi modificare il colore aggiungendo la matematica allo stesso che è stato utilizzato nella versione precedente / splatmap.


Pur fornendo alcune informazioni utili, ciò non risponde effettivamente alla domanda posta direttamente. Se l'OP volesse davvero sapere come fare tramite lo shader, avrebbe chiesto.
Pip
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.