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.




