N'ayant rien trouvé de concluant sur glouglou, je me suis attelé à la réalisation d'un petit script permettant de visualiser et sélectionner directement les bones d'un gameobject depuis la vue de l'éditeur.
Voici le script à coller sur l'objet au sommet de la hiérarchie :
Code : Tout sélectionner
using UnityEngine;
using System.Collections;
using UnityEditor;
[ExecuteInEditMode]
public class DrawBones : MonoBehaviour
{
public bool drawAxis = true;
public bool drawJoints = true;
private GameObject selectedBone = null;
private bool mouseup = false;
void Start(){
if(Application.isPlaying) this.enabled = false;
}
void drawbone(Transform t)
{
foreach ( Transform child in t){
float len = 0.05f;
if(selectedBone == t.gameObject){
Gizmos.color = Color.magenta;
}else{
Gizmos.color = Color.white;
}
Gizmos.DrawLine(t.position, child.position);
if(drawJoints){
if(selectedBone == child.gameObject){
Gizmos.color = Color.magenta;
}else{
Gizmos.color = Color.white;
}
Gizmos.DrawSphere(child.position,Mathf.Min (0.02f,Vector3.Distance(child.position,t.position)*0.2f));
}
if(drawAxis){
Gizmos.color = Color.red;
Gizmos.DrawLine(child.position, child.position+child.right*len);
Gizmos.color = Color.green;
Gizmos.DrawLine(child.position, child.position+child.up*len);
Gizmos.color = Color.blue;
Gizmos.DrawLine(child.position, child.position+child.forward*len);
}
drawbone(child);
}
}
void OnDrawGizmos(){
if (Event.current.type == EventType.MouseDown){
Ray r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
Gizmos.DrawLine(r.origin,r.origin + r.direction*10);
getNearestBone (r,transform);
}
if (Event.current.type == EventType.MouseUp && selectedBone!=null){
mouseup = true;
}
if(Event.current.type == EventType.Repaint && mouseup){
Selection.activeGameObject = selectedBone;
mouseup = false;
}
drawbone(transform);
}
void getNearestBone(Ray r,Transform t){
Transform nearest = null;
float distance = 9999f;
float d = 0f;
Component[] transforms = t.gameObject.GetComponentsInChildren(typeof(Transform), true);
foreach ( Transform child in transforms){
if(child.parent != null){
d = dist_Point_to_Segment(child.position,r.origin,r.origin+r.direction*100);
if(d < distance && d < 0.1f){
distance = d;
nearest = child;
}
}
}
selectedBone = null;
if(nearest != null) selectedBone = nearest.gameObject;
}
float dist_Point_to_Segment( Vector3 P, Vector3 S0, Vector3 S1){
Vector3 v = S1 - S0;
Vector3 w = P - S0;
float c1 = Vector3.Dot(w,v);
if ( c1 <= 0 )
return Vector3.Distance(P, S0);
float c2 = Vector3.Dot(v,v);
if ( c2 <= c1 )
return Vector3.Distance(P, S1);
float b = c1 / c2;
Vector3 Pb = S0 + b * v;
return Vector3.Distance(P, Pb);
}
}
Du coup je doit attendre l'event Repaint qui suit l'event mouseUp pour effectuer la sélection du bone le plus proche de l'endroit où l'on vient de cliquer
Mais entretemps la sélection du gameobject contenant les bones s'est opérée, donc dans l'ordre on a :
- mousedown -> détection du bone le plus proche du point cliqué
- mouseup
- unity détecte le clic et procède à la sélection du gameobject du mesh
- Repaint -> sélection du bone que le script a détecté
Du coup, à chaque clic ça procède à deux sélections consécutives, ce qui est plutôt désagréable... si quelqu'un a une idée pour régler ça, je suis preneur
... Ou si un autre script mieux foutu existe aussi