FANDOM


Salut à tous, c'est encore wardow, aujourd'hui le tutoriel portera sur comment faire pour qu'un bloc soit effacé d'une map en cliquant dessus.

Le script pas-à-pasModifier

La fonction Behavior:Awake()Modifier

Commençons tout de suite par :

self.mapRndr = CraftStudio.FindGameObject( "map" ):GetComponent( "MapRenderer" )

Cette ligne vas permettre de stocker dans la variable self.mapRndr le composant de type MapRenderer (Rendu de Map) de l'objet nommé map dans ma scène. Il vous faut donc une scène composée d'un objet (avec un rendu de map) nommée "map", bien évidemment vous pouvez changer ce nom à votre guise. Attention à ne pas modifier "MapRenderer", sinon ça ne fonctionnera pas !


self.camera = CraftStudio.FindGameObject( "camera" ):GetComponent( "Camera" )

Ici nous faisons la même chose mais pour la caméra. Attention à ne pas modifier le dernier "Camera", sinon ça ne fonctionnera pas !


Ces deux lignes doivent être dans la fonction Behavior:Awake(), comme ceci :

function Behavior:Awake()
    self.mapRndr = CraftStudio.FindGameObject( "map" ):GetComponent( "MapRenderer" )
    self.camera = CraftStudio.FindGameObject( "camera" ):GetComponent( "Camera" )
end

La fonction Behavior:Update() Modifier

Elle permettra de vérifier toutes les 60ème de seconde si l'on clique sur un bloc et, si oui, le supprimer.

if CraftStudio.Input.WasButtonJustPressed("clicgauche") then

Il nous faut tout d'abord vérifier si le joueur appuis sur un bouton, la condition se fait avec if et then et la fonction CraftStudio[...]Pressed("clicgauche") renvoie true (vrai) si le bouton est appuyé et si quelque chose est true dans une condition, le script continue(Pas besoin de mettre "== true" ;).


local ​mousepos = CraftStudio.Input.GetMousePosition()

Ensuite il nous faut une info pour pouvoir créer un rayon : la position de la souris. Nous pouvons l'obtenir grâce à cette fonction et nous la stockons dans la variable locale mousepos.


local ray = self.camera:CreateRay( mousepos )

Nous pouvons maintenant créer notre rayon qui a besoin de la caméra (le point de départ du rayon) et de la position de la souris(point par ou la demi-droite passeras) pour fonctionner. Nous avons déjà ces infos, elles sont respectivement dans les variables self.camera et mousepos, c'est super, nous n'avons rien oublié.


local dist, normal, blocpos = ray:IntersectsMapRenderer( self.mapRndr )

Maintenant il faut la position du bloc cliqué, c'est donc avec la fonction IntersectsMapRenderer() que nous allons la récupérer. cette fonction est assez spéciale : elle retourne plusieurs valeurs, stockables dans différentes variables. Les valeurs retournées sont la distance, la normale, la position du bloc et la position du bloc adjacent. Notez que les 3 dernières données sont optionnelles mais si vous souhaitez obtenir une autre donnée, il faut donner une variable à chaque donnée qui se trouve avant.

Si vous souhaitez obtenir la position du bloc cliqué, il faut indiquer une variable pour la distance (dist), une pour la normale (normal) puis enfin une pour la position du bloc cliqué (blocpos).

Nous stockons ces trois valeurs dans des variables locales grâce au mot local devant celles ci.

Cette fonction a besoin, comme vous avez pu le voir de la variable contenant le rayon (ray) et du rendu de la map (self.mapRndr).


if dist ~= nil then

Cette ligne permet de vérifier si la variable dist contient quelque chose, rappelez-vous, dans mes autres tutoriels je l'avais déjà dit, le symbole ~= veux dire "est différent de" et nil est égale a "nul, rien, vide". Si elle est différente de vide, (en fait si elle contient quelque chose) alors l'utilisateur a cliqué sur la map. Nous n'avons pas besoin de savoir ce qu'elle contient, juste de savoir si elle contient quelque chose.


self.mapRndr:GetMap():SetBlockAt( blocpos.x, blocpos.y, blocpos.z, 255, Map.BlockOrientation.North)

Et voila la ligne la plus importante du script (et la dernière si on ne compte pas les end ^^).

En fait, elle contient deux fonctions : GetMap() et SetBlockAt ().

La première permet, avec la variable self.mapRndr de récupérer une table contenant les infos de la map (sûrement la liste des blocs et leur position, mais je n'en suis pas du tout sûr)

La seconde est légèrement plus compliquée : elle a besoin de six informations pour fonctionner : la table contenant les infos sur la map, la position X du bloc à ajouter (Et oui, en fait il n'y a pas de fonction pour supprimmer un bloc alors nous alons changer le bloc cliqué par un bloc vide), la position Y, la position Z, l'ID du bloc et son orientation.

Pour les infos de la map, j'ai expliqué juste au dessus, pour les positions nous avons la variable blocpos définie quelques lignes plus haut, il vous suffit de rajouter .x , .y ou .z juste après pour avoir chacune des positions, l'ID du bloc ici es 255 car cet ID correspond à un bloc vide, et pour l'orientation du bloc j'utilise ici Map.BlockOrientation.North mais puisque le bloc est vide, ça n'a aucune importance (Les orientations disponibles sont : Map.BlockOrientation.North, Map.BlockOrientation.East, Map.BlockOrientation.South, Map.BlockOrientation.West)


N'oubliez pas les deux end pour fermer les deux conditions que nous avons créés et votre script sera fonctionnel !


A la demande de Erwan0fil et NDBand je rajoute une fonction qui permet de détruire certains blocs seulement (en fonction de leur ID)

GetBlockIDAt()

Cette fonction permet de retourner, si on lui donne une table avec les infos de la map et les coordonnées du bloc de retourner son ID.

Vous l'aurez certainement compris : nous alons encore utiliser une condition.

if self.mapRndr:GetMap():GetBlockIDAt ( blocpos.x, blocpos.y, blocpos.z ) == 0 then

Je ne sais pas si j'ai besoin de vous expliquer. Bon aller, je vais quand même le faire :P

If pour la condition.


self.mapRndr:GetMap() Retourne la table avec les infos de la map (voir plus haut).


GetBlockIDAt voir juste au-dessus.


blocpos.x, blocpos.y, blocpos.z corespondent à la position du bloc.


== 0 deux "=" car il en faut deux dans une condition, sinon le jeu pourait confondre avec une insertion de donnée dans une variable, et le 0 correspond à l'ID du bloc que l'on peut détruire.


Si vous le souhaitez vous pouvez rajouter not après le if, et donc l'ID que vous entrerez à la fin sera un bloc que l'on ne peux pas détruire.


if not self.mapRndr:GetMap().....


cette condition doit se trouver entre

if dist ~= nil then

et

self.mapRndr:GetMap():SetBlockAt (blocpos.x, blocpos.y, blocpos.z, 255, Map.BlockOrientation.North)


Le script entierModifier

Et voila à quoi ressemble le script une fois que vous avez tout écris :

function Behavior:Awake()
    self.mapRndr = CraftStudio.FindGameObject( "map" ):GetComponent( "MapRenderer" )
    self.camera = CraftStudio.FindGameObject( "camera" ):GetComponent( "Camera" )
end

function Behavior:Update()

    if CraftStudio.Input.WasButtonJustPressed("clicgauche") then
        local mousepos = CraftStudio.Input.GetMousePosition()
        local ray = self.camera:CreateRay( mousepos )
        local dist, normal, blocpos = ray:IntersectsMapRenderer( self.mapRndr ) 
       
        if dist ~= nil then
            self.mapRndr:GetMap():SetBlockAt( blocpos.x, blocpos.y, blocpos.z, 255, Map.BlockOrientation.North)
        end
    end
end


Et avec la vérification de l'ID du bloc :

function Behavior:Awake()
    self.mapRndr = CraftStudio.FindGameObject("map"):GetComponent("MapRenderer")
    self.camera = CraftStudio.FindGameObject("camera"):GetComponent("Camera")
end

function Behavior:Update()
    if CraftStudio.Input.WasButtonJustPressed("clicgauche") then
        local mousepos = CraftStudio.Input.GetMousePosition()
        local ray = self.camera:CreateRay(mousepos)
        local dist, normal, blocpos = ray:IntersectsMapRenderer( self.mapRndr )
        if dist ~= nil then
            if self.mapRndr:GetMap():GetBlockIDAt ( blocpos.x, blocpos.y, blocpos.z ) == 0 then
                self.mapRndr:GetMap():SetBlockAt (blocpos.x, blocpos.y, blocpos.z, 255, Map.BlockOrientation.North)
            end
        end
    end
end


J'éspère que ce tutoriel vous a plus et n'hésitez pas à me poser des questions / corriger les éventuelles erreurs que j'aurais pu faire.


A bientôt pour un autre tuto :p

Wardow

Interférence d'un bloqueur de publicité détectée !


Wikia est un site gratuit qui compte sur les revenus de la publicité. L'expérience des lecteurs utilisant des bloqueurs de publicité est différente

Wikia n'est pas accessible si vous avez fait d'autres modifications. Supprimez les règles personnalisées de votre bloqueur de publicité, et la page se chargera comme prévu.

Sur le réseau FANDOM

Wiki au hasard