I. Introduction▲
Cette série explique pas à pas la création d'un contrôleur pour le mouvement d'un personnage dans un jeu de plateformes 2D.
Vous pouvez retrouver les autres épisodes de cette série dans le sommaire dédié.
II. Vidéo▲
Unity - Contrôleur pour personnage d'un jeu de plateformes - Gestion des collisions
III. Résumé▲
Dans cet épisode, nous allons utiliser le résultat obtenu de la détection des collisions du chapitre précédent afin de modifier la vélocité de l'objet.
III-A. Collisions▲
Premièrement, nous récupérons la liste des objets en collision avec notre objet. Ensuite, nous utilisons cette liste afin d'obtenir l'angle de collision pour déterminer si l'objet est au sol, ou si nous devons restreindre son mouvement. L'angle s'obtient grâce à la normale de l'objet en collision :
using
System.
Collections;
using
System.
Collections.
Generic;
using
UnityEngine;
public
class
PhysicsObject :
MonoBehaviour {
public
float
minGroundNormalY =
.
65f
;
public
float
gravityModifier =
1f
;
protected
bool
grounded;
protected
Vector2 groundNormal;
protected
Rigidbody2D rb2d;
protected
Vector2 velocity;
protected
ContactFilter2D contactFilter;
protected
RaycastHit2D[]
hitBuffer =
new
RaycastHit2D[
16
];
protected
List<
RaycastHit2D>
hitBufferList =
new
List<
RaycastHit2D>
(
16
);
protected
const
float
minMoveDistance =
0
.
001f
;
protected
const
float
shellRadius =
0
.
01f
;
void
OnEnable
(
)
{
rb2d =
GetComponent<
Rigidbody2D>
(
);
}
void
Start (
)
{
contactFilter.
useTriggers =
false
;
contactFilter.
SetLayerMask (
Physics2D.
GetLayerCollisionMask (
gameObject.
layer));
contactFilter.
useLayerMask =
true
;
}
void
Update (
)
{
targetVelocity =
Vector2.
zero;
ComputeVelocity (
);
}
protected
virtual
void
ComputeVelocity
(
)
{
}
void
FixedUpdate
(
)
{
velocity +=
gravityModifier *
Physics2D.
gravity *
Time.
deltaTime;
grounded =
false
;
Vector2 deltaPosition =
velocity *
Time.
deltaTime;
Vector2 move =
Vector2.
up *
deltaPosition.
y;
Movement (
move,
true
);
}
void
Movement
(
Vector2 move,
bool
yMovement)
{
float
distance =
move.
magnitude;
if
(
distance >
minMoveDistance)
{
int
count =
rb2d.
Cast (
move,
contactFilter,
hitBuffer,
distance +
shellRadius);
hitBufferList.
Clear (
);
for
(
int
i =
0
;
i <
count;
i++
) {
hitBufferList.
Add (
hitBuffer [
i]
);
}
for
(
int
i =
0
;
i <
hitBufferList.
Count;
i++
)
{
Vector2 currentNormal =
hitBufferList [
i].
normal;
if
(
currentNormal.
y >
minGroundNormalY)
{
grounded =
true
;
if
(
yMovement)
{
groundNormal =
currentNormal;
currentNormal.
x =
0
;
}
}
float
projection =
Vector2.
Dot (
velocity,
currentNormal);
if
(
projection <
0
)
{
velocity =
velocity -
projection *
currentNormal;
}
float
modifiedDistance =
hitBufferList [
i].
distance -
shellRadius;
distance =
modifiedDistance <
distance ?
modifiedDistance :
distance;
}
}
rb2d.
position =
rb2d.
position +
move.
normalized *
distance;
}
}
IV. Ressources▲
Vous pouvez télécharger les ressources pour ce projet ici.
V. Commenter▲
Vous pouvez commenter et donner vos avis dans la discussion associée sur le forum.