/// <summary> /// 创建一个环形复合对撞机游戏对象 /// </summary> public GameObject CreateRing(PivotAxis pivotAxis, int sides, float outerRadius, float innerRadius, float height, float rotationOffset) { // 空的游戏对象,将作为环形碰撞盒的根 var compoundCollider = new GameObject("环形碰撞盒"); var length = 2 * outerRadius * Mathf.Tan(Mathf.PI / sides); var width = outerRadius - innerRadius; for (var i = 1; i <= sides; i++) { var segment = new GameObject { name = "Bevel Box " + "(" + i + ")" }; segment.AddComponent <BoxCollider>(); var collider = segment.GetComponent <BoxCollider>(); // collider.isTrigger = true; collider.size = new Vector3(length, height, width); // 设置比例(项目里父物体的localScale都为1) segment.transform.localScale = Vector3.one; //注释该行,让 Box 的 localScale 和 BoxCollider 的 size 交换,保证与项目规定统一,要不加完环形碰撞盒后,在Scene场景里会看到碰撞盒被放大 //segment.transform.localScale= new Vector3(Length, Height, width); // 应用纵向旋转 segment.transform.Rotate(Vector3.right, rotationOffset); var segmentAngleDegrees = i * (360f / sides); // 相对于父物体的位置 segment.transform.position = new Vector3(0f, 0f, outerRadius - (width / 2)); segment.transform.RotateAround(Vector3.zero, Vector3.up, segmentAngleDegrees); // 旋转默认为Y,所以如果Y则跳过此步骤 if (pivotAxis != PivotAxis.Y) { var rotationAxis = (pivotAxis == PivotAxis.Z) ? Vector3.right : Vector3.forward; segment.transform.RotateAround(Vector3.zero, rotationAxis, 90f); } // 以"环形碰撞盒"为父物体 segment.transform.SetParent(compoundCollider.transform, true); } Undo.RegisterCreatedObjectUndo(compoundCollider, "Create Torus Compound Collider"); return(compoundCollider); }
void DrawRingGUI() { // Store distance of inner from outer radius to lock distance if enabled var radiusDiff = outerRadius - innerRadius; GUILayout.Label("Ring", EditorStyles.boldLabel); pivotAxis = (PivotAxis)EditorGUILayout.EnumPopup("Pivot Axis", pivotAxis); segments = EditorGUILayout.IntSlider("Sides", segments, 3, 64); outerRadius = Mathf.Max(EditorGUILayout.FloatField("Outer Radius", outerRadius), 0.011f); // 0.011-Infinity EditorGUILayout.BeginHorizontal(); if (lockInnerRadiusToOuter) { GUI.enabled = false; } innerRadius = Mathf.Clamp(EditorGUILayout.FloatField("Inner Radius", innerRadius), 0.01f, outerRadius - 0.01f); // 0.01-(outerRadius - 0.01) GUI.enabled = true; lockInnerRadiusToOuter = GUILayout.Toggle(lockInnerRadiusToOuter, new GUIContent("Lock", "Locks inner radius value to current distance from outer radius."), "Button", GUILayout.MaxWidth(50f)); EditorGUILayout.EndHorizontal(); // Lock innerRadius to current distance from outerRadius if (lockInnerRadiusToOuter) { innerRadius = Mathf.Max(0.1f, outerRadius - radiusDiff); } colliderShape = (ColliderShape) EditorGUILayout.EnumPopup(new GUIContent("Collider Shape", "Sets the shape of the sub-collider objects."), colliderShape); // Options for box collider only if (colliderShape == ColliderShape.Box) { EditorGUILayout.Separator(); matchHeightToWidth = EditorGUILayout.Toggle( new GUIContent("Match Height to Width", "Lock height to Outer Radius minus Inner Radius."), matchHeightToWidth); if (matchHeightToWidth) { GUI.enabled = false; } height = Mathf.Max(EditorGUILayout.FloatField("Height", height), 0.01f); // 0.01-Infinity GUI.enabled = true; hasEndCap = EditorGUILayout.Toggle( new GUIContent("Cap Bottom", "Adds a cylindrical cap to the bottom end of the ring, creating a barrel shape."), hasEndCap); EditorGUILayout.Separator(); rotationOffset = EditorGUILayout.Slider( new GUIContent("Rotation", "Apply rotation to sub-colliders around their length-wise axis."), rotationOffset, 0f, 360f); } }
/// <summary> /// Creates a ring-shaped compound collider game object. /// </summary> public static GameObject CreateRing(PivotAxis pivotAxis, int sides, float outerRadius, float innerRadius, ColliderShape colliderShape, float height, float rotationOffset, bool hasEndCap) { // Empty game object that will serve as the root of the compound collider "prefab" var compoundCollider = new GameObject("Ring Compound Collider"); float length = 2 * outerRadius * Mathf.Tan(Mathf.PI / sides); // Length follows the flow of the ring of the torus float width = outerRadius - innerRadius; if (colliderShape.Equals(ColliderShape.Capsule)) { // Capsule length needs to be adjusted to factor in spherical caps length = (length / outerRadius * ((outerRadius + innerRadius) / 2)) + (width); } for (int i = 0; i < sides; i++) { // Create the new collider object GameObject segment = null; if (colliderShape.Equals(ColliderShape.Box)) { segment = GameObject.CreatePrimitive(PrimitiveType.Cube); segment.transform.localScale = new Vector3(length, height, width); // Set scale segment.transform.Rotate(Vector3.right, rotationOffset); // Apply lengthwise rotation // Set the renderer material on the segment object segment.GetComponent <Renderer>().material = colliderMaterial; } else if (colliderShape.Equals(ColliderShape.Capsule)) { // Create segment game object and set its position segment = new GameObject("Capsule"); // Add CapsuleCollider component var capsuleCollider = segment.AddComponent <CapsuleCollider>(); // Turn capsule so it lies length-wise along the X-axis capsuleCollider.direction = 0; capsuleCollider.height = length; capsuleCollider.radius = width / 2; } float segmentAngleDegrees = i * (360f / sides); // Position the segment relative to its parent segment.transform.position = new Vector3(0f, 0f, outerRadius - (width / 2)); segment.transform.RotateAround(Vector3.zero, Vector3.up, segmentAngleDegrees); // Rotate to matcb pivot axis if (pivotAxis != PivotAxis.Y) // We do Y by default so skip this step if Y { Vector3 rotationAxis = (pivotAxis == PivotAxis.Z) ? Vector3.right : Vector3.forward; segment.transform.RotateAround(Vector3.zero, rotationAxis, 90f); } // Set the segment parent to the compound collider GameObject segment.transform.SetParent(compoundCollider.transform, true); } // Add the cap if enabled if (hasEndCap) { var capObject = CreateCylinderPrimitive(sides, outerRadius, width); // Position the cap on the bottom of the tube capObject.transform.position = new Vector3(0f, -((height / 2) + width / 2), 0f); // Set the cap's parent to the compound collider GameObject capObject.transform.SetParent(compoundCollider.transform, true); // Set the renderer material on the segment object capObject.GetComponent <Renderer>().material = colliderMaterial; } // Register undo event for creation of compound collider Undo.RegisterCreatedObjectUndo(compoundCollider, "Create Torus Compound Collider"); return(compoundCollider); }
public static void AddDataValueLabel(SpreadsheetDocument document, WorksheetPart sheet, PivotAxis axis) { PivotTablePart pivotTablePart = sheet.GetPartsOfType<PivotTablePart>().First(); XDocument pivotTable = pivotTablePart.GetXDocument(); switch (axis) { case PivotAxis.Column: // Add to colFields { XElement fields = pivotTable.Element(S.pivotTableDefinition).Element(S.colFields); if (fields == null) { fields = new XElement(S.colFields, new XAttribute(NoNamespace.count, 0)); XElement rowFields = pivotTable.Element(S.pivotTableDefinition).Element(S.rowFields); if (rowFields == null) pivotTable.Element(S.pivotTableDefinition).Element(S.pivotFields).AddAfterSelf(fields); else rowFields.AddAfterSelf(fields); } fields.Add(new XElement(S.field, new XAttribute(NoNamespace.x, -2))); fields.Attribute(NoNamespace.count).Value = fields.Elements(S.field).Count().ToString(); } break; case PivotAxis.Row: // Add to rowFields { XElement fields = pivotTable.Element(S.pivotTableDefinition).Element(S.rowFields); if (fields == null) { fields = new XElement(S.rowFields, new XAttribute(NoNamespace.count, 0)); pivotTable.Element(S.pivotTableDefinition).Element(S.pivotFields).AddAfterSelf(fields); } fields.Add(new XElement(S.field, new XAttribute(NoNamespace.x, -2))); fields.Attribute(NoNamespace.count).Value = fields.Elements(S.field).Count().ToString(); } break; case PivotAxis.Page: // Add to pageFields { XElement fields = pivotTable.Element(S.pivotTableDefinition).Element(S.pageFields); if (fields == null) { fields = new XElement(S.pageFields, new XAttribute(NoNamespace.count, 0)); XElement prev = pivotTable.Element(S.pivotTableDefinition).Element(S.colFields); if (prev == null) prev = pivotTable.Element(S.pivotTableDefinition).Element(S.rowFields); if (prev == null) pivotTable.Element(S.pivotTableDefinition).Element(S.pivotFields).AddAfterSelf(fields); else prev.AddAfterSelf(fields); } fields.Add(new XElement(S.pageField, new XAttribute(NoNamespace.fld, -2))); fields.Attribute(NoNamespace.count).Value = fields.Elements(S.field).Count().ToString(); } break; } pivotTablePart.PutXDocument(); PivotTableCacheDefinitionPart cacheDefPart = pivotTablePart.GetPartsOfType<PivotTableCacheDefinitionPart>().First(); ForcePivotRefresh(cacheDefPart); }
public static void AddPivotAxis(SpreadsheetDocument document, WorksheetPart sheet, string fieldName, PivotAxis axis) { // Create indexed items in cache and definition PivotTablePart pivotTablePart = sheet.GetPartsOfType<PivotTablePart>().First(); PivotTableCacheDefinitionPart cacheDefPart = pivotTablePart.GetPartsOfType<PivotTableCacheDefinitionPart>().First(); PivotTableCacheRecordsPart recordsPart = cacheDefPart.GetPartsOfType<PivotTableCacheRecordsPart>().First(); XDocument cacheDef = cacheDefPart.GetXDocument(); int index = Array.FindIndex(cacheDef.Descendants(S.cacheField).ToArray(), z => z.Attribute(NoNamespace.name).Value == fieldName); XDocument records = recordsPart.GetXDocument(); List<XElement> values = new List<XElement>(); foreach (XElement rec in records.Descendants(S.r)) { XElement val = rec.Elements().Skip(index).First(); int x = Array.FindIndex(values.ToArray(), z => XElement.DeepEquals(z, val)); if (x == -1) { values.Add(val); x = values.Count() - 1; } val.ReplaceWith(new XElement(S.x, new XAttribute(NoNamespace.v, x))); } XElement sharedItems = cacheDef.Descendants(S.cacheField).Skip(index).First().Element(S.sharedItems); sharedItems.Add(new XAttribute(NoNamespace.count, values.Count()), values); recordsPart.PutXDocument(); cacheDefPart.PutXDocument(); // Add axis definition to pivot table field XDocument pivotTable = pivotTablePart.GetXDocument(); XElement pivotField = pivotTable.Descendants(S.pivotField).Skip(index).First(); XElement items = new XElement(S.items, new XAttribute(NoNamespace.count, values.Count() + 1), values.OrderBy(z => z.Attribute(NoNamespace.v).Value).Select(z => new XElement(S.item, new XAttribute(NoNamespace.x, Array.FindIndex(values.ToArray(), a => a.Attribute(NoNamespace.v).Value == z.Attribute(NoNamespace.v).Value))))); items.Add(new XElement(S.item, new XAttribute(NoNamespace.t, "default"))); switch (axis) { case PivotAxis.Column: pivotField.Add(new XAttribute(NoNamespace.axis, "axisCol"), items); // Add to colFields { XElement fields = pivotTable.Element(S.pivotTableDefinition).Element(S.colFields); if (fields == null) { fields = new XElement(S.colFields, new XAttribute(NoNamespace.count, 0)); XElement rowFields = pivotTable.Element(S.pivotTableDefinition).Element(S.rowFields); if (rowFields == null) pivotTable.Element(S.pivotTableDefinition).Element(S.pivotFields).AddAfterSelf(fields); else rowFields.AddAfterSelf(fields); } fields.Add(new XElement(S.field, new XAttribute(NoNamespace.x, index))); fields.Attribute(NoNamespace.count).Value = fields.Elements(S.field).Count().ToString(); } break; case PivotAxis.Row: pivotField.Add(new XAttribute(NoNamespace.axis, "axisRow"), items); // Add to rowFields { XElement fields = pivotTable.Element(S.pivotTableDefinition).Element(S.rowFields); if (fields == null) { fields = new XElement(S.rowFields, new XAttribute(NoNamespace.count, 0)); pivotTable.Element(S.pivotTableDefinition).Element(S.pivotFields).AddAfterSelf(fields); } fields.Add(new XElement(S.field, new XAttribute(NoNamespace.x, index))); fields.Attribute(NoNamespace.count).Value = fields.Elements(S.field).Count().ToString(); } break; case PivotAxis.Page: pivotField.Add(new XAttribute(NoNamespace.axis, "axisPage"), items); // Add to pageFields { XElement fields = pivotTable.Element(S.pivotTableDefinition).Element(S.pageFields); if (fields == null) { fields = new XElement(S.pageFields, new XAttribute(NoNamespace.count, 0)); XElement prev = pivotTable.Element(S.pivotTableDefinition).Element(S.colFields); if (prev == null) prev = pivotTable.Element(S.pivotTableDefinition).Element(S.rowFields); if (prev == null) pivotTable.Element(S.pivotTableDefinition).Element(S.pivotFields).AddAfterSelf(fields); else prev.AddAfterSelf(fields); } fields.Add(new XElement(S.pageField, new XAttribute(NoNamespace.fld, index))); fields.Attribute(NoNamespace.count).Value = fields.Elements(S.field).Count().ToString(); } break; } pivotTablePart.PutXDocument(); ForcePivotRefresh(cacheDefPart); }
/// <summary> /// 绘制环形碰撞盒GUI /// </summary> public void DrawRingBoxCollGui() { var style = new GUIStyle { normal = { textColor = Color.blue }, fontSize = 20 }; // 如果启用,将内半径与外半径的距离存储到锁定距离 var radiusDiff = OuterRadius - InnerRadius; GUILayout.Label("一:克隆环形类的碰撞盒", style); //------------一:开始垂直画盒子------------ GUILayout.BeginVertical("box"); // 第一组垂直排版开始 EditorGUILayout.BeginVertical(); GUILayout.Label("Tips:轴心、对称中心 同步下方的《自定义操作碰撞盒》"); GUILayout.Space(3); // 选择轴心 PivotAxis = (PivotAxis)EditorGUILayout.EnumPopup("1:轴心", PivotAxis); GUILayout.Space(3); // 选择对称中心 SelfRoundPivotAxis = EditorGUILayout.Vector3Field("2:对称中心(默认原点)", SelfRoundPivotAxis); GUILayout.Space(3); if (GUILayout.Button("选择对象,设置对称中心")) { SetMyPivot(); } GUILayout.Space(3); // 设置边数,最小3,最大64 BoxCollNumGenerate = EditorGUILayout.IntSlider("3:设置边数", BoxCollNumGenerate, 3, 64); GUILayout.Space(3); // 外半径(从指定外半径的值到无穷大。0.011f,无穷大) OuterRadius = Mathf.Max(EditorGUILayout.FloatField("4:外半径", OuterRadius), 0.011f); EditorGUILayout.EndVertical(); // 第一组垂直排版结束 GUILayout.Space(3); // 第二组水平排版开始 EditorGUILayout.BeginHorizontal(); if (IsLockInnerRadius) { GUI.enabled = false; } // 内半径(最小0.01,最大值要小于外半径-0.01) InnerRadius = Mathf.Clamp(EditorGUILayout.FloatField("内半径", InnerRadius), 0.01f, OuterRadius - 0.01f); GUI.enabled = true; // 锁 IsLockInnerRadius = GUILayout.Toggle(IsLockInnerRadius, new GUIContent("锁内半径", "将内半径值锁定到距外半径的当前距离"), "Button"); GUILayout.MaxWidth(50f); EditorGUILayout.EndHorizontal(); // 第二组水平排版结束 // 锁定内外半径间的距离 if (IsLockInnerRadius) { InnerRadius = Mathf.Max(0.1f, OuterRadius - radiusDiff); } // 碰撞盒高度从0.01到无穷大 Height = Mathf.Max(EditorGUILayout.FloatField("手动调整碰撞盒高度", Height), 0.01f); GUI.enabled = true; GUILayout.EndVertical(); //------------一:结束垂直画盒子------------ // ------------ 一:开始垂直画盒子 ------------ GUILayout.BeginVertical("box"); GUILayout.Label("快捷设置数据", SetGuiStyle(Color.red, 16)); GUILayout.Space(3); // 第一组水平排版开始 EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("轮架")) { // 轮架数据 length=0.8,limit勾选 // 小圆洞的 length=0.8-0.18=0.72,limit不勾选 OuterRadius = 0.208f; // 丰满数据:0.24f InnerRadius = 0.16f; Height = 0.71f; ChoseQuickData = "轮架"; } if (GUILayout.Button("小圆棍")) { OuterRadius = 0.14f; InnerRadius = 0.01f; Height = 0.79f; // 1.58 ChoseQuickData = "小圆棍"; } if (GUILayout.Button("插槽")) { OuterRadius = 0.3f; InnerRadius = 0.245f; Height = 0.79f; ChoseQuickData = "插槽"; } EditorGUILayout.EndHorizontal(); // 第一组水平排版结束 // 第二组水平排版开始 EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("厚轮架格挡")) { OuterRadius = 0.27f; // 丰满数据:0.28f InnerRadius = 0.01f; Height = 0.15f; ChoseQuickData = "厚轮架格挡"; } if (GUILayout.Button("薄轮架格挡")) { OuterRadius = 0.27f; // 丰满数据:0.28f InnerRadius = 0.01f; Height = 0.075f; ChoseQuickData = "薄轮架格挡"; } if (GUILayout.Button("圆洞")) { OuterRadius = 0.35f; InnerRadius = 0.31f; Height = 0.79f; ChoseQuickData = "圆洞"; // 其它匹配数据 //一:0.29 0.23 二:0.37 0.23 } EditorGUILayout.EndHorizontal(); // 第二组水平排版结束 GUILayout.Space(3); // 第N组水平排版开始 EditorGUILayout.BeginHorizontal(); GUILayout.Label("提示:当前所选快捷数据是", SetGuiStyle(Color.black, 14)); GUILayout.TextField(ChoseQuickData); EditorGUILayout.EndHorizontal(); // 第N组水平排版结束 GUILayout.EndVertical(); // ------------ 一:结束垂直画盒子 ------------ }