Unity教程之-制作闪亮的星星Star(五):源码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ywjun0919/article/details/50725207

Star.cs

using System;
using UnityEngine;

[ExecuteInEditMode,RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class Star : MonoBehaviour {

    [Serializable]
    public class Point {
        public Color color;
        public Vector3 offset;
    }

    public Point[] points;
    public int frequency = 1;
    public Color centerColor;

    private Mesh mesh;
    private Vector3[] vertices;
    private Color[] colors;
    private int[] triangles;

    public void UpdateStar()
    {
        GetComponent<MeshFilter>().mesh = mesh = new Mesh();
        mesh.name = "Star Mesh";

        if (frequency < 1)
        {
            frequency = 1;
        }
        if (points == null || points.Length == 0)
        {
            points = new Point[] { new Point() };
        }

        int numberOfPoints = frequency * points.Length;
        vertices = new Vector3[numberOfPoints + 1];
        colors = new Color[numberOfPoints + 1];
        triangles = new int[numberOfPoints * 3];
        float angle = -360f / numberOfPoints;
        colors[0] = new Color(centerColor.r, centerColor.g, centerColor.b, centerColor.a); ;
        for (int iF = 0, v = 1, t = 1; iF < frequency; iF++)
        {
            for (int iP = 0; iP < points.Length; iP += 1, v += 1, t += 3)
            {
                vertices[v] = Quaternion.Euler(0f, 0f, angle * (v - 1)) * points[iP].offset;
                colors[v] = new Color(points[iP].color.r, points[iP].color.g, points[iP].color.b, points[iP].color.a);
                triangles[t] = v;
                triangles[t + 1] = v + 1;
            }
        }
        triangles[triangles.Length - 1] = 1;

        mesh.vertices = vertices;
        mesh.colors = colors;
        mesh.triangles = triangles;
    }

    void OnEnable () {
        UpdateStar();
    }

    //void Update()
    //{
    //    if (Application.isEditor)
    //    {
    //        UpdateStar();
    //    }
    //}
    void Reset()
    {
        UpdateStar();
    }

    void OnDisable()
    {
        if (Application.isEditor)
        {
            GetComponent<MeshFilter>().mesh = null;
            DestroyImmediate(mesh);
        }
    }
}

Star.shader

Shader "Star"{
    SubShader{
        Tags{ "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
        Blend SrcAlpha OneMinusSrcAlpha
        Cull Off
        Lighting Off
        ZWrite Off
        Pass{
            CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag

                struct data {
                    float4 vertex : POSITION;
                    fixed4 color: COLOR;
                };

                data vert (data v) {
                    v.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                    return v;
                }

                fixed4 frag(data f) : COLOR {
                    return f.color;
                }
            ENDCG
        }
    }
}

StarInspector.cs

using UnityEditor;
using UnityEngine;

[CanEditMultipleObjects, CustomEditor(typeof(Star))]
public class StarInspector : Editor {
    private static Vector3 pointSnap = Vector3.one * 0.1f;
    private static GUIContent
        insertContent = new GUIContent("+", "duplicate this point"),
        deleteContent = new GUIContent("-", "delete this point"),
        pointContent = GUIContent.none,
        teleportContent = new GUIContent("T");

    private static GUILayoutOption
        buttonWidth = GUILayout.MaxWidth(20f),
        colorWidth = GUILayout.MaxWidth(50f);

    private SerializedObject star;
    private SerializedProperty
        points,
        frequency,
        centerColor;

    private int teleportingElement;

    void OnEnable () {
        star = new SerializedObject(targets);
        points = star.FindProperty("points");
        frequency = star.FindProperty("frequency");
        centerColor = star.FindProperty("centerColor");

        teleportingElement = -1;
        teleportContent.tooltip = "start teleporting this point";
    }

    public override void OnInspectorGUI () {
        star.Update();

        GUILayout.Label("Points");
        for(int i = 0; i < points.arraySize; i++){
            SerializedProperty
                point = points.GetArrayElementAtIndex(i),
                offset = point.FindPropertyRelative("offset");
            if(offset == null){
                break;
            }
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(offset, pointContent);
            EditorGUILayout.PropertyField(point.FindPropertyRelative("color"), pointContent, colorWidth);

            if(GUILayout.Button(teleportContent, EditorStyles.miniButtonLeft, buttonWidth)){
                if(teleportingElement >= 0){
                    points.MoveArrayElement(teleportingElement, i);
                    teleportingElement = -1;
                    teleportContent.tooltip = "start teleporting this point";
                }
                else{
                    teleportingElement = i;
                    teleportContent.tooltip = "teleport here";
                }
            }
            if(GUILayout.Button(insertContent, EditorStyles.miniButtonMid, buttonWidth)){
                points.InsertArrayElementAtIndex(i);
            }
            if(GUILayout.Button(deleteContent, EditorStyles.miniButtonRight, buttonWidth)){
                points.DeleteArrayElementAtIndex(i);
            }

            EditorGUILayout.EndHorizontal();
        }
        if(teleportingElement >= 0){
            GUILayout.Label("teleporting point " + teleportingElement);
        }

        EditorGUILayout.PropertyField(frequency);
        EditorGUILayout.PropertyField(centerColor);

        if(
            star.ApplyModifiedProperties() ||
            (Event.current.type == EventType.ValidateCommand &&
            Event.current.commandName == "UndoRedoPerformed")
        ){
            foreach(Star s in targets){
                if(PrefabUtility.GetPrefabType(s) != PrefabType.Prefab){
                    s.UpdateStar();
                }
            }
        }
    }

    void OnSceneGUI()
    {
        Star star = (Star)target;
        Transform starTrans = star.transform;
        Undo.RecordObject(star, "Move star transform");
        float angle = -360 / (star.frequency * star.points.Length);
        for (int i =0;i<star.points.Length;++i)
        {
            Quaternion rotation = Quaternion.Euler(0,0,angle *i);
            Vector3 oldPoint = starTrans.TransformPoint(rotation * star.points[i].offset),
            newPoint = Handles.FreeMoveHandle(oldPoint, Quaternion.identity, 0.05f, pointSnap, Handles.DotCap);
            if (oldPoint != newPoint)
            {
                star.points[i].offset = Quaternion.Inverse(rotation) * starTrans.InverseTransformPoint(newPoint);
                star.UpdateStar();
            }
        }
    }
}

源码地址:http://download.csdn.net/detail/ywjun0919/9440824

阅读更多

没有更多推荐了,返回首页