using System.Collections.Generic; using UnityEngine; using Object = UnityEngine.Object; //============================================================ //支持中文,文件使用UTF-8编码 //@author JiphuTzu //@create 20220910 //@company Umawerse // //@description: //============================================================ namespace Umawerse.FiniteStateMachines { public class PolygonDrawState : DrawingState { private Mesh _mesh; private LineRenderer _line; public PolygonDrawState(ToolsBootstrap root) : base(root, StateName.polygon, 3, 99) { } protected override void OnTap(Vector3 pos) { AddPoint(pos); } protected override void OnDoubleTap(Vector3 pos) { AddPoint(pos); } protected override void UpdatePreview(Vector3 pos) { var verts = new List(); verts.AddRange(vertices); verts.Add(pos); Show(verts); } public override void Init() { base.Init(); _mesh = new Mesh(); target.AddComponent().mesh = _mesh; var renderer = target.AddComponent(); renderer.material = root.ployMaterial; renderer.material.color = Color.green; // var mr = new GameObject("LineRender"); mr.transform.SetParent(target.transform); _line = mr.AddComponent(); _line.sortingOrder = -1; _line.startWidth = 0.3f; _line.endWidth = 0.3f; _line.numCornerVertices = 3; _line.material = root.solidLineMaterial; _line.material.color = Color.green; } public override void Complete() { Show(vertices); var mc = target.AddComponent(); //var label = Object.Instantiate(root.labelPrefab, target.transform); //label.Init($"面积:", false); //label.SetPosition(mc.bounds.center + Vector3.up); //label.SetAlignment(); } public override void AddPoint(Vector3 position, bool showImmediately = true) { vertices.Add(position); if (showImmediately) { var h = vertices[0].y > position.y ? vertices[0].y : position.y; for (var i = 0; i < vertices.Count; i++) { var v = vertices[i]; v.y = h; vertices[i] = v; if (i + 1 < target.transform.childCount) target.transform.GetChild(i + 1).position = v; } } var ployPoint = Object.Instantiate(root.ployPointPrefab, target.transform); ployPoint.transform.localPosition = vertices[vertices.Count - 1]; var mr = ployPoint.GetComponent(); mr.material.SetColor(COLOR_ID, Color.green); mr.sortingOrder = 2; if (vertices.Count < 3 || !showImmediately) return; Show(vertices); } private void Show(List verts) { var triangles = new List(); for (var i = 2; i < verts.Count; i++) { triangles.Add(0); if (IsUp(verts[i] - verts[0], verts[i - 1] - verts[0])) { triangles.Add(i); triangles.Add(i - 1); } else { triangles.Add(i - 1); triangles.Add(i); } } _mesh.vertices = verts.ToArray(); _mesh.triangles = triangles.ToArray(); // var vs = new Vector3[verts.Count + 1]; verts.CopyTo(vs); vs[vs.Length - 1] = vs[0]; _line.positionCount = vs.Length; _line.SetPositions(vs); _line.material.SetFloat("_Cnt", GetLength(vs) / 3); } private bool IsUp(Vector3 a, Vector3 b) { var nor = Vector3.Cross(a, b); var angle = Vector3.Dot(nor, Vector3.up); return angle > 0; } private float GetLength(Vector3[] verts) { var length = 0f; for (var i = 1; i < verts.Length; i++) { length += Vector3.Distance(verts[i], verts[i - 1]); } return length; } } }