简体   繁体   中英

How to copy points from a PolygonCollider2D into a Vector2[]?

I'm making a ScriptableObject to store settings for a prefab, so I can spawn it, and set things such as the points of a PolygonCollider2D . This is a way to create many similar objects, and not have to create each one as a prefab or prefab variant.

The points seems to be in an array called Paths, then in each element of that, is an array called Element 0, which has Vector2's. My collider will always have only one path, so I'd like to copy that list and paste it into the Scriptable Object Asset which has an array of Vector2: public Vector2[] points;

I can easily copy between PolygonCollider2D's by right clicking Points, and choose copy and then paste into another collider. If I paste this into a text editor, I get this:

GenericPropertyJSON:{"name":"m_Points","type":-1,"children":[{"name":"m_Paths","type":-1,"arraySize":1,"arrayType":"vector","children":[{"name":"Array","type":-1,"arraySize":1,"arrayType":"vector","children":[{"name":"size","type":12,"val":1},{"name":"data","type":-1,"arraySize":8,"arrayType":"Vector2","children":[{"name":"Array","type":-1,"arraySize":8,"arrayType":"Vector2","children":[{"name":"size","type":12,"val":8},{"name":"data","type":8,"children":[{"name":"x","type":2,"val":0.067855835},{"name":"y","type":2,"val":-1.4540863}]},{"name":"data","type":8,"children":[{"name":"x","type":2,"val":1.38775635},{"name":"y","type":2,"val":-0.6495056}]},{"name":"data","type":8,"children":[{"name":"x","type":2,"val":1.77092743},{"name":"y","type":2,"val":1.06118774}]},{"name":"data","type":8,"children":[{"name":"x","type":2,"val":1.6979599},{"name":"y","type":2,"val":1.639801}]},{"name":"data","type":8,"children":[{"name":"x","type":2,"val":0.271110535},{"name":"y","type":2,"val":1.63804626}]},{"name":"data","type":8,"children":[{"name":"x","type":2,"val":-1.778122},{"name":"y","type":2,"val":0.559341431}]},{"name":"data","type":8,"children":[{"name":"x","type":2,"val":-1.65858459},{"name":"y","type":2,"val":-1.3278656}]},{"name":"data","type":8,"children":[{"name":"x","type":2,"val":-0.930610657},{"name":"y","type":2,"val":-1.62702942}]}]}]}]}]}]}

But I can't figure out how to make a field in the SO that I can paste this data into.

When I look at the source for PolygonCollider2D the comment mentions corner points, and I don't know if the comment is wrong, but I don't see the GetPoints_Binding anywhere in the source either.

/// <summary>
///   <para>Corner points that define the collider's shape in local space.</para>
/// </summary>
/// <footer><a href="https://docs.unity3d.com/2020.3/Documentation/ScriptReference/30_search.html?q=PolygonCollider2D-points">`PolygonCollider2D.points` on docs.unity3d.com</a></footer>
    public extern Vector2[] points { [NativeMethod("GetPoints_Binding"), MethodImpl(MethodImplOptions.InternalCall)] get; [NativeMethod("SetPoints_Binding"), MethodImpl(MethodImplOptions.InternalCall)] set; }

Any ideas how to solve how to copy/paste these?

PolygonCollider2D

自定义脚本对象

I solved it by adding this to the ScriptableObject, so I could copy the points by assigning the collider. It uses Odin for the button.

Hope it helps someone with this same unusual problem:)

    [ShowInInspector] 
    private PolygonCollider2D colliderToCopyFrom;
    
    [Button] 
    private void CopyPoints() {
        points = new Vector2[colliderToCopyFrom.points.Length];
        Array.Copy(colliderToCopyFrom.points, points, colliderToCopyFrom.points.Length);
    }

The JSON you get there is a special utility Unity provides for copying the values via the Inspector within the Unity Editor. It is specific to exactly this component type and is a representation of the private serialized fields you can't directly access via the API but only the inspector.


However, since you go by code anyway there is no need to do what you do at all.

Vector2 is a struct so a value type and no need to copy them at all.

And further (as most public members in Unity) the PolygonCollider2D.points is a property which internally handles and copies the points inside the getter and setter so later changes on the array do not affect it => There is also no need at all to copy the array, and anyway it already returns only a copy.

So using

points = colliderToCopyFrom.points;

already is all you need to do.

And for assigning just the same

colliderToCopyFrom.points = someVector2Array;

Have in mind though that these points are in local space of the collider. If you need them in world space you can convert them like eg

using System.Linq;

...

worldPoints = colliderToCopyFrom.points.Select(p => colliderToCopyFrom.TransformPoint(p)).ToArray();

and the other way round

colliderToCopyFrom.points = worldPoints.Select(p => colliderToCopyFrom.InverseTransformPoint (p)).ToArray();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM