[Clos - Tirage au sort à venir] #12 : Concours du déconfinement mai 2020 !!!

Des concours et des cadeaux pour les utilisateurs d'Unity 3D France :-)
Avatar de l’utilisateur
E3DStef
Administrateur
Administrateur
Messages : 1646
Inscription : 14 Juil 2013 18:30
Localisation : https://www.carte-des-membres.com/fr/Unity3D-France/

[Clos - Tirage au sort à venir] #12 : Concours du déconfinement mai 2020 !!!

Message par E3DStef » 12 Mai 2020 16:31

Bonjour à tous !

12e concours !

Je vais essayer de relancer ces concours que j'avais initié il y a déjà 5 ans ^^

Mon espoir (totalement utopique) était d'en faire un par mois mais cela est bien trop chronophage ^^, donc restons raisonnables et relançons ces concours humblement au rythme de 1 à 2 par an (printemps hiver).

Ce concours est lancé à l'occasion de la sortie d'une 3e édition du livre du livre d'Anthony Cardinale "Créez des jeux de A à Z avec Unity" dans la version 2020 ! L'éditeur les éditions D-BookeR représenté par Patricia MONCORGE ont bien voulu jouer le jeu et nous offrir plusieurs lots pour ce concours, merci !!!

Date de début du concours : Dès maintenant - Date de fin du concours : 03 Juin minuit

Participation : gratuite


Comment participer ? :

Principe de tombola, chaque participant ayant au moins UN numéro peut gagner un des lots mis en jeu

Pour avoir des numéros c'est facile !

Répondre aux questions "superduredeouf" ! :

Chaque bonne réponse (à m'envoyer par MP) aux questions ci-dessous = 1 numéro

Quel éditeur propose le livre "Créer des jeux de A & Z sur Unity" ?
> Pour la réponse donnez-moi le lien URL de l'éditeur

Quel autre livre récemment proposé par cette maison d'édition parle d'un autre moteur de jeu ?
> Pour la réponse donnez-moi le lien URL du livre en question

Citez l'auteur du livre qui sort le 04 Juin 2020 en librairie (et qui > nous concerne) ?
> Pour la réponse indiquer Prénom NOM et le lien vers son site web

Poster ci après (en réponse à ce sujet donc) :

Un élément graphique ou un script que vous avez réalisé (dont vous êtes l'auteur !) avec Unity3d
(Un de chaque maxi par personne)

Chaque élément posté et validé par les modos/admin = 1 numéro
Chaque élément posté avec quelques explications et validé par les modos/admin = 2 numéros
Chaque élément posté avec son tuto pour reproduire et validé par les modos/admin = 5 numéros

Communiquer sur les réseaux sociaux ci après (en réponse à ce sujet donc) :

Chaque post sur un réseau social (FB, Tw, Lk) = 1 numéro par réseau social
> Une capture écran posté ici = 1 numéro

Vous avez la capacité de participer selon vos envies !

Exemple :
Toto réponds juste à toutes les questions (par MP à l'admin qui valide les bonnes réponses)
Toto a gagné 3 numéros (total actuel = 3 numéros)
Toto a posté une réalisation 3d avec son tuto (validé par les modos/admin)
Toto a gagné 5 numéros (total actuel = 8 numéros)
Toto a posté un script C# de magnétisme d'objet avec son tuto (validé par les modos/admin)
Toto a gagné 5 numéros (total actuel = 13 numéros)
Toto a posté un screen de son post sur Facebook (et uniquement Fb car toto il n'aime pas Twitter et Linkedin)
Toto a gagné 1 numéro (total actuel = 14 numéros)

Du coup Toto a 14 chances d'avoir un des lots ^^

Bref participer un maximum vous offre un maximum de chance de gagner les lots !

Cadeaux :
Des livres à gagner :

1er prix : Livre imprimé "Créez des jeux de A à 2 avec Unity 2020" dédicacé par son auteur !
2e prix : Livre format numérique "Créez des jeux de A à 2 avec Unity 2020" en version PDF ou ePub (au choix)
3e prix : La partie I ou la partie II de ce livre (I. Votre premier jeu mobile ou II. un FPS 3D pour PC) en version PDF ou ePub (au choix)

Une licence logicielle à gagner :
4" prix : Une licence PLAYMAKER offerte par Bouiss (membre très présent sur le Discord)

Pour ceux qui ont raté ma preview sur ce livre c'est ici

Modalité d'attribution :
Avoir au moins UN numéro pour pouvoir participer au tirage au sort.

Le tirage au sort aura lieu en direct sur la chaine Twitch d'Unity3DFrance.
Je vous donnerai le lien ici une fois la date calée.

> Twitter : "unity3d_france"
>
FaceBook : "Unity France" ou "franceunity3d@gmail.com"
>
Google + : "Unity France"
> GitLab : "Unity3D-France"


Si vous avez des questions posez-les moi par MP svp

A+ et bonne chance à tous !

Stef
Le Savoir n'est Précieux que s'il est Partagé

Si besoin urgent de me contacter, faites moi un mail sur : franceunity3d@gmail.com

EmileF
Messages : 673
Inscription : 18 Mars 2017 19:39

Re: #12 : Concours du déconfinement mai 2020 !!!

Message par EmileF » 13 Mai 2020 20:55

Bonjour,

En réponse au concours #12 voici:
un script que j'ai réalisé pour faciliter quelques actions qu'on peut apporter à un gameObject.
Ce script peut aider les débutants et d'autres aussi, pour appliquer à un gameobject des
mouvements, déplacement, rotation, mise à l'échelle,
des changements de couleur, des apparitions ou des disparitions,
et même exécuter d'autres actions,
avec une gestion du temps d'exécution et du délai avant l'exécution.

La mise en place est très simple:
  • Dans un dossier "Editor" mettre le script "ActiviteEditor"
    Dans un empty ou tout autre objet, lui attribuer le script "Activite"
    Il suffit dans le script "Activite" de préciser, dans l'inspector,
    le type de mouvement,
    l'objet cible auquel ces actions vont être attribuées
    et ensuite, selon le cas, les valeurs cibles, pour le déplacement ou la rotation, ou la couleur... (C'est "ActiviteEditor" qui gère ces valeurs demandées)
    Pour l'appel à la fonction, il suffit de marquer le nom de la fonction(attention à la casse) qui doit être située dans un script composant de l'objet cible
    Et enfin appeler à partir d'un autre script la fonction publique "Execute()" dans le script "Activite" pour exécuter l'action.
Voilà les scripts:
Le script principal:

Code : Tout sélectionner

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class Activite : MonoBehaviour
{
    //La liste des opérations possibles
    public enum TypeActe
    {
        localMove,
        LocalMoveAdd,
        Move,
        MoveAdd,
        LocalTurn,
        LocalTurnAdd,
        Turn,
        TurnAdd,
        Scale,
        ScaleAdd,
        Color,
        FadeOn,
        FadeOff,
        AppelleFonction,
        ActiveObjet,
        DesactiveObjet,
        ActiveCollider,
        DesactiveCollider,
        Visible,
        Invisible,
    }

    //Les valeurs attendues pour l'exécution des actions
    //Le type de l'action
    public TypeActe Type;
    //L'objet ciblé par l'action
    public GameObject Objet;
    //La valeur finale ou à ajouter pour les mouvements
    public Vector3 Valeur;
    //La couleur finale pour l'action color
    public Color Color;
    //le nom de la fonction à appeler dans un script de l'objet
    public string Fonction;
    //la duree de l'action pour les mouvements
    public float Duree;
    //le délai avant l'exécution de l'action
    public float Delai;
    //Ceci à servi pour les test n'est plus utile maintenant/t
    //public bool Go;

    //private void Update()
    //{
    //    if(Go)
    //    {
    //        Execute();
    //        Go = false;
    //    }
    //}

    /// <summary>
    /// La fonction à appeler pour exécuter l'action 
    /// </summary>
    public void Execute()
   {
        switch (Type)
        {
            case TypeActe.localMove:
                StartCoroutine(Move(Objet, Valeur, Duree, Delai, true, false));
                break;
            case TypeActe.LocalMoveAdd:
                StartCoroutine(Move(Objet, Valeur, Duree, Delai, true, true));
                break;
            case TypeActe.Move:
                StartCoroutine(Move(Objet, Valeur, Duree, Delai, false, false));
                break;
            case TypeActe.MoveAdd:
                StartCoroutine(Move(Objet, Valeur, Duree, Delai, false, true));
                break;
            case TypeActe.LocalTurn:
                StartCoroutine(Turn(Objet, Valeur, Duree, Delai, true, false));
                break;
            case TypeActe.LocalTurnAdd:
                StartCoroutine(Turn(Objet, Valeur, Duree, Delai, true, true));
                break;
            case TypeActe.Turn:
                StartCoroutine(Turn(Objet, Valeur, Duree, Delai, false, false));
                break;
            case TypeActe.TurnAdd:
                StartCoroutine(Turn(Objet, Valeur, Duree, Delai, false, true));
                break;
            case TypeActe.Scale:
                StartCoroutine(Scale(Objet, Valeur, Duree, Delai, false));
                break;
            case TypeActe.ScaleAdd:
                StartCoroutine(Scale(Objet, Valeur, Duree, Delai, true));
                break;
            case TypeActe.Color:
                StartCoroutine(Colore(Objet, Color, Duree, Delai));
                break;
            case TypeActe.FadeOn:
                StartCoroutine(Fade(Objet, Duree, Delai, true));
                break;
            case TypeActe.FadeOff:
                StartCoroutine(Fade(Objet, Duree, Delai, false));
                break;
            case TypeActe.AppelleFonction:
                StartCoroutine(Call(Objet, Fonction, Delai));
                break;
            case TypeActe.ActiveObjet:
                StartCoroutine(Active(Objet, Delai, true));
                break;
            case TypeActe.DesactiveObjet:
                StartCoroutine(Active(Objet, Delai, false));
                break;
            case TypeActe.ActiveCollider:
                StartCoroutine(Collider(Objet, Delai, true));
                break;
            case TypeActe.DesactiveCollider:
                StartCoroutine(Collider(Objet, Delai, false));
                break;
            case TypeActe.Visible:
                StartCoroutine(Visible(Objet, Delai, true));
                break;
            case TypeActe.Invisible:
                StartCoroutine(Visible(Objet, Delai, false));
                break;
            default:
                break;
        }
    }

    //pour rendre visible ou invisible l'affichage un objet sans le désactiver
    private IEnumerator Visible(GameObject objet, float delai, bool v)
    {
        yield return new WaitForSeconds(delai);
        SetVisible(objet, v);
    }
    private void SetVisible(GameObject objet, bool v)
    {
        if (objet.GetComponent<Renderer>())
            objet.GetComponent<Renderer>().enabled = v;
        else if (objet.GetComponent<TextMesh>())
        {
            Color color = objet.GetComponent<TextMesh>().color;
            objet.GetComponent<TextMesh>().color = new Color(color.r, color.g, color.b, v ? 1 : 0);
        }
        else if (objet.GetComponent<Text>())
            objet.GetComponent<Text>().enabled = v;
        else if (objet.GetComponent<Image>())
            objet.GetComponent<Image>().enabled = v;
        else if (objet.GetComponent<Light>())
            objet.GetComponent<Light>().enabled = v;
        else if (objet.GetComponent<Camera>())
            objet.GetComponent<Camera>().enabled = v;
    }

    //pour activer ou désactiver le collider de l'objet
    private IEnumerator Collider(GameObject objet, float delai, bool v)
    {
        yield return new WaitForSeconds(delai);
        if (objet.GetComponent<Collider>())
            objet.GetComponent<Collider>().enabled = v;
    }

    //pour activer ou désactiver le gameObject
    private IEnumerator Active(GameObject objet, float delai, bool v)
    {
        yield return new WaitForSeconds(delai);
        objet.SetActive(v);
    }

    //Pour gérer les déplacements
    private IEnumerator Move(GameObject objet, Vector3 value, float duree, float delai, bool local, bool add)
    {
        yield return new WaitForSeconds(delai);
        float elapsedTime = 0;
        Vector3 startingPos = local ? objet.transform.localPosition : objet.transform.position;
        Vector3 end = value;
        if (add)
            end += startingPos;
        while (elapsedTime < duree)
        {
            if (local)
                objet.transform.localPosition = Vector3.Lerp(startingPos, end, (elapsedTime / duree));
            else
                objet.transform.position = Vector3.Lerp(startingPos, end, (elapsedTime / duree));
            elapsedTime += Time.deltaTime;
            yield return new WaitForEndOfFrame();
        }
        if (local)
            objet.transform.localPosition = end;
        else
            objet.transform.position = end;
    }

    //Pour gérer les rotations
    private IEnumerator Turn(GameObject objet, Vector3 value, float duree, float delai, bool local, bool add)
    {
        yield return new WaitForSeconds(delai);
        float elapsedTime = 0;
        Vector3 startingRot = local ? objet.transform.localEulerAngles : objet.transform.eulerAngles;
        Vector3 end = value;
        if (add)
            end += startingRot;
        while (elapsedTime < duree)
        {
            if (local)
                objet.transform.localEulerAngles = Vector3.Lerp(startingRot, end, (elapsedTime / duree));
            else
                objet.transform.eulerAngles = Vector3.Lerp(startingRot, end, (elapsedTime / duree));
            elapsedTime += Time.deltaTime;
            yield return new WaitForEndOfFrame();
        }
        if (local)
            objet.transform.localEulerAngles = end;
        else
            objet.transform.eulerAngles = end;
    }

    //Pour gérer la taille 
    private IEnumerator Scale(GameObject objet, Vector3 value, float duree, float delai, bool add)
    {
        yield return new WaitForSeconds(delai);
        float elapsedTime = 0;
        Vector3 startingScale = objet.transform.localScale;
        Vector3 end = value;
        if (add)
            end += startingScale;
        while (elapsedTime < duree)
        {
            objet.transform.localScale = Vector3.Lerp(startingScale, end, (elapsedTime / duree));
            elapsedTime += Time.deltaTime;
            yield return new WaitForEndOfFrame();
        }
        objet.transform.localScale = end;
    }

    //pour gérer le fondu (attention le matérial utilisé pour les renderer doivent avoir un shader transparent.
    private IEnumerator Fade(GameObject objet, float duree, float delai, bool on)
    {
        Debug.Log("Fade");
        yield return new WaitForSeconds(delai);
        float elapsedTime = 0;
        Color startingColor = GetColor(objet);
        Color cible = startingColor;
        Color end = new Color(startingColor.r,startingColor.g,startingColor.g, on ? 1f : 0f);
        Debug.Log(end);
        while (elapsedTime < duree)
        {
            SetColor(objet, Color.Lerp(startingColor, end, (elapsedTime / duree)));
            elapsedTime += Time.deltaTime;
            yield return new WaitForEndOfFrame();
        }
        SetColor(objet, end);
    }
    
    //Pour gérer la couleur
    private IEnumerator Colore(GameObject objet, Color value, float duree, float delai)
    {
        yield return new WaitForSeconds(delai);
        float elapsedTime = 0;
        Color startingColor = GetColor(objet);
        Color cible = startingColor;
        Color end = value;
        while (elapsedTime < duree)
        {
            SetColor(objet, Color.Lerp(startingColor, end, (elapsedTime / duree)));
            elapsedTime += Time.deltaTime;
            yield return new WaitForEndOfFrame();
        }
        SetColor(objet, end);
    }
    private Color GetColor(GameObject objet)
    {
        Color getcolor = new Color();
        if (objet.GetComponent<Renderer>())
            getcolor = objet.GetComponent<Renderer>().material.color;
        else if (objet.GetComponent<TextMesh>())
            getcolor = objet.GetComponent<TextMesh>().color;
        else if (objet.GetComponent<Text>())
            getcolor = objet.GetComponent<TextMesh>().color;
        else if (objet.GetComponent<Image>())
            getcolor = objet.GetComponent<Image>().color;
        else if (objet.GetComponent<Light>())
            getcolor = objet.GetComponent<Light>().color;
        else if (objet.GetComponent<Camera>())
            getcolor = objet.GetComponent<Camera>().backgroundColor;
        return getcolor;
    }
    private void SetColor(GameObject objet, Color color)
    {
        if (objet.GetComponent<Renderer>())
            objet.GetComponent<Renderer>().material.color = color;
        else if (objet.GetComponent<TextMesh>())
            objet.GetComponent<TextMesh>().color = color;
        else if (objet.GetComponent<Text>())
            objet.GetComponent<TextMesh>().color = color;
        else if (objet.GetComponent<Image>())
            objet.GetComponent<Image>().color = color;
        else if (objet.GetComponent<Light>())
            objet.GetComponent<Light>().color = color;
        else if (objet.GetComponent<Camera>())
            objet.GetComponent<Camera>().backgroundColor = color;
    }

    //pour appeler une fonction dans un script component de l'objet
    private IEnumerator Call(GameObject objet, string fonction, float delai)
    {
        yield return new WaitForSeconds(delai);
        objet.SendMessage(fonction);
    }

}
L'Editor pour faciliter son usage dans l'inspector. Il n'est pas indispensable mais bien utile

Code : Tout sélectionner

using UnityEditor;

[CustomEditor(typeof(Activite))]
public class ActiviteEditor : Editor
{

    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        SerializedProperty type = serializedObject.FindProperty("Type");
        SerializedProperty objet = serializedObject.FindProperty("Objet");
        SerializedProperty valeur = serializedObject.FindProperty("Valeur");
        SerializedProperty color = serializedObject.FindProperty("Color");
        SerializedProperty fonction = serializedObject.FindProperty("Fonction");
        SerializedProperty duree = serializedObject.FindProperty("Duree");
        SerializedProperty delai = serializedObject.FindProperty("Delai");

        EditorGUILayout.PropertyField(type);
        int v = type.enumValueIndex;

        if (v < 10) // move, turn, scale
        {
            EditorGUILayout.PropertyField(objet);
            EditorGUILayout.PropertyField(valeur);
            EditorGUILayout.PropertyField(duree);
            EditorGUILayout.PropertyField(delai);
        }
        else if (v == 10) // color
        {
            EditorGUILayout.PropertyField(objet);
            EditorGUILayout.PropertyField(color);
            EditorGUILayout.PropertyField(duree);
            EditorGUILayout.PropertyField(delai);
        }
        else if (v < 13) // fade
        {
            EditorGUILayout.PropertyField(objet);
            EditorGUILayout.PropertyField(duree);
            EditorGUILayout.PropertyField(delai);
        }
        else if (v == 13) // fonction
        {
            EditorGUILayout.PropertyField(objet);
            EditorGUILayout.PropertyField(fonction);
            EditorGUILayout.PropertyField(delai);
        }
        else //les autres actions
        {
            EditorGUILayout.PropertyField(objet);
            EditorGUILayout.PropertyField(delai);
        }
        serializedObject.ApplyModifiedProperties();

    }
}

J'espère que ce petit script va pouvoir être utile à beaucoup
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Avatar de l’utilisateur
E3DStef
Administrateur
Administrateur
Messages : 1646
Inscription : 14 Juil 2013 18:30
Localisation : https://www.carte-des-membres.com/fr/Unity3D-France/

Re: [Clos - Tirage au sort à venir] #12 : Concours du déconfinement mai 2020 !!!

Message par E3DStef » 16 Juin 2020 23:07

UP

Bon le tirage au sort est mis en pause car j'attends djulio74 post ici les liens vers son script et son shader

Une fois ceci fait je procéderai au tirage au sort en DIRECT SUR TWWWWWITCHHH ^^

A+

Stef
Le Savoir n'est Précieux que s'il est Partagé

Si besoin urgent de me contacter, faites moi un mail sur : franceunity3d@gmail.com

djulio74
Messages : 682
Inscription : 19 Déc 2009 22:55

Re: [Clos - Tirage au sort à venir] #12 : Concours du déconfinement mai 2020 !!!

Message par djulio74 » 17 Juin 2020 19:55

Salut a tous.
En effet je pensais avoir raté le délai et avais lâché l'affaire ^^

Je pense faire deux partages si j'y arrive.
D'abord un tout simple qui permet de mixer plusieurs textures sur un mesh en utilisant un seul shader donc avec un seul matérial.
Le principe utilise les vertexColor d'un mesh.
En effet, après pas mal de recherche, je ne trouvait que des solution pour ne mixer que 3 voir 4 teture ensemble en utilisant les vertex color. Ce qui correspondait à une texture par composant de la couleur ( r, g, b et a). J'avais besoin de plus, et me suis mis a faire ce petit shader qui permet de mxer jusqu'à 11 texture toujours en utilisant uniquement la couleur des vertex.

Bien que cela se place dans la catégorie "graphique" du concours, je vais aussi ajouter un mini-script permettant d'assigner ces vertex color à un mesh pour pouvoir le tester.

Le script en question est à mettre sur un GameObject comportant donc un MeshFilter :

Code : Tout sélectionner

using UnityEngine;

public class RandomVertexColor : MonoBehaviour
{

	// liste des couleurs utilisable pour les vertex color
	private Color[] couleurs = new Color[11] {
		new Color (1, 0, 0, 0),
		new Color (0, 1, 0, 0),
		new Color (0, 0, 1, 0),
		new Color (0, 0, 0, 1),
		new Color (1, 1, 0, 0),
		new Color (0, 1, 1, 0),
		new Color (0, 0, 1, 1),
		new Color (1, 0, 0, 1),
		new Color (0, 0, 0, 0),
		new Color (0, 1, 0, 1),
		new Color (1, 0, 1, 0),
	};

	Mesh mesh;
	Color32[] Vcolor;
	int couleur = 0;

	void Start()
    {		
		// recuperation du mesh et création d'un array de Color32 pour chacun de vertex présent dans le mesh
		// et on les assigne (les mesh de base de Unity n'ont pas de vertex color atribués)
		mesh = GetComponent<MeshFilter>().mesh;
		Vcolor = new Color32[mesh.vertices.Length];
		AssignColor();
	}

    void Update()
    {
		// Avec le touche A du clavier, on assigne la meme couleur a tout les vertex, en faisant
		// defiler a chaque appui parmis les couleurs dispo
        if (Input.GetKeyDown(KeyCode.A))
		{
			couleur = (int)Mathf.Repeat(couleur + 1, couleurs.Length);
			AssignColor();
		}

		// Avec la touche R du clavier, on assigne de façon aléatoire une couleur aux vertex
		if (Input.GetKeyDown(KeyCode.R))
		{
			RandomColor();
		}
	}	
	void AssignColor()
	{		
		for ( int i = 0; i < Vcolor.Length; i++)
		{
			Vcolor[i] = couleurs[couleur];
		}
		mesh.colors32 = Vcolor;
	}
	void RandomColor()
	{
		for (int i = 0; i < Vcolor.Length; i++)
		{
			couleur = (int) Random.Range(0, couleurs.Length - 1);
			Vcolor[i] = couleurs[couleur];
		}
		mesh.colors32 = Vcolor;
	}
}
Le principe est simple, en appuyant sur la touche A du clavier, on assigne la même couleur a tous les vertex du mesh en faisant défiler parmis les couleurs disponible. Avec le touche R, on assigne de manière aléatoire une couleurs a chacun des vertex.
Une couleur est composé des 4 variables (r g b a), le principe est d'avoir des couleurs différentes en utilisant uniquement des valeurs de 0 ou 1 pour chacun des composant. on utilise donc ces couleurs :

Code : Tout sélectionner

new Color (1, 0, 0, 0),
		new Color (0, 1, 0, 0),
		new Color (0, 0, 1, 0),
		new Color (0, 0, 0, 1),
		new Color (1, 1, 0, 0),
		new Color (0, 1, 1, 0),
		new Color (0, 0, 1, 1),
		new Color (1, 0, 0, 1),
		new Color (0, 0, 0, 0),
		new Color (0, 1, 0, 1),
		new Color (1, 0, 1, 0),
		
On peut donc mixer 11 textures avec un seul material.
Ces couleurs ne sont pas toutes celles dispos avec soit 1 ou 0 comme valeurs pour chacun des composant, mais apres avoir fait des tests et un tableau, ce sont les seuls utilisables pour pouvoir s'en servir pour que chacune corresponde a une seul texture (sans utiliser de if a gogo ^^)

bien sur, juste ce script n'aura pas d'effet sur le visuel de votre mesh, il faut un shader qui s'occupe de "décoder" ces combinaisons de couleur :

Pour utiliser ces couleurs pour afficher des textures différentes, c'est dans un shader que ça se passe.
Dans ce shader, la couleur de chaque vertex est récupérée et un calcul est fait pour savoir quelle texture appliquer.
Le shader en question est celui la :

Code : Tout sélectionner

Shader "MAP/Mix texture" {
	Properties{
		_MainTex1("Texture 1", 2D) = "white" {}
		_MainTex2("Texture 2", 2D) = "white" {}
		_MainTex3("Texture 3", 2D) = "white" {}
		_MainTex4("Texture 4", 2D) = "white" {}
		_MainTex5("Texture 5", 2D) = "white" {}
		_MainTex6("Texture 6", 2D) = "white" {}
		_MainTex7("Texture 7", 2D) = "white" {}
		_MainTex8("Texture 8", 2D) = "white" {}
		_MainTex9("Texture 9", 2D) = "white" {}
		_MainTex10("Texture 10", 2D) = "white" {}
		_MainTex11("Texture 11", 2D) = "white" {}

	}
		SubShader{
			Tags { "RenderType" = "Opaque" }
			LOD 300

			CGPROGRAM
			#pragma surface surf Standard fullforwardshadows vertex:vert
			#pragma target 5.0

			sampler2D _MainTex1;
			sampler2D _MainTex2;
			sampler2D _MainTex3;
			sampler2D _MainTex4;
			sampler2D _MainTex5;
			sampler2D _MainTex6;
			sampler2D _MainTex7;
			sampler2D _MainTex8;
			sampler2D _MainTex9;
			sampler2D _MainTex10;
			sampler2D _MainTex11;

			struct Input {
			  float2 uv_MainTex1;
			  half4 COL;
			  half4 COL1;
			  half4 COL2;
			  half4 COL3;
			  half4 couleur;
		  };

			 void vert(inout appdata_full v, out Input o) {
			  UNITY_INITIALIZE_OUTPUT(Input,o);

			  o.COL.r = max(v.color.r - v.color.b * v.color.b - v.color.g * v.color.g - v.color.a * v.color.a ,0.0);
			  o.COL.g = max(v.color.g - v.color.r * v.color.r - v.color.b * v.color.b - v.color.a * v.color.a, 0.0);
			  o.COL.b = max(v.color.b - v.color.r * v.color.r - v.color.g * v.color.g - v.color.a * v.color.a, 0.0);
			  o.COL.a = max(v.color.a - v.color.r * v.color.r - v.color.g * v.color.g - v.color.b * v.color.b ,0.0);
			  o.COL1.r = v.color.r * v.color.g;
			  o.COL1.g = v.color.g * v.color.b;
			  o.COL1.b = v.color.b * v.color.a;
			  o.COL1.a = v.color.r * v.color.a;
			  o.COL2.r = max(1.0 - v.color.r * v.color.r - v.color.b * v.color.b - v.color.g * v.color.g - v.color.a * v.color.a ,0.0);
			  o.COL2.g = v.color.g * v.color.a;
			  o.COL2.b = v.color.r * v.color.b;
			  o.couleur = v.color;
		  }



			void surf(Input IN, inout SurfaceOutputStandard o) {

			half3 Col1 = (IN.COL.r) * (tex2D(_MainTex1, IN.uv_MainTex1).rgb);
			half3 Col2 = (IN.COL.g) * (tex2D(_MainTex2, IN.uv_MainTex1).rgb);
			half3 Col3 = (IN.COL.b) * (tex2D(_MainTex3, IN.uv_MainTex1).rgb);
			half3 Col4 = (IN.COL.a) * (tex2D(_MainTex4, IN.uv_MainTex1).rgb);
			half3 Col5 = (IN.COL1.r) * (tex2D(_MainTex5, IN.uv_MainTex1).rgb);
			half3 Col6 = (IN.COL1.g) * (tex2D(_MainTex6, IN.uv_MainTex1).rgb);
			half3 Col7 = (IN.COL1.b) * (tex2D(_MainTex7, IN.uv_MainTex1).rgb);
			half3 Col8 = (IN.COL1.a) * (tex2D(_MainTex8, IN.uv_MainTex1).rgb);
			half3 Col9 = (IN.COL2.r) * (tex2D(_MainTex9, IN.uv_MainTex1).rgb);
			half3 Col10 = (IN.COL2.g) * (tex2D(_MainTex10, IN.uv_MainTex1).rgb);
			half3 Col11 = (IN.COL2.b) * (tex2D(_MainTex11, IN.uv_MainTex1).rgb);

			// pour afficher les textures : //
				o.Albedo = (Col1 + Col2 + Col3 + Col4 + Col5 + Col6 + Col7 + Col8 + Col9 + Col10 + Col11) ;
			// pour afficher les Vertex  Color : //
				//o.Albedo = IN.couleur;

			}
			ENDCG
	}
	FallBack "Diffuse"
}
Il faut donc s'en servir dans un nouveau material, à appliquer à notre Gameobjet sur lequel on a mis le ptit script qui assigne les vertex colors.

Je ne vais pas rentrer dans les détails des shader (faudrait je fasse un petit tuto a l'ocaz) mais le principe est le suivant :
- j'ai trois nouvelles couleurs (COL , COL1 et COL2) dans le shader, uniquement pour passer du vertex au surface shader
- Cela donne (avec 4 composant pour une couleur) la possibilité de stocker 12 variable mais que 11 sont utilisée, une pour chaque textures.
- Avec une couleur donnée d'un vertex, parmi ces 11 variables (COL.r, COL.g ... etc ), une seule est attribué à 1 et les autres a 0. dans tout les cas on a 10 x 0 et 1 x 1.
- dans la partis surface, je récupère ces variables qui sont donc toujours 10 fois égale a 0 et une seule fois a 1, pour les multiplier a sa texture correspondant. cette fois on se retrouve avec 11 float (half3 dans les shaders)
- Enfin pour l'affichage, on ajoute ces 11 valeurs ensemble, et la transition se fait d'une vertex a l'autre quand deux vertex voisins ne partagent pas la même couleur.

J'ai aussi fait en sorte que l'ordre des couleurs dans le script correspond a l'ordre des textures dans le shader pour plus de facilité.
J'ai aussi fait un Petit package comportant une scene d'exemple avec une sphere et les composant deja assigné et des texture basique (peut être besoin de réassigner les textures au material)

Voilà donc ma première participation au concours. J’espère avoir été assez clair et si ce n'est pas le cas, je répondrais volontiers à vos questions (en MP en attendant de voir si je fais un post dédié dans les tuto)

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Avatar de l’utilisateur
E3DStef
Administrateur
Administrateur
Messages : 1646
Inscription : 14 Juil 2013 18:30
Localisation : https://www.carte-des-membres.com/fr/Unity3D-France/

Re: [Clos - Tirage au sort à venir] #12 : Concours du déconfinement mai 2020 !!!

Message par E3DStef » 18 Juin 2020 23:02

Ok merci de ton lien.

Concours clos je vais procéder au tirage au sort.

Je vous donnerai les informations ici (date heure canal)

A+ et merci de votre participation.

Stef
Le Savoir n'est Précieux que s'il est Partagé

Si besoin urgent de me contacter, faites moi un mail sur : franceunity3d@gmail.com

Verrouillé

Revenir vers « Concours »