ne retourne pas tous les points de contact

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
Avatar de l’utilisateur
Kaloverian
Messages : 342
Inscription : 10 Août 2016 03:03

ne retourne pas tous les points de contact

Message par Kaloverian » 06 Jan 2022 16:58

bonjour,

Mon but est lorsque par exemple une sphère1 rentre dans une sphère 2,un script me retourne tous les points de contact.On se rend bien compte que lorsque sphere 1 rentre dans sphère 2,tous les points de contact se situent sur une latitude de la sphère 2 qui se déplace au fur et à mesure qu'elle rentre dans sphère 1.
Hélas la fonction OnCollisionStay ne fournit que 2 points de contact.
voir code dont script est attaché à thisSphereCollider

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class point_contacts_onStay : MonoBehaviour
{
    public SphereCollider thisShereCollider,otherSphereCollider;
    

   
    // Start is called before the first frame update
    void Start()
    {
          ObjList = new List<GameObject>();
    }

    // Update is called once per frame
    void Update()
    {
        
    }
 void OnCollisionStay(Collision otherSphereCollider)
    {
      
        foreach (ContactPoint contact in otherSphereCollider.contacts)
        {
           // Debug.DrawRay(contact.point, contact.normal * 10, Color.blue);
           Debug.Log("point de contact :("+contact.point.x+","+contact.point.y+","+contact.point.z+")");
          Debug.Log("normale de contact :("+contact.normal.x+","+contact.normal.y+","+contact.normal.z+")");
          Debug.Log("nombre depoints de contact"+ otherSphereCollider.contacts.Length);
      
        }
    }
Je n'ai pas l'impression que l'API de Unity fournit ce genre de fonctions.
Comment pourrai-je y arriver?

merci de votre aide

Avatar de l’utilisateur
Kaloverian
Messages : 342
Inscription : 10 Août 2016 03:03

petit problème de collisions multiples

Message par Kaloverian » 08 Jan 2022 18:26

bonjour,

Mon but est à travers un exemple simple(un objet thisCollider heurte en meme temps 2 sphères proches otherCollider1 et otherColllider2)de récupérer au moment de la collision multiple le nombre total de points de contact.
J'attache donc 2 scripts à thisCollider:
collision1.cs

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;



public class collision1 : MonoBehaviour
{
    public SphereCollider thisSphereCollider,otherSphereCollider1;

   Vector3 vect;

   int i,;
  
    // Start is called before the first frame update
    void Start()
    {
     }

    // Update is called once per frame
   void Update()
    {
 
    }

 
    void OnCollisionEnter(Collision otherSphereCollider1) 
    {
        ContactPoint[] contacts = new ContactPoint[10];
          int a= otherSphereCollider1.contacts.Length;
    
        Debug.Log("nombre de points de contact: " + otherSphereCollider1.contacts.Length);
       Debug.Log("First normal of the point that collide: " + otherSphereCollider1.contacts[0].normal);
        
      
   for(int i=0;i<otherSphereCollider1.contacts.Length;i++)
    {
     
    Debug.Log("vcoordonnées du point de contact "+i+" : ("+otherSphereCollider1.contacts[i].point.x+","+otherSphereCollider1.contacts[i].point.y+","+otherSphereCollider1.contacts[i].point.z+")");
         Debug.Log("---------------------------------------------");

    
    }
 
  }


et un autre script collision2.cs

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;



public class collision2 : MonoBehaviour
{
    public SphereCollider thisSphereCollider,otherSphereCollider12

   Vector3 vect;

   int i,;

  
    // Start is called before the first frame update
    void Start()
    {
      
     
    

    }

    // Update is called once per frame
   void Update()
    {
     
      
     
    }

 
    void OnCollisionEnter(Collision otherSphereCollider2)
    
    {  
        ContactPoint[] contacts = new ContactPoint[10];
        
        int b= otherSphereCollider2.contacts.Length;
    
        Debug.Log("nombre de points de contact: " + otherSphereCollider2.contacts.Length);
       Debug.Log("First normal of the point that collide: " + otherSphereCollider2.contacts[0].normal);
        
      
   for(int i=0;i<otherSphereCollider2.contacts.Length;i++)
    {
     
    Debug.Log("vcoordonnées du point de contact "+i+" : ("+otherSphereCollider2.contacts[i].point.x+","+otherSphereCollider2.contacts[i].point.y+","+otherSphereCollider2.contacts[i].point.z+")");
         Debug.Log("---------------------------------------------");

    
    }
 
  }


Seulement,avec ces 2 scripts attachés à thisCollider ,je n'obtiendrais pas le nombre totals de points
J'essaie d'y remédier en créant un nouveau script recapitulatif_collisions.cs incluant 3 classes:
la classe principale qui hérite à la fois de collision1 et collision2
la classe collision1
la classe collision2
Dans la classe prinicipale,je crée 1 objet OBJ1 de collision1 puis 1 objet OBJ2 de collisioN2 puis je définis:
OBJ1.a
OBJ2.b
pour essayer d'obtenir le nombre total de points de contact:
int c=OBJ1;a+OBJ2.b;
comme ceci:

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;




public class recapitulatif_collisions : collision1,collison2
{ 
  void Start()
    {    int c;
         collision1 objet1 = new collision1();
        collision2 objet2 = new collision2();
        c=objet1.a+objet2.b;
        c=a+b;


        
    }

    // Update is called once per frame
    void Update()
    { 
      Debug.Log("nombre total de points de contact :"+c);
     }
    
    
}
public class collision1 
{
    public SphereCollider thisSphereCollider,otherSphereCollider1;

   Vector3 vect;

   int i,;

  
    // Start is called before the first frame update
    void Start()
    {
      
     
    

    }

    // Update is called once per frame
   void Update()
    {
     
      
     
    }

 
    void OnCollisionEnter(Collision otherSphereCollider1)
    
    {  
        ContactPoint[] contacts = new ContactPoint[10];
        
        int b= otherSphereCollider1.contacts.Length;
    
        Debug.Log("nombre de points de contact: " + otherSphereCollider1.contacts.Length);
       Debug.Log("First normal of the point that collide: " + otherSphereCollider1.contacts[0].normal);
        
      
   for(int i=0;i<otherSphereCollider1.contacts.Length;i++)
    {
     
    Debug.Log("vcoordonnées du point de contact "+i+" : ("+otherSphereCollider1.contacts[i].point.x+","+otherSphereCollider1.contacts[i].point.y+","+otherSphereCollider1.contacts[i].point.z+")");
         Debug.Log("---------------------------------------------");

    
    }
}
    
    public class collision2 : 
{
    public SphereCollider thisSphereCollider,otherSphereCollider2;

   Vector3 vect;

   int j,;

  
    // Start is called before the first frame update
    void Start()
    {
      
     
    

    }

    // Update is called once per frame
   void Update()
    {
     
      
     
    }

 
    void OnCollisionEnter(Collision otherSphereCollider2)
    
    {  
        ContactPoint[] contacts = new ContactPoint[10];
        
        int b= otherSphereCollider2.contacts.Length;
    
        Debug.Log("nombre de points de contact: " + otherSphereCollider2.contacts.Length);
       Debug.Log("First normal of the point that collide: " + otherSphereCollider2.contacts[0].normal);
        
      
   for(int j=0;j<otherSphereCollider2.contacts.Length;j++)
    {
     
    Debug.Log("vcoordonnées du point de contact "+j+" : ("+otherSphereCollider2.contacts[i].point.x+","+otherSphereCollider2.contacts[i].point.y+","+otherSphereCollider2.contacts[i].point.z+")");
         Debug.Log("---------------------------------------------");

    
    }

 }

Mon problème est que ce dernier script ne fonctionne pas.
Peut-on alors me le corriger ou me donner une autre solution?

merci de votre aide

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: ne retourne pas tous les points de contact

Message par Max » 08 Jan 2022 19:12

Bonsoir,
Kaloverian a écrit :
08 Jan 2022 18:26
Seulement,avec ces 2 scripts attachés à thisCollider ,je n'obtiendrais pas le nombre totals de points
Tu peux schématiser ton soucis ? Quels sont les points de contacts que tu attends pas exemple dans le cas de deux sphères ?
Avec le moteur physique, si deux sphères entre en contact, tu n'auras qu'un point de contact entre les deux (les sphères ne rentrant pas l'une dans l'autre).
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Avatar de l’utilisateur
Kaloverian
Messages : 342
Inscription : 10 Août 2016 03:03

Re: ne retourne pas tous les points de contact

Message par Kaloverian » 08 Jan 2022 19:52

ci-joint image des 3 sphère.
Unity_collision multiple.PNG
Unity_collision multiple.PNG (91.32 Kio) Consulté 2980 fois
La pshère du milieu est thisColllider qui à un moment donné par translation de (0,0,-1) va heurter les 2 sphères de cotés dont chaque point de contact est facile à deviner.
Chaque script collision1.cs et collision2.cs retourne effectivement 1 point de contact lors de la collision.
Je cherche à créer bon script retournant le nombre total (ici 1+1=2) de points de contact lors de la collision multiple

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: ne retourne pas tous les points de contact

Message par Max » 08 Jan 2022 21:27

cela doit fonctionner alors dans ce cas aussi, avec les deux points de contact.
Je viens de faire le test avec l'exemple de la doc et pas de soucis.

Image
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Avatar de l’utilisateur
Kaloverian
Messages : 342
Inscription : 10 Août 2016 03:03

Re: ne retourne pas tous les points de contact

Message par Kaloverian » 08 Jan 2022 21:38

l'exemple de la doc n'utilise qu'une seule fois la fonction OnCollisionEnter avec un seul objet de type Collision en argument.
Alors qu'il y a 2 déclencheurs(2 collisions)
Avez-vous crée 2 scripts cs en suivant l'exemple de la doc puis les avez-vous attacher à thisCollider?
ou
autrement?

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: ne retourne pas tous les points de contact

Message par Max » 09 Jan 2022 10:36

non un seul script, sur la boule noire qui se déplace et entre en collision avec les deux autres.
Pourquoi faudrait-il un script sur chaque élément ? La fonction OnCollisionEnter va être appelée lors de chaque entrée en collision avec un élément tiers, et fournira le/les points de contact avec ceux-ci. Mettre un script sur chaque élément serait redondant, sauf cas particulier.
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Avatar de l’utilisateur
Kaloverian
Messages : 342
Inscription : 10 Août 2016 03:03

Re: ne retourne pas tous les points de contact

Message par Kaloverian » 09 Jan 2022 23:45

Effectivement:un seul script attaché à this Collider suffit
En utilisant ce script amélioré par rapport à celui de la doc et en mettant thisCollider directement au mileu des 2 autres sphères,les 2 contacts sont simultanés(ils sont effectués au temps 0)

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class collision : MonoBehaviour
{
    public SphereCollider thisSphereCollider,otherSphereCollider;
 
    float time;

    int i;

      void Awake()
    {
        time=Time.time;
       

     }

    // Start is called before the first frame update
    void Start()
    {
      
     
    

    }

    // Update is called once per frame
   void Update()
    {
    
        time=Time.time;
      
     
    }


    void OnCollisionEnter(Collision otherSphereCollider)
    
    {
        ContactPoint[] contacts = new ContactPoint[10];
  
      Debug.Log("nombre de points de contact: " + otherSphereCollider.contacts.Length);
      Debug.Log("First normal of the point that collide: " + otherSphereCollider.contacts[0].normal);
        
      
    

    for(int i=0;i<otherSphereCollider.contacts.Length;i++)
    {
       Debug.Log("point de contact "+i+" : "+contacts[i]);
  
      Debug.Log("vcoordonnées du point de contact "+i+" : ("+otherSphereCollider.contacts[i].point.x+","+otherSphereCollider.contacts[i].point.y+","+otherSphereCollider.contacts[i].point.z+")");
      

          
    }

     Debug.Log("collision du SphereCollider au temps :"+time);
      Debug.Log("le collisionneur est :"+thisSphereCollider.gameObject.tag);
      Debug.Log("le déclencheur est :"+otherSphereCollider.gameObject.tag);
      Debug.Log("---------------------------------------------");
     
    }
    
    
 }

on voit bien que le script rend 2 points de contact différent.
Seulement dans ma console est affiché ceci:
nombre de points de contact: 1
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:68)

First normal of the point that collide: (-1.0, 0.0, 0.0)
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:69)

point de contact 0 : UnityEngine.ContactPoint
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:76)

vcoordonnées du point de contact 0 : (0,4,0,0)
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:84)

collision du SphereCollider au temps : 0
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:90)

le collisionneur est :sphere_first
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:91)

le déclencheur est :sphere A
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:92)

---------------------------------------------
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:93)

nombre de points de contact: 1
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:68)

First normal of the point that collide: (1.0, 0.0, 0.0)
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:69)

point de contact 0 : UnityEngine.ContactPoint
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:76)

vcoordonnées du point de contact 0 : (-0,4,0,0)
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:84)

collision du SphereCollider au temps : 0
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:90)

le collisionneur est :sphere_first
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:91)

le déclencheur est :sphere B
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:92)

---------------------------------------------
UnityEngine.Debug:Log (object)
collision1:OnCollisionEnter (UnityEngine.Collision) (at Assets/collision1.cs:93)

2 fois nombre de contact :1
au lieu d'une seule fois nombre de points de contact :2
Pourquoi otherSphereCollider.contacts.Length retourne 1 au lieu de 2?
Dernière édition par Kaloverian le 10 Jan 2022 16:04, édité 3 fois.

Avatar de l’utilisateur
Max
Messages : 8771
Inscription : 30 Juil 2011 13:57
Contact :

Re: ne retourne pas tous les points de contact

Message par Max » 10 Jan 2022 09:34

Kaloverian a écrit :
09 Jan 2022 23:45
2 fois nombre de contact :1
au lieu d'une seule fois nombre de points de contact :2
Pourquoi otherSphereCollider.contacts.Length retourne 1 au lieu de 2?
je dirais que le contact avec les deux éléments ne se faisant pas en même temps, tu rentres donc deux fois de suite dans OnCollisionEnter(). Donc plutôt logique comme résulta.
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Avatar de l’utilisateur
Kaloverian
Messages : 342
Inscription : 10 Août 2016 03:03

Re: ne retourne pas tous les points de contact

Message par Kaloverian » 10 Jan 2022 16:08

Mais une autre question survient:
Quand par exemple une sphère1 rentre dans une sphère 2,ce script ne retournepas tous les points de contact.On se rend bien compte que lorsque sphere 1 rentre dans sphère 2,tous les points de contact se situent sur une latitude de la sphère 2 qui se déplace au fur et à mesure qu'elle rentre dans sphère 1.On voit bien que le nombre de points de contact est infini alors que mon script n'en retourne que 2!
Je pense alors à la fonction OnCollisionStay mais je n'arrive à bien l'mplémenter
Dernière édition par Kaloverian le 11 Jan 2022 00:58, édité 4 fois.

Répondre

Revenir vers « (C#) CSharp »