dindomoteur_creation_du_joueur
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédenteProchaine révisionLes deux révisions suivantes | ||
dindomoteur_creation_du_joueur [2022/03/20 15:42] – Simon Deplat | dindomoteur_creation_du_joueur [2022/03/27 13:21] – Simon Deplat | ||
---|---|---|---|
Ligne 28: | Ligne 28: | ||
De manière intuitive, chacun d' | De manière intuitive, chacun d' | ||
+ | |||
+ | **Les calques et masques de collisions seront également réglés correctement** (le Joueur est sur le calque 1 et détecte le masque 4 (entre autres), et la plate-forme est sur le calque 4 et ne détecte rien). | ||
Ensuite, **je les ajoute au nœud Main en les instanciant**. Ils ne bougent pas, mais ils apparaissent à l' | Ensuite, **je les ajoute au nœud Main en les instanciant**. Ils ne bougent pas, mais ils apparaissent à l' | ||
Ligne 53: | Ligne 55: | ||
====Note à propos de la classe Joueur==== | ====Note à propos de la classe Joueur==== | ||
- | Dans les versions | + | Dans les versions |
- | Nous allons mettre | + | Les scripts |
+ | |||
+ | Notamment, dans le script | ||
+ | |||
+ | **De fait nous n' | ||
====Implémentation de la gravité==== | ====Implémentation de la gravité==== | ||
- | Chaque personnage | + | Le joueur |
- | // | ||
< | < | ||
- | class_name Personnage | ||
extends KinematicBody2D | extends KinematicBody2D | ||
- | var masse = 1 | + | var _gravite |
- | var gravite | + | |
+ | var _masse | ||
var _velocite = Vector2.ZERO | var _velocite = Vector2.ZERO | ||
- | # la fonction _physics_process héritée est appelée | + | func _ready(): |
- | # après la fonction _physics_process parente | + | if get_tree().root.has_node(" |
- | func _physics_process( | + | _gravite = Global.gravite |
- | _velocite.y += gravite | + | |
+ | func _physics_process( | ||
+ | |||
+ | # Intégration de la gravité | ||
+ | _velocite.y += _gravite | ||
+ | |||
+ | _velocite = move_and_slide_with_snap( | ||
+ | _velocite, | ||
+ | Vector2.ZERO, | ||
+ | Vector2.UP, | ||
+ | true, # Ne glisse pas sur le sol en cas d' | ||
+ | 4, # Nombre de collisions traitées par cycle | ||
+ | 0.9, # Angle maximum du sol ( en radians ) | ||
+ | false # Inertie infinie ? | ||
+ | ) | ||
</ | </ | ||
- | //joueur.gd// | + | ====Implémentation du saut==== |
+ | |||
+ | On ajoute au Joueur une capacité de saut. Plus les valeurs de //masse// et de // | ||
+ | |||
+ | // | ||
< | < | ||
- | class_name Joueur | + | extends |
- | extends | + | |
+ | var _gravite = 50 | ||
+ | |||
+ | var _masse = 1 | ||
+ | var _forceSaut = 1000 | ||
+ | |||
+ | var _velocite = Vector2.ZERO | ||
func _ready(): | func _ready(): | ||
- | masse = 50 | + | if get_tree().root.has_node(" |
+ | _gravite | ||
func _physics_process( _delta ): | func _physics_process( _delta ): | ||
+ | |||
+ | entreeSaut() | ||
+ | |||
+ | # Intégration de la gravité | ||
+ | _velocite.y += _gravite * _masse | ||
_velocite = move_and_slide_with_snap( | _velocite = move_and_slide_with_snap( | ||
Ligne 96: | Ligne 131: | ||
false # Inertie infinie ? | false # Inertie infinie ? | ||
) | ) | ||
+ | |||
+ | # Appui sur le bouton de saut | ||
+ | func entreeSaut(): | ||
+ | # Mécanisme de saut | ||
+ | if is_on_floor(): | ||
+ | if Input.is_action_just_pressed(" | ||
+ | _velocite.y -= _forceSaut | ||
</ | </ | ||
- | ====Implémentation | + | ====Ajout du déplacement latéral==== |
+ | Un simple algorithme qui permet de **déplacer le Joueur sur l'axe horizontal**. Ici, le plus intéressant est la méthode // | ||
- | On ajoute au Personnage une capacité | + | Pas de phénomène d' |
- | // | ||
< | < | ||
- | class_name Personnage | ||
extends KinematicBody2D | extends KinematicBody2D | ||
- | var masse = 1 | + | var _gravite |
- | var gravite = Global.gravite | + | |
- | var forceSaut = 1 | + | |
- | var forceSautActuelle | + | var _masse |
- | var surLeSol | + | var _forceSaut |
+ | var _vitesse = 300 | ||
+ | |||
+ | var _direction = 0 | ||
var _velocite = Vector2.ZERO | var _velocite = Vector2.ZERO | ||
- | # la fonction _physics_process héritée est appelée | + | func _ready(): |
- | # après la fonction _physics_process parente | + | if get_tree().root.has_node(" |
- | func _physics_process( | + | _gravite = Global.gravite |
- | _velocite.y += gravite | + | |
+ | func _physics_process( | ||
+ | |||
+ | bouge() | ||
+ | entreeSaut() | ||
+ | |||
+ | # Intégration du déplacement latéral | ||
+ | _velocite.x = _direction * _vitesse | ||
+ | # Intégration de la gravité | ||
+ | _velocite.y += _gravite | ||
+ | |||
+ | _velocite = move_and_slide_with_snap( | ||
+ | _velocite, | ||
+ | Vector2.ZERO, | ||
+ | Vector2.UP, | ||
+ | true, # Ne glisse pas sur le sol en cas d' | ||
+ | 4, # Nombre de collisions traitées par cycle | ||
+ | 0.9, # Angle maximum du sol ( en radians ) | ||
+ | false # Inertie infinie ? | ||
+ | ) | ||
+ | |||
+ | # Appui sur le bouton de saut | ||
+ | func entreeSaut(): | ||
+ | # Mécanisme de saut | ||
+ | if is_on_floor(): | ||
+ | if Input.is_action_just_pressed(" | ||
+ | _velocite.y -= _forceSaut | ||
+ | |||
+ | # Appui sur les boutons clavier de déplacement | ||
+ | func bouge(): | ||
+ | if Input.is_action_just_pressed(" | ||
+ | _direction = -1 | ||
+ | elif Input.is_action_just_pressed(" | ||
+ | _direction = 1 | ||
+ | |||
+ | if Input.is_action_just_released(" | ||
+ | if not Input.is_action_pressed(" | ||
+ | _direction = 0 | ||
+ | else: | ||
+ | _direction = 1 | ||
- | # On vérifie si le personnage est sur le sol | + | if Input.is_action_just_released(" |
- | surLeSol = is_on_floor() | + | if not Input.is_action_pressed(" |
- | #Si oui, et s'il est en train de sauter, | + | _direction |
- | if surLeSol and forceSautActuelle > 0: | + | else: |
- | # Remise à zéro de sa vélocité de saut | + | _direction |
- | pass | + | |
- | # | + | |
- | if not surLeSol and forceSautActuelle > 0: | + | |
- | # Décroît de la vélocité de saut | + | |
- | forceSautActuelle | + | |
- | # Remise à zéro si la vélocité de saut devient négative | + | |
- | if forceSautActuelle < 0: | + | |
- | forceSautActuelle | + | |
- | print(forceSautActuelle) | + | |
</ | </ | ||
- | //joueur.gd// | + | |
+ | ====Ajout d'une inertie latérale==== | ||
+ | Il y a maintenant nécessité pour le //Joueur// de **se mettre en mouvement et d' | ||
< | < | ||
- | class_name Joueur | + | extends |
- | extends | + | |
+ | var _gravite = 50 | ||
+ | |||
+ | var _masse = 1 | ||
+ | var _forceSaut = 350 | ||
+ | var _vitesse = 300 | ||
+ | var _acceleration = 20 | ||
+ | var _deceleration = 10 | ||
+ | |||
+ | var _direction = 0 | ||
+ | var _vitesseActuelle = 0 | ||
+ | |||
+ | var _velocite = Vector2.ZERO | ||
func _ready(): | func _ready(): | ||
- | masse = 100 | + | if get_tree().root.has_node(" |
- | forceSaut | + | _gravite |
func _physics_process( _delta ): | func _physics_process( _delta ): | ||
+ | bouge() | ||
+ | entreeSaut() | ||
+ | traitementDuMouvement() | ||
+ | |||
+ | # Intégration du déplacement latéral | ||
+ | _velocite.x = _vitesseActuelle | ||
+ | # Intégration de la gravité | ||
+ | _velocite.y += _gravite * _masse | ||
+ | |||
+ | _velocite = move_and_slide_with_snap( | ||
+ | _velocite, | ||
+ | Vector2.ZERO, | ||
+ | Vector2.UP, | ||
+ | true, # Ne glisse pas sur le sol en cas d' | ||
+ | 4, # Nombre de collisions traitées par cycle | ||
+ | 0.9, # Angle maximum du sol ( en radians ) | ||
+ | false # Inertie infinie ? | ||
+ | ) | ||
+ | |||
+ | # Appui sur le bouton de saut | ||
+ | func entreeSaut(): | ||
# Mécanisme de saut | # Mécanisme de saut | ||
- | if surLeSol: | + | if is_on_floor(): |
if Input.is_action_just_pressed(" | if Input.is_action_just_pressed(" | ||
- | forceSautActuelle | + | _velocite.y |
+ | |||
+ | # Appui sur les boutons clavier de déplacement | ||
+ | func bouge(): | ||
+ | if Input.is_action_just_pressed(" | ||
+ | _direction = -1 | ||
+ | elif Input.is_action_just_pressed(" | ||
+ | _direction = 1 | ||
- | # Si le personnage | + | if Input.is_action_just_released(" |
- | if forceSautActuelle | + | if not Input.is_action_pressed(" |
- | # Compensation | + | _direction = 0 |
- | _velocite.y | + | else: |
+ | _direction = 1 | ||
+ | |||
+ | if Input.is_action_just_released(" | ||
+ | if not Input.is_action_pressed(" | ||
+ | _direction = 0 | ||
+ | else: | ||
+ | _direction = -1 | ||
+ | |||
+ | # Gestion des accélérations/ | ||
+ | func traitementDuMouvement(): | ||
+ | # Vélocité horizontale | ||
+ | if _direction != 0: | ||
+ | _vitesseActuelle += _acceleration * _direction | ||
+ | |||
+ | # Restriction aux vitesses max | ||
+ | if _vitesseActuelle < 0: | ||
+ | if _vitesseActuelle < -_vitesse: | ||
+ | _vitesseActuelle = -_vitesse | ||
+ | else: | ||
+ | if _vitesseActuelle > _vitesse: | ||
+ | _vitesseActuelle = _vitesse | ||
+ | else: | ||
+ | # Décélération au sol | ||
+ | if is_on_floor(): | ||
+ | if _vitesseActuelle < 0: | ||
+ | if _vitesseActuelle < -_deceleration: | ||
+ | _vitesseActuelle += _deceleration | ||
+ | else: | ||
+ | _vitesseActuelle = 0 | ||
+ | elif _vitesseActuelle > 0: | ||
+ | if _vitesseActuelle > _deceleration: | ||
+ | _vitesseActuelle -= _deceleration | ||
+ | else: | ||
+ | _vitesseActuelle = 0 | ||
+ | </ | ||
+ | |||
+ | ====Affinage de l' | ||
+ | On ajoute deux mécanismes pour rendre les sauts plus agréables. | ||
+ | |||
+ | Premièrement, | ||
+ | |||
+ | Deuxièmement, | ||
+ | |||
+ | <code> | ||
+ | extends KinematicBody2D | ||
+ | |||
+ | var _gravite = 50 | ||
+ | |||
+ | var _masse = 2 | ||
+ | var _forceSaut = 2000 | ||
+ | var _vitesse = 300 | ||
+ | var _acceleration = 20 | ||
+ | var _deceleration = 10 | ||
+ | var _ratioDInterruptionDuSaut = 0.5 | ||
+ | var _ratioDGraviteSaut = 0.75 | ||
+ | |||
+ | var _direction = 0 | ||
+ | var _vitesseActuelle = 0 | ||
+ | var _forceSautActuelle = 0 | ||
+ | |||
+ | var _velocite = Vector2.ZERO | ||
+ | var _saute = false | ||
+ | |||
+ | func _ready(): | ||
+ | if get_tree().root.has_node(" | ||
+ | _gravite = Global.gravite | ||
+ | |||
+ | func _physics_process( _delta ): | ||
+ | |||
+ | bouge() | ||
+ | entreeSaut() | ||
+ | if _saute: | ||
+ | if _velocite.y < 0: | ||
+ | interruptionDuSaut() | ||
+ | traitementDuMouvement() | ||
+ | |||
+ | # Intégration du déplacement latéral | ||
+ | _velocite.x = _vitesseActuelle | ||
+ | # Intégration | ||
+ | if _velocite.y < 0: | ||
+ | _velocite.y | ||
+ | else: | ||
+ | _velocite.y += _gravite * _masse | ||
_velocite = move_and_slide_with_snap( | _velocite = move_and_slide_with_snap( | ||
Ligne 168: | Ligne 366: | ||
) | ) | ||
+ | # Appui sur le bouton de saut | ||
+ | func entreeSaut(): | ||
+ | # Mécanisme de saut | ||
+ | if is_on_floor(): | ||
+ | if Input.is_action_just_pressed(" | ||
+ | _velocite.y -= _forceSaut | ||
+ | _saute = true | ||
+ | |||
+ | # Gestion de l' | ||
+ | func interruptionDuSaut(): | ||
+ | if Input.is_action_just_released(" | ||
+ | _velocite.y *= _ratioDInterruptionDuSaut | ||
+ | _saute = false | ||
+ | |||
+ | # Appui sur les boutons clavier de déplacement | ||
+ | func bouge(): | ||
+ | if Input.is_action_just_pressed(" | ||
+ | _direction = -1 | ||
+ | elif Input.is_action_just_pressed(" | ||
+ | _direction = 1 | ||
+ | |||
+ | if Input.is_action_just_released(" | ||
+ | if not Input.is_action_pressed(" | ||
+ | _direction = 0 | ||
+ | else: | ||
+ | _direction = 1 | ||
+ | |||
+ | if Input.is_action_just_released(" | ||
+ | if not Input.is_action_pressed(" | ||
+ | _direction = 0 | ||
+ | else: | ||
+ | _direction = -1 | ||
+ | |||
+ | # Gestion des accélérations/ | ||
+ | func traitementDuMouvement(): | ||
+ | # Vélocité horizontale | ||
+ | if _direction != 0: | ||
+ | _vitesseActuelle += _acceleration * _direction | ||
+ | |||
+ | # Restriction aux vitesses max | ||
+ | if _vitesseActuelle < 0: | ||
+ | if _vitesseActuelle < -_vitesse: | ||
+ | _vitesseActuelle = -_vitesse | ||
+ | else: | ||
+ | if _vitesseActuelle > _vitesse: | ||
+ | _vitesseActuelle = _vitesse | ||
+ | else: | ||
+ | # Décélération au sol | ||
+ | if is_on_floor(): | ||
+ | if _vitesseActuelle < 0: | ||
+ | if _vitesseActuelle < -_deceleration: | ||
+ | _vitesseActuelle += _deceleration | ||
+ | else: | ||
+ | _vitesseActuelle = 0 | ||
+ | elif _vitesseActuelle > 0: | ||
+ | if _vitesseActuelle > _deceleration: | ||
+ | _vitesseActuelle -= _deceleration | ||
+ | else: | ||
+ | _vitesseActuelle = 0 | ||
</ | </ | ||
- | **[EN CONSTRUCTION]** | + | ====Ajout d'une Camera2D==== |
+ | |||
+ | **L' | ||
+ | |||
+ | À l'aide de l' | ||
+ | |||
+ | C'est suffisant pour le prototypage. | ||
+ | |||
+ | ====Changement de direction du personnage==== | ||
+ | |||
+ | L' | ||
+ | |||
+ | < | ||
+ | # Appui sur les boutons clavier de déplacement | ||
+ | func bouge(): | ||
+ | if Input.is_action_just_pressed(" | ||
+ | _direction = -1 | ||
+ | if not Input.is_action_pressed(" | ||
+ | $Sprite.set_scale( Vector2( -1, 1 ) ) | ||
+ | elif Input.is_action_just_pressed(" | ||
+ | _direction = 1 | ||
+ | if not Input.is_action_pressed(" | ||
+ | $Sprite.set_scale( Vector2( 1, 1 ) ) | ||
+ | if Input.is_action_just_released(" | ||
+ | if not Input.is_action_pressed(" | ||
+ | _direction = 0 | ||
+ | else: | ||
+ | _direction = 1 | ||
+ | $Sprite.set_scale( Vector2( 1, 1 ) ) | ||
+ | |||
+ | if Input.is_action_just_released(" | ||
+ | if not Input.is_action_pressed(" | ||
+ | _direction = 0 | ||
+ | else: | ||
+ | _direction = -1 | ||
+ | $Sprite.set_scale( Vector2( -1, 1 ) ) | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====Animation du personnage==== | ||
+ | |||
+ | Il ne manque à ce stade plus que d' | ||
+ | |||
+ | {{ :: | ||
+ | |||
+ | J'ai commencé par **ajouter un nœud // | ||
+ | |||
+ | J'ai activé **la //lecture automatique au chargement// | ||
+ | |||
+ | J'ai dû rajouter un nœud // | ||
+ | |||
+ | Le tout est ensuite appelé au sein d'une fonction dédiée : | ||
+ | |||
+ | < | ||
+ | func _physics_process( _delta ): | ||
+ | [...] | ||
+ | animer() | ||
+ | |||
+ | [...] | ||
+ | |||
+ | # Animation du personnage : | ||
+ | func animer(): | ||
+ | # Vérifier si le personnage est au sol : | ||
+ | if $RayCast2D.is_colliding(): | ||
+ | # S'il bouge | ||
+ | if _velocite.x != 0: | ||
+ | $AnimationPlayer.play(" | ||
+ | # Sinon | ||
+ | else: | ||
+ | $AnimationPlayer.play(" | ||
+ | else: | ||
+ | $AnimationPlayer.play(" | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====Contrôle du personnage à la manette==== | ||
+ | |||
+ | Avant de terminer, je souhaite simplement que l'on puisse également **contrôler le personnage à l'aide d'une manette**. | ||
+ | |||
+ | Dans cette optique, je décide de changer la fonction //bouge()// affin qu' | ||
+ | |||
+ | Je rajoute donc **un paramètre d' | ||
+ | |||
+ | < | ||
+ | extends KinematicBody2D | ||
+ | |||
+ | var _typeEntree = " | ||
+ | var _zoneMorte = 0.3 | ||
+ | |||
+ | var _gravite = 50 | ||
+ | |||
+ | var _masse = 2 | ||
+ | var _forceSaut = 2000 | ||
+ | var _vitesse = 400 | ||
+ | var _acceleration = 20 | ||
+ | var _deceleration = 10 | ||
+ | var _ratioDInterruptionDuSaut = 0.5 | ||
+ | var _ratioDGraviteSaut = 0.75 | ||
+ | |||
+ | var _direction = 0 | ||
+ | var _vitesseActuelle = 0 | ||
+ | var _forceSautActuelle = 0 | ||
+ | |||
+ | var _velocite = Vector2.ZERO | ||
+ | var _saute = false | ||
+ | |||
+ | func _ready(): | ||
+ | if get_tree().root.has_node(" | ||
+ | _typeEntree = Global.typeEntree | ||
+ | _zoneMorte = Global.zoneMorte | ||
+ | _gravite = Global.gravite | ||
+ | |||
+ | func _physics_process( _delta ): | ||
+ | |||
+ | bouge() | ||
+ | entreeSaut() | ||
+ | if _saute: | ||
+ | if _velocite.y < 0: | ||
+ | interruptionDuSaut() | ||
+ | traitementDuMouvement() | ||
+ | |||
+ | # Intégration du déplacement latéral | ||
+ | _velocite.x = _vitesseActuelle | ||
+ | # Intégration de la gravité | ||
+ | if _velocite.y < 0: | ||
+ | _velocite.y += _gravite * _masse * _ratioDGraviteSaut | ||
+ | else: | ||
+ | _velocite.y += _gravite * _masse | ||
+ | |||
+ | _velocite = move_and_slide_with_snap( | ||
+ | _velocite, | ||
+ | Vector2.ZERO, | ||
+ | Vector2.UP, | ||
+ | true, # Ne glisse pas sur le sol en cas d' | ||
+ | 4, # Nombre de collisions traitées par cycle | ||
+ | 0.9, # Angle maximum du sol ( en radians ) | ||
+ | false # Inertie infinie ? | ||
+ | ) | ||
+ | |||
+ | animer() | ||
+ | |||
+ | # Appui sur le bouton de saut | ||
+ | func entreeSaut(): | ||
+ | # Mécanisme de saut | ||
+ | if is_on_floor(): | ||
+ | if Input.is_action_just_pressed(" | ||
+ | _velocite.y -= _forceSaut | ||
+ | _saute = true | ||
+ | |||
+ | # Gestion de l' | ||
+ | func interruptionDuSaut(): | ||
+ | if Input.is_action_just_released(" | ||
+ | _velocite.y *= _ratioDInterruptionDuSaut | ||
+ | _saute = false | ||
+ | |||
+ | # Appui sur les boutons clavier de déplacement | ||
+ | func bouge(): | ||
+ | if _typeEntree == " | ||
+ | var entree = Input.get_axis(" | ||
+ | if entree < -_zoneMorte: | ||
+ | _direction = -1 | ||
+ | $Sprite.set_scale( Vector2( -1, 1 ) ) | ||
+ | elif entree > _zoneMorte: | ||
+ | _direction = 1 | ||
+ | $Sprite.set_scale( Vector2( 1, 1 ) ) | ||
+ | else: | ||
+ | _direction = 0 | ||
+ | else: | ||
+ | if Input.is_action_just_pressed(" | ||
+ | _direction = -1 | ||
+ | if not Input.is_action_pressed(" | ||
+ | $Sprite.set_scale( Vector2( -1, 1 ) ) | ||
+ | elif Input.is_action_just_pressed(" | ||
+ | _direction = 1 | ||
+ | if not Input.is_action_pressed(" | ||
+ | $Sprite.set_scale( Vector2( 1, 1 ) ) | ||
+ | if Input.is_action_just_released(" | ||
+ | if not Input.is_action_pressed(" | ||
+ | _direction = 0 | ||
+ | else: | ||
+ | _direction = 1 | ||
+ | $Sprite.set_scale( Vector2( 1, 1 ) ) | ||
+ | |||
+ | if Input.is_action_just_released(" | ||
+ | if not Input.is_action_pressed(" | ||
+ | _direction = 0 | ||
+ | else: | ||
+ | _direction = -1 | ||
+ | $Sprite.set_scale( Vector2( -1, 1 ) ) | ||
+ | |||
+ | # Gestion des accélérations/ | ||
+ | func traitementDuMouvement(): | ||
+ | # Vélocité horizontale | ||
+ | if _direction != 0: | ||
+ | _vitesseActuelle += _acceleration * _direction | ||
+ | |||
+ | # Restriction aux vitesses max | ||
+ | if _vitesseActuelle < 0: | ||
+ | if _vitesseActuelle < -_vitesse: | ||
+ | _vitesseActuelle = -_vitesse | ||
+ | else: | ||
+ | if _vitesseActuelle > _vitesse: | ||
+ | _vitesseActuelle = _vitesse | ||
+ | else: | ||
+ | # Décélération au sol | ||
+ | if is_on_floor(): | ||
+ | if _vitesseActuelle < 0: | ||
+ | if _vitesseActuelle < -_deceleration: | ||
+ | _vitesseActuelle += _deceleration | ||
+ | else: | ||
+ | _vitesseActuelle = 0 | ||
+ | elif _vitesseActuelle > 0: | ||
+ | if _vitesseActuelle > _deceleration: | ||
+ | _vitesseActuelle -= _deceleration | ||
+ | else: | ||
+ | _vitesseActuelle = 0 | ||
+ | |||
+ | # Animation du personnage : | ||
+ | func animer(): | ||
+ | # Vérifier si le personnage est au sol : | ||
+ | if $RayCast2D.is_colliding(): | ||
+ | # S'il bouge | ||
+ | if _velocite.x != 0: | ||
+ | $AnimationPlayer.play(" | ||
+ | # Sinon | ||
+ | else: | ||
+ | $AnimationPlayer.play(" | ||
+ | else: | ||
+ | $AnimationPlayer.play(" | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ====Notes de fin==== | ||
+ | |||
+ | Et voilà pour cette première étape de personnage. Je décide de m' | ||
+ | |||
+ | Il pourra servir de base pour des jeux n' | ||
+ | |||
+ | Au cas où, voici à quoi ressemble ma scène dans l' | ||
+ | |||
+ | {{ :: | ||
+ | |||
+ | Notez que je n'ai pas renommé les noeuds (sauf le parent) pour que vous les identifiiez plus facilement ici, mais qu'il est tout-de-même conseillé de les renommer lors de ses projets propres. | ||
+ | Je créé par ailleurs **une copie autonome de ce //Joueur// dans le dossier // | ||
{{tag> | {{tag> |
dindomoteur_creation_du_joueur.txt · Dernière modification : 2022/03/27 19:24 de Simon Deplat