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
[Clos - Tirage au sort à venir] #12 : Concours du déconfinement mai 2020 !!!
- E3DStef
- 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 !!!
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
Si besoin urgent de me contacter, faites moi un mail sur : franceunity3d@gmail.com
Re: #12 : Concours du déconfinement mai 2020 !!!
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:
Le script principal:
L'Editor pour faciliter son usage dans l'inspector. Il n'est pas indispensable mais bien utile
J'espère que ce petit script va pouvoir être utile à beaucoup
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.
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);
}
}
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();
}
}
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.
- E3DStef
- 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 !!!
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
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
Si besoin urgent de me contacter, faites moi un mail sur : franceunity3d@gmail.com
Re: [Clos - Tirage au sort à venir] #12 : Concours du déconfinement mai 2020 !!!
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 :
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 :
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 :
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)
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;
}
}
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),
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"
}
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 _______________________/
- E3DStef
- 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 !!!
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
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
Si besoin urgent de me contacter, faites moi un mail sur : franceunity3d@gmail.com