Github
一応はWYSIWYGと言えるかも.
要望次第で, Polygon Collider 2Dの編集インターフェイスと同じにするかもしれません.
タイルベースのレンダリングプロセスには, 扇形は細長い三角形を生成しがちなので良くない.
足りなければ考える.
Nexus4で実行.
original UnityEngine.UI.Image
---------------------------------------- Android Unity internal profiler stats: cpu-player> min: 22.9 max: 103.2 avg: 76.4 cpu-ogles-drv> min: 0.0 max: 0.0 avg: 0.0 gpu> min: 0.0 max: 0.0 avg: 0.0 cpu-present> min: 0.0 max: 24.5 avg: 0.6 frametime> min: 44.5 max: 103.2 avg: 77.0 batches> min: 4 max: 4 avg: 4 draw calls> min: 4 max: 4 avg: 4 tris> min: 1324 max: 1324 avg: 1324 verts> min: 2632 max: 2632 avg: 2632 dynamic batching> batched draw calls: 0 batches: 0 tris: 0 verts: 0 static batching> batched draw calls: 0 batches: 0 tris: 0 verts: 0 player-detail> physx: 5.1 animation: 0.0 culling 0.0 skinning: 0.0 batching: 0.0 render: 5.3 fixed-update-count: 2 .. 5 managed-scripts> update: 11.0 fixedUpdate: 0.0 coroutines: 0.0 managed-memory> used heap: 2334720 allocated heap: 2928640, max number of collections: 0 collection total duration: 0.0
Utility.PolygonalImage2D
約2倍の頂点数で, 描画ピクセル数は80%ぐらい?
---------------------------------------- Android Unity internal profiler stats: cpu-player> min: 28.9 max: 81.2 avg: 56.6 cpu-ogles-drv> min: 0.0 max: 0.0 avg: 0.0 gpu> min: 0.0 max: 0.0 avg: 0.0 cpu-present> min: 0.0 max: 4.0 avg: 0.2 frametime> min: 28.9 max: 81.9 avg: 56.7 batches> min: 4 max: 4 avg: 4 draw calls> min: 4 max: 4 avg: 4 tris> min: 3888 max: 3888 avg: 3888 verts> min: 5200 max: 5200 avg: 5200 dynamic batching> batched draw calls: 0 batches: 0 tris: 0 verts: 0 static batching> batched draw calls: 0 batches: 0 tris: 0 verts: 0 player-detail> physx: 3.0 animation: 0.0 culling 0.0 skinning: 0.0 batching: 0.0 render: 5.0 fixed-update-count: 1 .. 4 managed-scripts> update: 9.8 fixedUpdate: 0.0 coroutines: 0.0 managed-memory> used heap: 2199552 allocated heap: 2928640, max number of collections: 0 collection total duration: 0.0
namespace LUtil { [RequireComponent(typeof(CanvasRenderer)), ExecuteInEditMode] public class PolygonalImage2D : UnityEngine.UI.Image { public Vector2[] points_; protected override void Awake() { base.Awake(); if(null == points_){ resetPoints(); } } private static Vector2 calcUV(RectTransform rectTrans, Sprite sprite, Vector2 position) { Rect rect = rectTrans.rect; Vector2 uv = new Vector2(position.x - rect.xMin, position.y-rect.yMin); if(1.0e-4f < rect.width) { uv.x /= rect.width; } if(1.0e-4f < rect.height) { uv.y /= rect.height; } return uv; } public void resetPointsSmaller() { RectTransform rectTrans = GetComponent<RectTransform>(); Rect rect = rectTrans.rect; points_ = new Vector2[4]; float w = rect.width * 0.05f; float h = rect.height * 0.05f; points_[0] = new Vector2(rect.xMin+w, rect.yMax-h); points_[1] = new Vector2(rect.xMax-w, rect.yMax-h); points_[2] = new Vector2(rect.xMax-w, rect.yMin+h); points_[3] = new Vector2(rect.xMin+w, rect.yMin+h); } public void resetPoints() { RectTransform rectTrans = GetComponent<RectTransform>(); points_ = new Vector2[4]; points_[0] = new Vector2(rectTrans.rect.xMin, rectTrans.rect.yMax); points_[1] = new Vector2(rectTrans.rect.xMax, rectTrans.rect.yMax); points_[2] = new Vector2(rectTrans.rect.xMax, rectTrans.rect.yMin); points_[3] = new Vector2(rectTrans.rect.xMin, rectTrans.rect.yMin); } protected override void OnPopulateMesh(UnityEngine.UI.VertexHelper toFill) { if(null == points_) { resetPoints(); } if(points_.Length < 3) { return; } int numPoints = points_.Length; RectTransform rectTrans = GetComponent<RectTransform>(); UIVertex vertex = new UIVertex(); Vector2 localOffset; localOffset.x = rectTrans.pivot.x * rectTrans.rect.width; localOffset.y = rectTrans.pivot.y * rectTrans.rect.height; Vector2 isize; Vector2 local; toFill.Clear(); if(null == sprite) { isize.x = (1.0e-4f < rectTrans.rect.width) ? 1.0f / rectTrans.rect.width : 1.0f; isize.y = (1.0e-4f < rectTrans.rect.height) ? 1.0f / rectTrans.rect.height : 1.0f; for(int i = 0; i < numPoints; ++i) { vertex.position = points_[i]; vertex.color = this.color; local = points_[i] + localOffset; vertex.uv0.x = (local.x) * isize.x; vertex.uv0.y = (local.y) * isize.y; toFill.AddVert(vertex); } for(int i = 2; i < numPoints; ++i) { toFill.AddTriangle(0, i - 1, i); } return; } //Debug.Log("OnPopulateMesh:" + gameObject.name + " " + sprite.packed); isize.x = (1 < sprite.texture.width) ? 1.0f / sprite.texture.width : 1.0f; isize.y = (1 < sprite.texture.height) ? 1.0f / sprite.texture.height : 1.0f; Vector2 localToSprite; localToSprite.x = sprite.rect.width/rectTrans.rect.width; localToSprite.y = sprite.rect.height/rectTrans.rect.height; //Debug.Log("sprite.packed " + sprite.packed); //Debug.Log("sprite.textureRectOffset " + sprite.textureRectOffset); //Debug.Log("sprite.textureRect " + sprite.textureRect); //Debug.Log("sprite.rect " + sprite.rect); //Debug.Log("sprite.pivot " + sprite.pivot); //Debug.Log("RectTransform.rect " + rectTrans.rect); //Debug.Log("RectTransform.pivot " + rectTrans.pivot); if(sprite.packed) { localOffset.x += sprite.textureRect.xMin; localOffset.y += sprite.textureRect.yMin; for(int i = 0; i < numPoints; ++i) { vertex.position = points_[i]; vertex.color = this.color; local = points_[i] + localOffset; local.x *= localToSprite.x; local.y *= localToSprite.y; vertex.uv0.x = (local.x) * isize.x; vertex.uv0.y = (local.y) * isize.y; toFill.AddVert(vertex); } } else { for(int i = 0; i < numPoints; ++i) { vertex.position = points_[i]; vertex.color = this.color; local = points_[i] + localOffset; local.x *= localToSprite.x; local.y *= localToSprite.y; vertex.uv0.x = (local.x) * isize.x; vertex.uv0.y = (local.y) * isize.y; toFill.AddVert(vertex); } } for(int i = 2; i < numPoints; ++i) { toFill.AddTriangle(0, i-1, i); } } // Implements ICanvasRaycastFilter public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) { if(!RectTransformUtility.RectangleContainsScreenPoint(rectTransform, screenPoint, eventCamera)) { return true; } Vector2 localPoint; if(!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, eventCamera, out localPoint)){ return false; } int i0=points_.Length-1, i1=0; bool yflag0 = (localPoint.y <= points_[i0].y); bool flag = false; for(; i1<points_.Length; i0=i1, ++i1) { bool yflag1 = (localPoint.y <= points_[i1].y); if(yflag0 != yflag1) { if(((localPoint.x-points_[i0].x)*(points_[i1].y - points_[i0].y) <= (points_[i1].x - points_[i0].x) * (localPoint.y - points_[i0].y)) == yflag1) { flag = !flag; } } yflag0 = yflag1; }//for(; i1 return flag; } } }
0 件のコメント:
コメントを投稿