自定义展开菜单

        在android开发中应该都自定过进度条,举个个简单的例子,通过重写view 的onDraw方法可以得到一个简单的进度条:

    重写onDraw方法

        mPaint.setColor(Color.parseColor("#888888"));
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawArc(rectF,0,mDegree,true,mPaint);
  通过线程的mDegree变化可以得到一个简单的进度条

 

  上面是一个简单的进度条,通过不断重绘制作出的效果,再看看下面的

   

  这个控件是通过类似进度条的加载效果来展示出菜单,下面是通过进度条的方式山寨的一个类似控件:

    

   这个控件其实不难,要注意的就是icon的绘制和一些位置的计算。下面是代码:

package com.example.arze.momentview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by arze on 2015/12/13.
 */
public class DrawProgressView extends View {

    private Paint mPaint = new Paint();

    //保存第一圈的icon
    private List<Drawable> mFirstDrawableList = new ArrayList<>();
    //保存第二圈的icon
    private List<Drawable> mSecondDrawableList = new ArrayList<>();
    //最内部的icon
    private Drawable mMainIcon;
    // 监听
    private OnDrawClickListener mOnDrawClickListener;
    // 一些默认常量
    private static final int DEFAULT_INNER = 60;
    private static final int DEFAULT_FIRST_WIDTH = 80;
    private static final int DEFAULT_SECOND_WIDTH = 80;
    private static final int DEFAULT_FIRST_COLOR = Color.parseColor("#cacaca");
    private static final int DEFAULT_SECOND_COLOR = Color.parseColor("#888888");
    private static final int DEFAULT_INNER_COLOR = Color.parseColor("#000000");
    private static final int DEFAULT_DEGREE = 1;


    //控件的长宽
    private int mWidth;
    private int mHeight;
    //内部圆的半径
    private int mInnerCir;
    //控件的中心点
    private Point mCenterPoint;
    //第一圈的宽度
    private int mFirstWidth;
    //第一圈的位置
    private RectF mFirstRectF;
    //第二圈的宽度
    private int mSecondWidth;
    //第二圈的位置
    private RectF mSecondRectF;
    //第一圈的颜色
    private int mFirstColor;
    // 第二圈的颜色
    private int mSecondColor;
    //内部圆的颜色
    private int mInnerColor;
    //内部圆的位置
    private RectF mInnerRectF;

    //展开第一圈
    private boolean isFirst = false;
    //展开第二圈
    private boolean isSecond = false;
    //展开完第一圈并显示
    private boolean isFirstShow = false;
    //展开完第二圈并显示
    private boolean isSencondShow = false;
    //回收第一圈
    private boolean isEndFirst = false;
    //回收第二圈
    private boolean isEndSecond = false;
    // 展开第一圈是否完成
    private boolean isStartFirstStop = true;
    //展开第二圈是否完成
    private boolean isStartSecondStop = true;
    //回收第一圈是否完成
    private boolean isEndFirstStop = true;
    //回收第二圈是否完成
    private boolean isEndSecondStop = true;

    //一些角度属性
    private float mDegree = 1;
    private float mFirstDrawDegree = 0;
    private float mSecondDrawDegree = 0;

    /**
     * 接口用来设置点击事件
     */
    public interface OnDrawClickListener {
        void onClick(View view, int position, boolean isFirst, boolean isSecond, boolean isCenter);
    }

    public void setOnDrawClickListener(OnDrawClickListener listener) {
        mOnDrawClickListener = listener;
    }


    public DrawProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);

    }

    public DrawProgressView(Context context) {
        super(context);
        init(context, null, 0);
    }

    public DrawProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    /**
     * 一些属性的初始化,xml属性的获取
     *
     * @param context
     * @param attrs
     * @param defStyleAttr
     */

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        mMainIcon = getResources().getDrawable(R.drawable.main_icon);
        mFirstDrawableList.add(getResources().getDrawable(R.drawable.first_icon_0));
        mFirstDrawableList.add(getResources().getDrawable(R.drawable.first_icon_1));
        mFirstDrawableList.add(getResources().getDrawable(R.drawable.first_icon_2));
        mSecondDrawableList.add(getResources().getDrawable(R.drawable.second_icon_0));
        mSecondDrawableList.add(getResources().getDrawable(R.drawable.second_icon_1));
        mSecondDrawableList.add(getResources().getDrawable(R.drawable.second_icon_2));
        mSecondDrawableList.add(getResources().getDrawable(R.drawable.second_icon_3));

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DrawView);
        if (null != array) {
            mFirstWidth = (int) array.getDimension(R.styleable.DrawView_first_width, DEFAULT_FIRST_WIDTH);
            mFirstColor = array.getColor(R.styleable.DrawView_first_color, DEFAULT_FIRST_COLOR);
            mSecondWidth = (int) array.getDimension(R.styleable.DrawView_second_width, DEFAULT_SECOND_WIDTH);
            mSecondColor = array.getColor(R.styleable.DrawView_second_color, DEFAULT_SECOND_COLOR);
            mInnerCir = (int) array.getDimension(R.styleable.DrawView_inner_cir, DEFAULT_INNER);
            mInnerColor = array.getColor(R.styleable.DrawView_inner_color, DEFAULT_INNER_COLOR);
            mDegree = array.getInteger(R.styleable.DrawView_degree, DEFAULT_DEGREE);
            array.recycle();
        }

    }

    /**
     * 重写onMeasure
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //要绘制的长和宽为
        mWidth = mHeight = mInnerCir * 2 + mFirstWidth * 2 + mSecondWidth * 2;
        setMeasuredDimension(mWidth, mHeight);
        //中心点
        mCenterPoint = new Point(mWidth / 2, mHeight / 2);
        //位置的获取
        mInnerRectF = new RectF(
                mCenterPoint.x - mInnerCir,
                mCenterPoint.y - mInnerCir,
                mCenterPoint.x + mInnerCir,
                mCenterPoint.y + mInnerCir);
        mFirstRectF = new RectF(mCenterPoint.x - mInnerCir - mFirstWidth / 2,
                mCenterPoint.y - mInnerCir - mFirstWidth / 2,
                mCenterPoint.x + mInnerCir + mFirstWidth / 2,
                mCenterPoint.y + mInnerCir + mFirstWidth / 2);
        mSecondRectF = new RectF(mCenterPoint.x - mInnerCir - mFirstWidth - mSecondWidth / 2,
                mCenterPoint.y - mInnerCir - mFirstWidth - mSecondWidth / 2,
                mCenterPoint.x + mInnerCir + mFirstWidth + mSecondWidth / 2,
                mCenterPoint.y + mInnerCir + mFirstWidth + mSecondWidth / 2);


    }

    /**
     * 通过角度,宽度,icon在画布的特定位置绘制出icon
     *
     * @param canvas
     * @param degree
     * @param width
     * @param drawable
     */

    private void drawDrawable(Canvas canvas, float degree, int width, Drawable drawable) {
        int x = (int) (Math.cos(degree / 180 * Math.PI) * width);
        int y = (int) (Math.sin(degree / 180 * Math.PI) * width);
        Point point = new Point(mCenterPoint.x + x, mCenterPoint.y + y);
        drawable.setBounds(
                point.x - drawable.getIntrinsicWidth() / 2,
                point.y - drawable.getIntrinsicHeight() / 2,
                point.x + drawable.getIntrinsicWidth() / 2,
                point.y + drawable.getIntrinsicHeight() / 2);
        drawable.draw(canvas);
    }

    /**
     * 重写onDraw
     *
     * @param canvas
     */

    @Override
    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);
        mPaint.setAntiAlias(true);
        mPaint.setColor(mInnerColor);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawOval(mInnerRectF, mPaint);
        drawDrawable(canvas, 0, 0, mMainIcon);
        mPaint.setStrokeWidth(mFirstWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        //判断是否正在展开第一圈
        if (isFirst) {
            mPaint.setColor(mFirstColor);
            canvas.drawArc(mFirstRectF, 0, mFirstDrawDegree, false, mPaint);
            //要绘制的icon中心点到控件中心点的距离
            int width = mInnerCir + mFirstWidth / 2;
            //如果角度mFirstDrawDegree > 50开始绘制第一个icon下面相同
            if (mFirstDrawDegree > 50) {
                float degree = mFirstDrawDegree - 20;
                drawDrawable(canvas, degree, width, mFirstDrawableList.get(0));
            }

            if (mFirstDrawDegree > 170) {
                float degree = mFirstDrawDegree - 20 - 120;
                drawDrawable(canvas, degree, width, mFirstDrawableList.get(1));
            }

            if (mFirstDrawDegree > 290) {
                float degree = mFirstDrawDegree - 20 - 120 * 2;
                drawDrawable(canvas, degree, width, mFirstDrawableList.get(2));
            }
        }
        if (isSecond) {
            mPaint.setColor(mSecondColor);
            canvas.drawArc(mSecondRectF, 0, mSecondDrawDegree, false, mPaint);
            int width = mInnerCir + mFirstWidth + mSecondWidth / 2;
            if (mSecondDrawDegree > 20) {
                float degree = mSecondDrawDegree - 20;
                drawDrawable(canvas, degree, width, mSecondDrawableList.get(0));
            }
            if (mSecondDrawDegree > 110) {
                float degree = mSecondDrawDegree - 20 - 90;
                drawDrawable(canvas, degree, width, mSecondDrawableList.get(1));
            }
            if (mSecondDrawDegree > 200) {
                float degree = mSecondDrawDegree - 20 - 90 * 2;
                drawDrawable(canvas, degree, width, mSecondDrawableList.get(2));
            }
            if (mSecondDrawDegree > 290) {
                float degree = mSecondDrawDegree - 20 - 90 * 3;
                drawDrawable(canvas, degree, width, mSecondDrawableList.get(3));
            }
        }
        //在回收的时候,要判断后控件在什么时候消失就行了
        if (isEndFirst) {
            float firstEndDegree = 360 - mFirstDrawDegree;
            mPaint.setColor(mFirstColor);
            canvas.drawArc(mFirstRectF, 0, firstEndDegree, false, mPaint);
            int width = mInnerCir + mFirstWidth / 2;
            float mMenu1Degree = 30 - mFirstDrawDegree;
            float mMenu2Degree = 150 - mFirstDrawDegree;
            float mMenu0Degree = 270 - mFirstDrawDegree;
            if (mFirstDrawDegree < 30) {
                drawDrawable(canvas, mMenu1Degree, width, mFirstDrawableList.get(0));
                drawDrawable(canvas, mMenu2Degree, width, mFirstDrawableList.get(2));
                drawDrawable(canvas, mMenu0Degree, width, mFirstDrawableList.get(1));
            } else if (mFirstDrawDegree < 150) {
                drawDrawable(canvas, mMenu2Degree, width, mFirstDrawableList.get(2));
                drawDrawable(canvas, mMenu0Degree, width, mFirstDrawableList.get(1));
            } else if (mFirstDrawDegree < 270) {
                drawDrawable(canvas, mMenu0Degree, width, mFirstDrawableList.get(1));
            }
        }
        if (isEndSecond) {
            float secondEndDegree = 360 - mSecondDrawDegree;
            mPaint.setColor(mSecondColor);
            int width = mInnerCir + mFirstWidth + mSecondWidth / 2;
            canvas.drawArc(mSecondRectF, 0, secondEndDegree, false, mPaint);
            float mMenu3Degree = 0 - mSecondDrawDegree;
            float mMenu4Degree = 270 - mSecondDrawDegree;
            float mMenu5Degree = 180 - mSecondDrawDegree;
            float mMenu6Degree = 90 - mSecondDrawDegree;
            if (mSecondDrawDegree < 90) {
                drawDrawable(canvas, mMenu4Degree, width, mSecondDrawableList.get(1));
                drawDrawable(canvas, mMenu5Degree, width, mSecondDrawableList.get(2));
                drawDrawable(canvas, mMenu6Degree, width, mSecondDrawableList.get(3));
            } else if (mSecondDrawDegree < 180) {
                drawDrawable(canvas, mMenu4Degree, width, mSecondDrawableList.get(1));
                drawDrawable(canvas, mMenu5Degree, width, mSecondDrawableList.get(2));
            } else if (mSecondDrawDegree < 270) {
                drawDrawable(canvas, mMenu4Degree, width, mSecondDrawableList.get(1));
            }


        }

    }

    /**
     * 展开第一圈
     */

    public void startFirst() {
        if (isStartFirstStop) {
            isStartFirstStop = false;
            isFirst = true;
            isEndFirst = false;
            mFirstDrawDegree = 0;
            new MyFirstThread(this).start();
        }
    }

    /**
     * 展开第二圈
     */

    public void startSecond() {
        if (isStartSecondStop) {
            isStartSecondStop = false;
            isSecond = true;
            isEndSecond = false;
            mSecondDrawDegree = 0;
            if (isFirstShow())
                new MySecondThread(this).start();
        }
    }

    /**
     * 回收第一圈
     */

    public void endFirst() {
        if (isEndFirstStop) {
            isEndFirstStop = false;
            isFirst = false;
            isEndFirst = true;
            mFirstDrawDegree = 0;
            new MyFirstThreadEnd(this).start();
        }
    }

    /**
     * 回收第二圈
     */


    public void endSecond() {
        if (isEndSecondStop) {
            isEndSecondStop = false;
            isSecond = false;
            isEndSecond = true;
            mSecondDrawDegree = 0;
            new MySecondThreadEnd(this).start();
        }

    }

    /**
     * 判断点击事件
     *
     * @param event
     * @return
     */

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                int x = (int) event.getX();
                int y = (int) event.getY();
                if (isFirstShow) {
                    for (int i = 0; i < mFirstDrawableList.size(); i++) {
                        //因为在绘制icon的过程中已经将icon在控件的位置setBounds了,所以可以根据这个来判断
                        if (mFirstDrawableList.get(i).getBounds().contains(x, y)) {
                            if (null != mOnDrawClickListener)
                                //控件的位置是从绘制的第一个控件逆时针开始算,下同
                                mOnDrawClickListener.onClick(this, i, true, false, false);
                        }
                    }
                }
                if (isSencondShow) {
                    for (int i = 0; i < mSecondDrawableList.size(); i++) {
                        if (mSecondDrawableList.get(i).getBounds().contains(x, y)) {
                            if (null != mOnDrawClickListener)
                                mOnDrawClickListener.onClick(this, i, false, true, false);
                        }
                    }
                }
                //判断是否在内圆,点击的点和中心点的距离是否小于或者等于半径
                int r = (int) Math.sqrt(Math.pow(x - mCenterPoint.x, 2) + Math.pow(y - mCenterPoint.y, 2));
                if (r <= mInnerCir) {
                    if (null != mOnDrawClickListener)
                    mOnDrawClickListener.onClick(this, 0, false, false, true);
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * 展开第一圈的角度变化线程
     */
    private class MyFirstThread extends Thread {
        private WeakReference<DrawProgressView> mTarget;

        public MyFirstThread(DrawProgressView view) {
            mTarget = new WeakReference<DrawProgressView>(view);
        }

        @Override
        public void run() {
            while (!interrupted()) {
                if (null == mTarget.get())
                    break;
                if (410 == mTarget.get().mFirstDrawDegree) {
                    break;
                }
                if (180 < mTarget.get().mFirstDrawDegree) {
                    try {
                        sleep(3);
                        mTarget.get().mFirstDrawDegree += mTarget.get().mDegree;
                        mTarget.get().postInvalidate();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                } else {
                    try {
                        sleep(5);
                        mTarget.get().mFirstDrawDegree += mTarget.get().mDegree;
                        mTarget.get().postInvalidate();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            isFirstShow = true;
            isStartFirstStop = true;
        }
    }

    /**
     * 展开第二圈的角度变化线程
     */

    private class MySecondThread extends Thread {
        private WeakReference<DrawProgressView> mTarget;

        public MySecondThread(DrawProgressView view) {
            mTarget = new WeakReference<DrawProgressView>(view);
        }

        @Override
        public void run() {
            while (!interrupted()) {
                if (null == mTarget.get())
                    break;
                if (380 == mTarget.get().mSecondDrawDegree)
                    break;
                if (180 < mTarget.get().mSecondDrawDegree) {
                    try {
                        sleep(5);
                        mTarget.get().mSecondDrawDegree += mTarget.get().mDegree;
                        mTarget.get().postInvalidate();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                } else {
                    try {
                        sleep(10);
                        mTarget.get().mSecondDrawDegree += mTarget.get().mDegree;
                        mTarget.get().postInvalidate();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            isSencondShow = true;
            isStartSecondStop = true;
        }
    }

    /**
     * 回收第一圈的角度变化线程
     */

    private class MyFirstThreadEnd extends Thread {
        private WeakReference<DrawProgressView> mTarget;

        public MyFirstThreadEnd(DrawProgressView view) {
            mTarget = new WeakReference<DrawProgressView>(view);
        }

        @Override
        public void run() {
            while (!interrupted()) {
                if (null == mTarget.get())
                    break;
                if (360 == mTarget.get().mFirstDrawDegree) {
                    break;
                }
                try {
                    sleep(5);
                    mTarget.get().mFirstDrawDegree += mTarget.get().mDegree;
                    mTarget.get().postInvalidate();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            isFirstShow = false;
            isEndFirstStop = true;
        }
    }

    /**
     * 回收第二圈的角度变化线程
     */

    private class MySecondThreadEnd extends Thread {
        private WeakReference<DrawProgressView> mTarget;

        public MySecondThreadEnd(DrawProgressView view) {
            mTarget = new WeakReference<DrawProgressView>(view);
        }

        @Override
        public void run() {
            while (!interrupted()) {
                if (null == mTarget.get())
                    break;
                if (360 == mTarget.get().mSecondDrawDegree) {
                    break;
                }
                try {
                    sleep(8);
                    mTarget.get().mSecondDrawDegree += mTarget.get().mDegree;
                    mTarget.get().postInvalidate();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            isSencondShow = false;
            isEndSecondStop = true;
        }
    }

    public boolean isSencondShow() {
        return isSencondShow;
    }

    public boolean isFirstShow() {
        return isFirstShow;
    }
}

   加上一些属性的定义:

<resources>
    <declare-styleable name="DrawView">
        <attr name="inner_cir" format="dimension" />
        <attr name="first_width" format="dimension" />
        <attr name="second_width" format="dimension" />
        <attr name="first_color" format="color" />
        <attr name="second_color" format="color" />
        <attr name="inner_color" format="color"/>
        <attr name="degree" format="integer"/>
    </declare-styleable>
</resources>
   其实效果挺不错的,理解了是通过不断重绘得出的代码应该没什么难度,可以考虑icon不固定让动态添加icon,然后计算角度就可以了。

  下面是Activity的代码

package com.example.arze.momentview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;


public class MainActivity extends AppCompatActivity implements DrawProgressView.OnDrawClickListener {
    DrawProgressView drawProgressView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawProgressView = ((DrawProgressView) findViewById(R.id.drawProgressView));
        drawProgressView.setOnDrawClickListener(this);
    }


    @Override
    public void onClick(View view, int position, boolean isFirst, boolean isSecond, boolean isCenter) {

        DrawProgressView drawProgressView = (DrawProgressView) view;
        if (isCenter) {
            if (drawProgressView.isSencondShow()) {
                drawProgressView.endSecond();
            }
            if (drawProgressView.isFirstShow()) {
                drawProgressView.endFirst();
            } else {
                drawProgressView.startFirst();
            }
        }

        if (isFirst) {
            if (1 == position) {
                if (drawProgressView.isSencondShow())
                    drawProgressView.endSecond();
                else
                    drawProgressView.startSecond();
            }
        }

    }
}

         

   

    

     

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity自带的菜单选项可以为开发人员提供快捷的功能,但是当我们需要一个更加专业化的菜单时,Unity的默认菜单选项可能无法满足需求。此时,自定义树形菜单就应运而生。 Unity的自定义树形菜单是基于EditorGUILayout的GUI实现的。首先,我们需要扩展Editor类并使用MenuCommand属性,以及EditorGUI类,来为自定义菜单添加菜单项和功能选项。然后,我们可以使用GUILayout实现垂直排列的树形菜单,在每个菜单项的后面添加子菜单。 接下来,我们应该为自定义菜单添加相应的功能。在每个菜单项中,我们可以通过EditorGUILayout实现按钮、文本框、下拉菜单等等,为每个功能选项设计对应的功能。比如,我们可以在菜单项中添加新的对象、展开/折叠所有对象、删除特定的对象等功能。 最后,我们需要重写OnGUI方法,在其中调用自己的菜单绘制函数。这样,在编辑器中打开自定义窗口时,我们就可以看到新的树形菜单和功能选项了。另外,我们要记得在Menu选项中添加自定义的扩展菜单,这样才能在编辑器菜单中添加自己的菜单项。 总而言之,Unity的自定义树形菜单功能可以让开发人员更加简便地实现自己的的菜单和功能选项。如果你想为Unity添加一些自定义的、专业化的菜单和功能选项,自定义树形菜单将是一个十分有效的解决方案。 ### 回答2: Unity是一款非常强大的游戏引擎,在其中可以进行大量的开发工作。其中,Unity提供了很多的功能和工具,其中就包括了自定义树形菜单。 在Unity中,树形菜单是一种非常方便的工具,可以让用户轻松地查看所有的功能和对象,并且方便进行管理。如果用户想要自定义树形菜单,可以按照以下的步骤进行操作: 1. 创建一个新的编辑器窗口,负责显示自定义树形菜单。 2. 在这个编辑器窗口中,可以使用GUILayout或者IMGUI等工具来自定义绘制。 3. 使用EditorApplication.hierarchyWindowChanged事件去监听当场景objectId的集合发生了改变时触发。 4. 使用UnityEditor.GUILayout.Popup方法样式,用户可以为每个节点添加下拉箭头。 5. 使用自定义GUILayout.Button方法样式,用户可以为每个节点添加列表中的按钮。 上述步骤是在Unity中自定义树形菜单的基本过程,用户可以根据自己的需求进行更改和调整。自定义树形菜单可以大大提高工作效率,让开发者更加方便地管理和操作游戏中的场景、对象和功能。 ### 回答3: Unity是一款十分强大的游戏引擎,是许多游戏制作人员所钟爱的工具。Unity自带的菜单栏虽然已经很强大,但是我们还是有时候需要自定义树形菜单,来更好的实现游戏中的各种功能。这里我们将介绍如何使用Unity自定义树形菜单。 首先,打开Unity的编辑器并打开项目。然后在项目中新建一个C#脚本,并将其命名为“CustomMenu.cs”。我们将在这个脚本中编写我们的树形菜单。 接下来,我们需要为我们的树形菜单设置一个名称。在“CustomMenu.cs”中,使用“[MenuItem(“Custom/MyMenu”)]”,产生一个名为“MyMenu”的菜单。 接下来,我们可以在Unity的编辑器中创建一个新的文件夹,将其命名为“Custom”,这个文件夹将成为我们创建的菜单的父级。 接下来,在“CustomMenu.cs”中,我们可以使用“[MenuItem(“Custom/MyMenu/Do Something”)]”创建菜单的子项,并添加相应的函数来实现这个子项的功能。 最后,在Unity中运行我们的项目,并点击菜单栏“Custom”选项,我们就可以看到我们刚刚创建的树形菜单了。当我们点击“MyMenu”时,会显示“Do Something”子项。当我们点击“Do Something”时,它将调用相应的函数并执行相应的操作。 综上所述,Unity自定义树形菜单的实现方法是很简单的。我们只需要编写一个包含菜单名称和相应函数的脚本即可。可以根据需要创建任意多的子项,并为它们添加相应的功能。自定义菜单能够帮助我们更好地实现游戏中的各种功能,提高我们的工作效率,让我们更加专注于游戏的创作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值