Пример #1
0
    public void OnSceneGUI()
    {
        // make sure we detect any changes in the object
        GUI.changed = false;

        Limiter limits = target as Limiter;

        // Don't show limits if the node is disabled.
        if (!limits.enabled)
        {
            return;
        }

        float minRange = limits.m_minimumRange;
        float maxRange = limits.m_maximumRange;

        if (!limits.m_limitRange)
        {
            Renderer[] renderObjects = limits.GetComponentsInChildren <Renderer>();
            Bounds     bounds        = renderObjects[0].bounds;
            for (int i = 1; i < renderObjects.Length; ++i)
            {
                bounds.Encapsulate(renderObjects[i].bounds);
            }

            minRange = bounds.size.magnitude * 1.5f;
            maxRange = minRange * 2.5f;
        }

        Matrix4x4 handlesMatrix = Handles.matrix;

        Handles.matrix = limits.transform.localToWorldMatrix;

        // ignore scaling on the matrix;
        Vector3 scale    = limits.transform.localScale;
        Vector3 invScale = new Vector3(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z);

        Handles.matrix = Handles.matrix * Matrix4x4.Scale(invScale);


        Quaternion leftRotation  = Quaternion.Euler(0.0f, limits.m_minimumHorizontalAngle, 0.0f);
        Quaternion rightRotation = Quaternion.Euler(0.0f, limits.m_maximumHorizontalAngle, 0.0f);
        Quaternion downRotation  = Quaternion.Euler(-limits.m_minimumVerticalAngle, 0.0f, 0.0f);
        Quaternion upRotation    = Quaternion.Euler(-limits.m_maximumVerticalAngle, 0.0f, 0.0f);
        Quaternion midRotoation  = Quaternion.Euler((limits.m_maximumVerticalAngle + limits.m_minimumVerticalAngle) * -0.5f, 0.0f, 0.0f);

        Vector3 leftNormal  = leftRotation * Vector3.right;
        Vector3 rightNormal = rightRotation * Vector3.right;

        Vector3 tm = upRotation * Vector3.forward;
        Vector3 tl = leftRotation * tm;
        Vector3 tr = rightRotation * tm;
        Vector3 bm = downRotation * Vector3.forward;
        Vector3 bl = leftRotation * bm;
        Vector3 br = rightRotation * bm;

        Vector3 tc = Vector3.up * Mathf.Sin(limits.m_maximumVerticalAngle * Mathf.Deg2Rad);
        Vector3 ts = leftRotation * Vector3.forward;

        Vector3 bc = Vector3.up * Mathf.Sin(limits.m_minimumVerticalAngle * Mathf.Deg2Rad);


        float horizArc = limits.m_maximumHorizontalAngle - limits.m_minimumHorizontalAngle;
        float vertArc  = limits.m_maximumVerticalAngle - limits.m_minimumVerticalAngle;

        // Draw the arcs

        Handles.DrawWireArc(Vector3.zero, leftNormal, bl, -vertArc, maxRange);
        Handles.DrawWireArc(Vector3.zero, rightNormal, br, -vertArc, maxRange);

        Handles.DrawWireArc(Vector3.zero + tc * maxRange
                            , Vector3.up
                            , ts
                            , horizArc
                            , maxRange * Mathf.Cos(limits.m_maximumVerticalAngle * Mathf.Deg2Rad));
        Handles.DrawWireArc(Vector3.zero + bc * maxRange
                            , Vector3.up
                            , ts
                            , horizArc
                            , maxRange * Mathf.Cos(limits.m_minimumVerticalAngle * Mathf.Deg2Rad));


        Handles.DrawWireArc(Vector3.zero, leftNormal, bl, -vertArc, minRange);
        Handles.DrawWireArc(Vector3.zero, rightNormal, br, -vertArc, minRange);

        Handles.DrawWireArc(Vector3.zero + tc * minRange
                            , Vector3.up
                            , ts
                            , horizArc
                            , minRange * Mathf.Cos(limits.m_maximumVerticalAngle * Mathf.Deg2Rad));
        Handles.DrawWireArc(Vector3.zero + bc * minRange
                            , Vector3.up
                            , ts
                            , horizArc
                            , minRange * Mathf.Cos(limits.m_minimumVerticalAngle * Mathf.Deg2Rad));

        Handles.DrawLine(minRange * tl, maxRange * tl);
        Handles.DrawLine(minRange * bl, maxRange * bl);
        Handles.DrawLine(minRange * tr, maxRange * tr);
        Handles.DrawLine(minRange * br, maxRange * br);

        if (limits.m_limitRange)
        {
            Handles.DrawWireArc(Vector3.zero, Vector3.right, bm, -vertArc, minRange);
            Handles.DrawWireArc(Vector3.zero, Vector3.right, bm, -vertArc, maxRange);

            // Range sliders

            Vector3 centre = Quaternion.Euler((limits.m_minimumVerticalAngle + limits.m_maximumVerticalAngle) * -0.5f, 0.0f, 0.0f) * Vector3.forward;
            limits.m_maximumRange = Mathf.Max(Handles.Slider(limits.m_maximumRange * centre, centre).magnitude, limits.m_minimumRange);
            limits.m_minimumRange = Mathf.Min(Handles.Slider(limits.m_minimumRange * centre, centre).magnitude, limits.m_maximumRange);
        }

        // angle sliders

        float   midRange    = (minRange + maxRange) * 0.5f;
        Vector3 horizCentre = Vector3.Dot(midRotoation * (Vector3.forward * midRange), Vector3.up) * Vector3.up;

        StoreOriginalAngles(limits);

        limits.m_minimumHorizontalAngle = NewHandles.AngleControl(horizCentre, Vector3.up, Vector3.forward, limits.m_minimumHorizontalAngle, midRange, NewHandles.DoubleArrowCap, true);
        limits.m_maximumHorizontalAngle = NewHandles.AngleControl(horizCentre, Vector3.up, Vector3.forward, limits.m_maximumHorizontalAngle, midRange, NewHandles.DoubleArrowCap, false);

        limits.m_minimumVerticalAngle = -NewHandles.AngleControl(Vector3.zero, Vector3.right, Vector3.forward, -limits.m_minimumVerticalAngle, maxRange, NewHandles.DoubleArrowCap, true);
        limits.m_maximumVerticalAngle = -NewHandles.AngleControl(Vector3.zero, Vector3.right, Vector3.forward, -limits.m_maximumVerticalAngle, maxRange, NewHandles.DoubleArrowCap, true);

        // Apply limits to the angles
        LimitAngles(limits);

        Handles.matrix = handlesMatrix;

        // report any changes in the object.
        if (GUI.changed)
        {
            EditorUtility.SetDirty(limits);
        }
    }