Example #1
0
    /// <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);
    }
Example #2
0
        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);
            }
        }
Example #3
0
        /// <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);
        }
Example #6
0
    /// <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();
        // ------------ 一:结束垂直画盒子 ------------
    }