unity编辑器拓展十二——用脚本控制特效的渐隐渐出(使用ReorderableList绘制List)

正常特效的渐隐渐出 是靠美术来k关键帧,比较不方便,就想着用脚本来控制比较方便,只要填写什么时候开始,渐出需要多长时间,中间持续多长时间,渐隐需要多长时间,填完就可以了,也方便修改。

脚本1:需要绘制的类 以及UpData里的计算

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
[ExecuteInEditMode]
public class Time_Fx : MonoBehaviour
{
    public List<Time_all> TimeGameObj = new List<Time_all>();
    private float[] time00 = null;
    private float[] TimeSin =null;
    private float[] Timestart = null;
    private float m_time;

    private void OnEnable()
    {
        TimeSin = new float[TimeGameObj.Count];
        time00 = new float[TimeGameObj.Count];
        Timestart = new float[TimeGameObj.Count];
        //在OnEnable里面记录Time.time 因为它只运行一次 所以可以记录下来开始运行的时间
        m_time = Time.time;


    }

    void Update()
    {
        for (int i = 0; i < TimeGameObj.Count; i++ )
        {
            Timestart[i] = m_time;

            if (Time.time - Timestart[i] < TimeGameObj[i].Start)
            {
                TimeSin[i] = 0; 
            }
            else
            {
               

                if (time00[i] < 1)
                {
                    time00[i] = (Time.time- m_time - TimeGameObj[i].Start)/ (TimeGameObj[i].Starting+0.01f);
                    TimeSin[i] = time00[i];
                }

               else if (time00[i] >= 1 && time00[i]<2)
                {
                    TimeSin[i] = 1;
                    time00[i] =1+ (Time.time- m_time - TimeGameObj[i].Start - TimeGameObj[i].Starting)/ (TimeGameObj[i].Miding+0.01f);
                    

                }

               else if (time00[i] >= 2 && time00[i] < 3)
                {
                    time00[i] = 2 + (Time.time- m_time - TimeGameObj[i].Start - TimeGameObj[i].Starting - TimeGameObj[i].Miding) / (TimeGameObj[i].Ending + 0.01f);
                    if (TimeSin[i] >= 0)
                    {
                        
                        TimeSin[i] =1- (Time.time- m_time - TimeGameObj[i].Start - TimeGameObj[i].Starting - TimeGameObj[i].Miding) / (TimeGameObj[i].Ending+0.01f);

                        if (TimeSin[i] < 0)
                        {
                            TimeSin[i] = 0;
                        }
                    }
                }            
            }

            TimeGameObj[i].gameObj.GetComponent<MeshRenderer>().sharedMaterial.SetFloat("_TimeSin", TimeSin[i]);
        }
    }
    }





[Serializable]
public class Time_all
{
    [SerializeField]
   public GameObject gameObj;

    [SerializeField]
  public  float Start;

    [SerializeField]
    public float Starting;



    [SerializeField]
    public float Miding;

    [SerializeField]
    public float Ending;
}

脚本2:通过使用ReorderableList绘制List

using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEditorInternal;
[ExecuteInEditMode]
[CustomEditor(typeof(Time_Fx))]
public class TimeFXEditor : Editor
{
    ReorderableList reorderableList;

    void OnEnable()
    {
        SerializedProperty prop = serializedObject.FindProperty("TimeGameObj");

        reorderableList = new ReorderableList(serializedObject, prop, true, true, true, true);

        //设置单个元素的高度
        reorderableList.elementHeight = 80;

        //绘制单个元素
        reorderableList.drawElementCallback =
            (rect, index, isActive, isFocused) => {
                var element = prop.GetArrayElementAtIndex(index);
                rect.height -= 4;
                rect.y += 2;
                EditorGUI.PropertyField(rect, element);
            };

        //背景色
        reorderableList.drawElementBackgroundCallback = (rect, index, isActive, isFocused) => {
            GUI.backgroundColor = new Color(0.7f,0.7f,0.7f);
        };

        //头部
        reorderableList.drawHeaderCallback = (rect) =>
            EditorGUI.LabelField(rect, prop.displayName);

    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        reorderableList.DoLayoutList();
        serializedObject.ApplyModifiedProperties();
    }
}

效果如下:

 

脚本3:在上面的基础上进行绘制

using UnityEngine;
using System.Collections;
using UnityEditor;
[ExecuteInEditMode]
//定制Serializable类的每个实例的GUI
[CustomPropertyDrawer(typeof(Time_all))]
public class CharacterDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        //创建一个属性包装器,用于将常规GUI控件与SerializedProperty一起使用
        using (new EditorGUI.PropertyScope(position, label, property))
        {
            //设置属性名宽度 Name HP
            EditorGUIUtility.labelWidth = 60;
            //输入框高度,默认一行的高度
            position.height = EditorGUIUtility.singleLineHeight;

            //gameObj位置矩形
            Rect gameObj = new Rect(position)
            {
                width = 160,
                height = 20
            };

            Rect Start = new Rect(position)
            {
                width = 100,    //减去icon的width 64
                x = position.x + 162             //在icon的基础上右移64
            };

            Rect Starting = new Rect(Start)
            {
                y = Start.y + EditorGUIUtility.singleLineHeight + 2

            };
        Rect Miding = new Rect(Starting)
            {
                //在name的基础上,y坐标下移
                y = Starting.y + EditorGUIUtility.singleLineHeight + 2
            };

            Rect Ending = new Rect(Miding)
            {
                //在hp的基础上,y坐标下移
                y = Miding.y + EditorGUIUtility.singleLineHeight + 2
            };

            //找到每个属性的序列化值
            SerializedProperty gameObjProperty = property.FindPropertyRelative("gameObj");
            SerializedProperty startProperty = property.FindPropertyRelative("Start");
            SerializedProperty startingProperty = property.FindPropertyRelative("Starting");
            SerializedProperty MidProperty = property.FindPropertyRelative("Miding");
            SerializedProperty EndProperty = property.FindPropertyRelative("Ending");
            // SerializedProperty weaponProperty = property.FindPropertyRelative("weapon");

            //绘制icon
            gameObjProperty.objectReferenceValue = EditorGUI.ObjectField(gameObj, gameObjProperty.objectReferenceValue, typeof(GameObject), true);
            startProperty.floatValue = EditorGUI.FloatField(Start, "Start", startProperty.floatValue);
            startingProperty.floatValue = EditorGUI.FloatField(Starting, "Starting", startingProperty.floatValue);
            MidProperty.floatValue = EditorGUI.FloatField(Miding, "Miding", MidProperty.floatValue);
            EndProperty.floatValue = EditorGUI.FloatField(Ending, "Ending", EndProperty.floatValue);

        }
    }
}

效果如下:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity编辑器拓展(Editor Extension)可以通过自定义的脚本来扩展Unity编辑器的功能和界面,以满足特定项目的需求。通过编辑器拓展,开发者可以创建自定义的编辑器窗口、工具栏按钮、菜单项、检视面板等,来增强Unity编辑器的功能和流程。 要创建一个Unity编辑器拓展,你可以使用C#编写一个继承自Editor类的脚本。这个脚本可以通过Unity的Inspector面板来设置相关的属性和行为。以下是一个简单的示例: ```csharp using UnityEngine; using UnityEditor; public class MyEditorExtension : EditorWindow { [MenuItem("Custom Tools/My Editor Window")] public static void OpenWindow() { // 创建并打开一个自定义的编辑器窗口 MyEditorExtension window = (MyEditorExtension)EditorWindow.GetWindow(typeof(MyEditorExtension)); window.Show(); } private void OnGUI() { // 在编辑器窗口中绘制UI元素 GUILayout.Label("Hello, I am a custom editor window!"); if (GUILayout.Button("Click Me")) { Debug.Log("Button clicked!"); } } } ``` 上述代码创建了一个自定义的编辑器窗口,并在窗口中绘制了一个标签和一个按钮。通过在Unity编辑器中点击"Custom Tools"菜单下的"My Editor Window",可以打开这个自定义的编辑器窗口。 除了编辑器窗口,你还可以通过继承Editor类来创建自定义的检视面板、菜单项等。Unity官方文档中有更详细的教程和示例,可以帮助你更深入地了解和使用Unity编辑器拓展
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值