unity3d - How can i create a 2D 'curve' collider -
i'm trying search smart way create curves next 1 (using unity3d 2d part (without using mesh collider))) , didn't found one
any appreciated.
seeing last answer (removed) doesn't fit want. have made myself beziercollider2d using bezier curves between 2 points , edgecollider2d.
version 1
beziercollider2d.cs
using unityengine; using system.collections; using system.collections.generic; [requirecomponent (typeof (edgecollider2d))] public class beziercollider2d : monobehaviour { public vector2 firstpoint; public vector2 secondpoint; public vector2 handlerfirstpoint; public vector2 handlersecondpoint; public int pointsquantity; vector3 calculatebezierpoint(float t,vector3 p0,vector3 handlerp0,vector3 handlerp1,vector3 p1) { float u = 1.0f - t; float tt = t * t; float uu = u * u; float uuu = uu * u; float ttt = tt * t; vector3 p = uuu * p0; //first term p += 3f * uu * t * handlerp0; //second term p += 3f * u * tt * handlerp1; //third term p += ttt * p1; //fourth term return p; } public vector2[] calculate2dpoints() { list<vector2> points = new list<vector2>(); points.add(firstpoint); for(int i=1;i<pointsquantity;i++) { points.add(calculatebezierpoint((1f/pointsquantity)*i,firstpoint,handlerfirstpoint,handlersecondpoint,secondpoint)); } points.add(secondpoint); return points.toarray(); }
}
beziercollider2deditor.cs
using unityengine; using unityeditor; using system.collections; [customeditor(typeof(beziercollider2d))] public class beziercollider2deditor : editor { beziercollider2d beziercollider; edgecollider2d edgecollider; int lastpointsquantity = 0; vector2 lastfirstpoint = vector2.zero; vector2 lasthandlerfirstpoint = vector2.zero; vector2 lastsecondpoint = vector2.zero; vector2 lasthandlersecondpoint = vector2.zero; public override void oninspectorgui() { beziercollider = (beziercollider2d) target; edgecollider = beziercollider.getcomponent<edgecollider2d>(); if (edgecollider != null) { beziercollider.pointsquantity = editorguilayout.intfield ("curve points",beziercollider.pointsquantity, guilayout.minwidth(100)); beziercollider.firstpoint = editorguilayout.vector2field ("first point",beziercollider.firstpoint, guilayout.minwidth(100)); beziercollider.handlerfirstpoint = editorguilayout.vector2field ("handler first point",beziercollider.handlerfirstpoint, guilayout.minwidth(100)); beziercollider.secondpoint = editorguilayout.vector2field ("second point",beziercollider.secondpoint, guilayout.minwidth(100)); beziercollider.handlersecondpoint = editorguilayout.vector2field ("handler secondpoint",beziercollider.handlersecondpoint, guilayout.minwidth(100)); editorutility.setdirty(beziercollider); if (beziercollider.pointsquantity > 0 && !beziercollider.firstpoint.equals(beziercollider.secondpoint) && ( lastpointsquantity != beziercollider.pointsquantity || lastfirstpoint != beziercollider.firstpoint || lasthandlerfirstpoint != beziercollider.handlerfirstpoint || lastsecondpoint != beziercollider.secondpoint || lasthandlersecondpoint != beziercollider.handlersecondpoint )) { edgecollider.points = beziercollider.calculate2dpoints(); } } } }
sample:
version 2 (with visual handlers , hiden edge collider in inspector)
beziercollider2d.cs
using unityengine; using system.collections.generic; [requirecomponent (typeof (edgecollider2d))] public class beziercollider2d : monobehaviour { public vector2 firstpoint; public vector2 secondpoint; public vector2 handlerfirstpoint; public vector2 handlersecondpoint; public int pointsquantity; vector3 calculatebezierpoint(float t,vector3 p0,vector3 handlerp0,vector3 handlerp1,vector3 p1) { float u = 1.0f - t; float tt = t * t; float uu = u * u; float uuu = uu * u; float ttt = tt * t; vector3 p = uuu * p0; //first term p += 3f * uu * t * handlerp0; //second term p += 3f * u * tt * handlerp1; //third term p += ttt * p1; //fourth term return p; } public vector2[] calculate2dpoints() { list<vector2> points = new list<vector2>(); points.add(firstpoint); for(int i=1;i<pointsquantity;i++) { points.add(calculatebezierpoint((1f/pointsquantity)*i,firstpoint,handlerfirstpoint,handlersecondpoint,secondpoint)); } points.add(secondpoint); return points.toarray(); } }
beziercollider2deditor.cs
using unityengine; using unityeditor; [customeditor(typeof(beziercollider2d))] public class beziercollider2deditor : editor { beziercollider2d beziercollider; edgecollider2d edgecollider; int lastpointsquantity = 0; vector2 lastfirstpoint = vector2.zero; vector2 lasthandlerfirstpoint = vector2.zero; vector2 lastsecondpoint = vector2.zero; vector2 lasthandlersecondpoint = vector2.zero; public override void oninspectorgui() { beziercollider = (beziercollider2d) target; edgecollider = beziercollider.getcomponent<edgecollider2d>(); if (edgecollider.hideflags != hideflags.hideininspector) { edgecollider.hideflags = hideflags.hideininspector; } if (edgecollider != null) { beziercollider.pointsquantity = editorguilayout.intfield ("curve points",beziercollider.pointsquantity, guilayout.minwidth(100)); beziercollider.firstpoint = editorguilayout.vector2field ("first point",beziercollider.firstpoint, guilayout.minwidth(100)); beziercollider.handlerfirstpoint = editorguilayout.vector2field ("handler first point",beziercollider.handlerfirstpoint, guilayout.minwidth(100)); beziercollider.secondpoint = editorguilayout.vector2field ("second point",beziercollider.secondpoint, guilayout.minwidth(100)); beziercollider.handlersecondpoint = editorguilayout.vector2field ("handler secondpoint",beziercollider.handlersecondpoint, guilayout.minwidth(100)); editorutility.setdirty(beziercollider); if (beziercollider.pointsquantity > 0 && !beziercollider.firstpoint.equals(beziercollider.secondpoint) && ( lastpointsquantity != beziercollider.pointsquantity || lastfirstpoint != beziercollider.firstpoint || lasthandlerfirstpoint != beziercollider.handlerfirstpoint || lastsecondpoint != beziercollider.secondpoint || lasthandlersecondpoint != beziercollider.handlersecondpoint )) { lastpointsquantity = beziercollider.pointsquantity; lastfirstpoint = beziercollider.firstpoint; lasthandlerfirstpoint = beziercollider.handlerfirstpoint; lastsecondpoint = beziercollider.secondpoint; lasthandlersecondpoint = beziercollider.handlersecondpoint; edgecollider.points = beziercollider.calculate2dpoints(); } } } void onscenegui () { if (beziercollider != null) { handles.color = color.grey; handles.drawline(beziercollider.transform.position+(vector3)beziercollider.handlerfirstpoint,beziercollider.transform.position+(vector3)beziercollider.firstpoint); handles.drawline(beziercollider.transform.position+(vector3)beziercollider.handlersecondpoint,beziercollider.transform.position+(vector3)beziercollider.secondpoint); beziercollider.firstpoint = handles.freemovehandle(beziercollider.transform.position+((vector3)beziercollider.firstpoint),quaternion.identity,0.04f*handleutility.gethandlesize(beziercollider.transform.position+((vector3)beziercollider.firstpoint)),vector3.zero,handles.dotcap) - beziercollider.transform.position; beziercollider.secondpoint = handles.freemovehandle(beziercollider.transform.position+((vector3)beziercollider.secondpoint),quaternion.identity,0.04f*handleutility.gethandlesize(beziercollider.transform.position+((vector3)beziercollider.secondpoint)),vector3.zero,handles.dotcap) - beziercollider.transform.position; beziercollider.handlerfirstpoint = handles.freemovehandle(beziercollider.transform.position+((vector3)beziercollider.handlerfirstpoint),quaternion.identity,0.04f*handleutility.gethandlesize(beziercollider.transform.position+((vector3)beziercollider.handlerfirstpoint)),vector3.zero,handles.dotcap) - beziercollider.transform.position; beziercollider.handlersecondpoint = handles.freemovehandle(beziercollider.transform.position+((vector3)beziercollider.handlersecondpoint),quaternion.identity,0.04f*handleutility.gethandlesize(beziercollider.transform.position+((vector3)beziercollider.handlersecondpoint)),vector3.zero,handles.dotcap) - beziercollider.transform.position; if (gui.changed) { editorutility.setdirty (target); } } } }
enjoy it.
Comments
Post a Comment