Unity 代码片段2017篇

///预先显示动画文件路径//

  1. public class ClipInfo : EditorWindow
  2. {
  3.     private AnimationClip clip;
  4.     [MenuItem("Window/Clip Info")]
  5.     static void Init()
  6.     {
  7.         GetWindow(typeof(ClipInfo));
  8.     }
  9.     public void OnGUI()
  10.     {
  11.         clip = EditorGUILayout.ObjectField("Clip", clip, typeof(AnimationClip), false) as AnimationClip;
  12.         EditorGUILayout.LabelField("Curves:");
  13.         if (clip != null)
  14.         {
  15.             foreach (var binding in AnimationUtility.GetCurveBindings(clip))
  16.             {
  17.                 AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, binding);
  18.                 EditorGUILayout.LabelField(binding.path + "/" + binding.propertyName + ", Keys: " + curve.keys.Length);
  19.                 for (int i = 0; i < curve.length; i++)
  20.                 {
  21.                     EditorGUILayout.LabelField("Keys" + i + ":" + curve[i].value);
  22.                 }
  23.             }
  24.         }
  25.         if (GUILayout.Button("Save"))
  26.         {
  27.             Save();
  28.         }
  29.     }
  30.     
  31.     public void Save()
  32.     {
  33.         if (clip != null)
  34.         {
  35.             ObjectPosCurvesData o = new ObjectPosCurvesData();
  36.             foreach (var binding in AnimationUtility.GetCurveBindings(clip))
  37.             {
  38.                 AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, binding);
  39.                 Debug.Log(binding.propertyName);
  40.                 if (binding.propertyName == "m_LocalPosition.x")
  41.                 {
  42.                     o.curveX = new float[curve.length];
  43.                     o.KeyLength = curve.length;
  44.                     for (int i = 0; i < curve.length; i++)
  45.                     {
  46.                         o.curveX[i] = curve[i].value;
  47.                     }
  48.                 }
  49.                 else if (binding.propertyName == "m_LocalPosition.y")
  50.                 {
  51.                     o.curveY = new float[curve.length];
  52.                     for (int i = 0; i < curve.length; i++)
  53.                     {
  54.                         o.curveY[i] = curve[i].value;
  55.                     }
  56.                 }
  57.                 else if (binding.propertyName == "m_LocalPosition.z")
  58.                 {
  59.                     o.curveZ = new float[curve.length];
  60.                     for (int i = 0; i < curve.length; i++)
  61.                     {
  62.                         o.curveZ[i] = curve[i].value;
  63.                     }
  64.                 }
  65.             }
  66.           //序列化并保存文件
  67.           FileUtils.SaveFile(@"E:\AnimationData\AD.data",FileUtils.SerializeToBinary(o));
  68.         }
  69.     }
  70. }
  71. [Serializable]
  72. public class ObjectPosCurvesData
  73. {
  74.     public int KeyLength;
  75.     public float[] curveX;
  76.     public float[] curveY;
  77.     public float[] curveZ;
  78. }

///NavMeshAgent 寻路路径Game显示/

public Transform line;//就是我们刚才添加的 gameobject
private LineRenderer _lineRenderer;//储存 gameobject 的 LineRenderer 组件
void Start () 
{
     _lineRenderer = line.GetComponent<LineRenderer>();
}
Vector3[] path = Nav.path.corners;//储存路径
_lineRenderer.SetVertexCount(path.Length);//设置线段数
for (int i = 0; i < path.Length; i++)
{
     _lineRenderer.SetPosition(i, path[i]);//设置线段顶点坐标
}

///OpenURL//

It's well worth noting that if you just want to send a very simple one with NO dynamic text, no body, no unusual characters, just replace the spaces with %20 manually like so:

 public void LinkHelpEMAIL()
  {
  string t =
  "mailto:blah@blah.com?subject=Question%20on%20Awesome%20Game";
  Application.OpenURL(t);
  }
exactly like that (do not escape the at symbol). saves typing, tested on both.
/// <summary>
 /// - opens the mail app on android, ios & windows (tested on windows)
 /// </summary>
 public class SendMailCrossPlatform
 {
     
     /// <param name="email"> myMail@something.com</param>
     /// <param name="subject">my subject</param>
     /// <param name="body">my body</param>
     public static void SendEmail (string email,string subject,string body)
     {
         subject = MyEscapeURL(subject);
         body = MyEscapeURL(body);
         Application.OpenURL("mailto:" + email + "?subject=" + subject + "&body=" + body);
     }
     public static string MyEscapeURL (string url)
     {
         return WWW.EscapeURL(url).Replace("+","%20");
     }
 }

//ScriptableObjectCreateInstance

public class NPCDataInstance : UnityEngine.ScriptableObject
{
    //public string data;
    public List<NPCData> dataLst;
}

[System.Serializable]
public class NPCData //: ScriptableObject
{
    public UnityEngine.Vector3 Position;
    //public UnityEngine.Color Color;
    public float Color_r;
    public float Color_g;
    public float Color_b;
}

[MenuItem("GameObject/GeneratePositionColor", false, 1)]/*Assets [CreateAssetMenu(fileName = "UntitledInstaller", menuName = "MyAsset/UntitledInstaller")]//添加这个特性就能在资源窗口右键创建资源*/
    public static void GenerateData()
    {
        var npcs = Selection.gameObjects[0].transform.GetComponentsInChildren<Transform>();
        var npcDataInstance = ScriptableObject.CreateInstance<NPCDataInstance>();
        npcDataInstance.dataLst = new List<NPCData>();
        for (int i = 1, count = npcs.Length; i < count; i++)
        {
            NPCData data = /*ScriptableObject.CreateInstance<NPCData>();*/new NPCData();
            data.Position = npcs[i].transform.position;
            SpriteRenderer sr = npcs[i].GetComponent<SpriteRenderer>();
            //data.Color = sr.color;
            data.Color_r = sr.color.r;
            data.Color_g = sr.color.g;
            data.Color_b = sr.color.b;
            npcDataInstance.dataLst.Add(data);
        }
        //string json = JsonConvert.SerializeObject(npcDataInstance.dataLst);
        AssetDatabase.CreateAsset(npcDataInstance, @"Assets\Resources\NPCData.asset"/*FileUtil.GetProjectRelativePath(AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this)))*/);
    }

LoadAssetAsync<NPCDataInstance>("NPCData.asset", (name, obj) =>
            {
                m_npcDataLst = (obj as NPCDataInstance).dataLst; });

//simple spire animation ///

 [CreateAssetMenu(order = 1000)]
    public class SpriteFrameAnimation : ScriptableObject
    {
        public bool loop;
        public float frameDuration = 15.0f; // duration is in milliseconds
        public Sprite[] frames = new Sprite[0];
    }

public enum SpriteFrameAnimationResetOption
    {
        DontReset,
        ResetIfNew,
        ResetAlways
    }

    [AddComponentMenu("UnityToolbag/Sprite Frame Animator")]
    public class SpriteFrameAnimator : MonoBehaviour
    {
        private SpriteFrameAnimation _currentAnimation;

        private int _frame;
        private float _timer;

        [SerializeField]
        private SpriteRenderer _spriteRenderer;

        [SerializeField]
        private SpriteFrameAnimation[] _animations;

        [SerializeField]
        private string _startAnimation = string.Empty;

        [SerializeField]
        private bool _playOnStart = false;

        public bool isAnimationComplete
        {
            get
            {
                if (_currentAnimation == null) {
                    return true;
                }

                if (_currentAnimation.loop) {
                    return false;
                }

                return _frame == _currentAnimation.frames.Length - 1 &&
                       _timer == _currentAnimation.frameDuration;
            }
        }

        public void Play(string name)
        {
            Play(name, SpriteFrameAnimationResetOption.ResetIfNew);
        }

        public void Play(string name, SpriteFrameAnimationResetOption resetOption)
        {
            SpriteFrameAnimation newAnimation = null;

            foreach (var anim in _animations){
                if (anim.name == name) {
                    newAnimation = anim;
                    break;
                }
            }

            if (newAnimation == null) {
                _currentAnimation = null;
                return;
            }

            switch (resetOption) {
                case SpriteFrameAnimationResetOption.ResetIfNew: {
                    if (newAnimation != _currentAnimation) {
                        _frame = 0;
                        _timer = 0;
                    }
                    break;
                }
                case SpriteFrameAnimationResetOption.ResetAlways: {
                    _frame = 0;
                    _timer = 0;
                    break;
                }
                default: {
                    break;
                }
            }

            _currentAnimation = newAnimation;
            if (_currentAnimation != null) {
                UpdateWithFrameData();
            }
        }

        public void Stop()
        {
            _currentAnimation = null;
        }

        public void Stop(int stopOnIndex)
        {
            if (_currentAnimation != null) {
                _frame = stopOnIndex;
                UpdateWithFrameData();
                _currentAnimation = null;
            }
        }

        void Awake()
        {
            _spriteRenderer = GetComponent<SpriteRenderer>();
        }

        void Start()
        {
            if (_playOnStart) {
                Play(_startAnimation);
            }
        }

        void Update()
        {
            if (_currentAnimation != null) {
                if (!isAnimationComplete) {
                    _timer += Time.deltaTime * 1000f;
                }

                if (_timer >= _currentAnimation.frameDuration) {
                    _timer -= _currentAnimation.frameDuration;

                    if (!isAnimationComplete || _currentAnimation.loop) {
                        if (_currentAnimation.loop) {
                            _frame = (_frame + 1) % _currentAnimation.frames.Length;
                        }
                        else if (_frame < _currentAnimation.frames.Length) {
                            _frame++;
                        }

                        UpdateWithFrameData();
                    }
                }
            }
        }

        void UpdateWithFrameData()
        {
            _spriteRenderer.sprite = _currentAnimation.frames[_frame];
        }
    }

生成脚本

编辑器脚本可以通过

var scriptPath = AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this));

AssetDatabase.LoadAssetAtPath<TextAsset>(assetPath);

inputText.Replace

File.WriteAllText(writePath, inputText);

            AssetDatabase.SaveAssets();

            AssetDatabase.Refresh();

物体 transform.rotation.eulerAngles; 遇到万向锁了  transform.forward 向前则没有 ,赋值给主角朝向 

设置一下Lua脚本的模板地址 :  Assets/Editor/Lua/Template/lua.lua

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

using UnityEngine;

using UnityEditor;

using System;

using System.IO;

using System.Text;

using UnityEditor.ProjectWindowCallback;

using System.Text.RegularExpressions;

public class Test

{

    [MenuItem("Assets/Create/Lua Script", false, 80)]

    public static void CreatNewLua()

    {

        ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0,

        ScriptableObject.CreateInstance<MyDoCreateScriptAsset>(),

        GetSelectedPathOrFallback() + "/New Lua.lua",

        null,

       "Assets/Editor/Lua/Template/lua.lua");

    }

    public static string GetSelectedPathOrFallback()

    {

        string path = "Assets";

        foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets))

        {

            path = AssetDatabase.GetAssetPath(obj);

            if (!string.IsNullOrEmpty(path) && File.Exists(path))

            {

                path = Path.GetDirectoryName(path);

                break;

            }

        }

        return path;

    }

}    

class MyDoCreateScriptAsset : EndNameEditAction

{

    public override void Action(int instanceId, string pathName, string resourceFile)

    {

        UnityEngine.Object o = CreateScriptAssetFromTemplate(pathName, resourceFile);

        ProjectWindowUtil.ShowCreatedAsset(o);

    }

    internal static UnityEngine.Object CreateScriptAssetFromTemplate(string pathName, string resourceFile)

    {

        string fullPath = Path.GetFullPath(pathName);

        StreamReader streamReader = new StreamReader(resourceFile);

        string text = streamReader.ReadToEnd();

        streamReader.Close();

        string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(pathName);

        text = Regex.Replace(text, "#NAME#", fileNameWithoutExtension);

        //string text2 = Regex.Replace(fileNameWithoutExtension, " ", string.Empty);

        //text = Regex.Replace(text, "#SCRIPTNAME#", text2);

        //if (char.IsUpper(text2, 0))

        //{

        //    text2 = char.ToLower(text2[0]) + text2.Substring(1);

        //    text = Regex.Replace(text, "#SCRIPTNAME_LOWER#", text2);

        //}

        //else

        //{

        //    text2 = "my" + char.ToUpper(text2[0]) + text2.Substring(1);

        //    text = Regex.Replace(text, "#SCRIPTNAME_LOWER#", text2);

        //}

        bool encoderShouldEmitUTF8Identifier = true;

        bool throwOnInvalidBytes = false;

        UTF8Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier, throwOnInvalidBytes);

        bool append = false;

        StreamWriter streamWriter = new StreamWriter(fullPath, append, encoding);

        streamWriter.Write(text);

        streamWriter.Close();

        AssetDatabase.ImportAsset(pathName);

        return AssetDatabase.LoadAssetAtPath(pathName, typeof(UnityEngine.Object));

    }

}  

初级资源创建

Editor文件夹下创建脚本:

using UnityEngine;

using UnityEditor;

public class CreateTest

{

    [MenuItem ("Assets/Create ExampleAssets")]

    static void CreateExampleAssets ()

    {

        var material = new Material (Shader.Find ("Standard"));

        ProjectWindowUtil.CreateAsset (material, "New Material.mat");

    }

}

点击Assets--Create ExampleAssets 就会发现一个材质球被创建

中级资源创建

Editor文件夹下创建脚本:

using UnityEngine;

using UnityEditor;

public class CreateMaterial

{

    [MenuItem ("Assets/Create Material")]

    static void CreateExampleAssets ()

    {

        var material = new Material (Shader.Find ("Standard"));

        var instanceID = material.GetInstanceID ();

        var icon = AssetPreview.GetMiniThumbnail (material);

        var endNameEditAction =

            ScriptableObject.CreateInstance<DoCreateMaterialAsset> ();

        ProjectWindowUtil.StartNameEditingIfProjectWindowExists (instanceID,

            endNameEditAction, "New Material.mat", icon, "");

    }

}

点击Assets--Create Material 创建一个特定的材质球

更自由的自定义资源创建

Editor文件夹下创建脚本:

using UnityEngine;

using UnityEditor;

using UnityEditor.ProjectWindowCallback;

public class DoCreateMaterialAsset : EndNameEditAction

{

    public override void Action (int instanceId, string pathName, string resourceFile)

    {

        var mat = (Material)EditorUtility.InstanceIDToObject (instanceId);

        mat.color = Color.red;

        AssetDatabase.CreateAsset (mat, pathName);

        AssetDatabase.ImportAsset (pathName);

        ProjectWindowUtil.ShowCreatedAsset (mat);

    }

}

Editor文件夹下创建脚本:

using System.IO;

using System.Text;

using UnityEditor;

using UnityEditor.ProjectWindowCallback;

using System;

public class DoCreateScriptAsset : EndNameEditAction

{

    public override void Action (int instanceId, string pathName, string resourceFile)

    {

        var text = File.ReadAllText (resourceFile);

        var className = Path.GetFileNameWithoutExtension (pathName);

        //清除空格

        className = className.Replace (" ", "");

        text ="//Programer: "+"porgramerName"+"\n//code date:"+DateTime.Now.Date.ToShortDateString()+"\n"

        +text.Replace ("#SCRIPTNAME#", className);

        text += "\n//自己添加Something!"+"\n";

        //utf8

        var encoding = new UTF8Encoding (true, false);

        File.WriteAllText (pathName, text, encoding);

        AssetDatabase.ImportAsset (pathName);

        var asset = AssetDatabase.LoadAssetAtPath<MonoScript> (pathName);

        ProjectWindowUtil.ShowCreatedAsset (asset);

    }

}

Editor文件夹下创建脚本:

using UnityEditor;

using UnityEngine;

using System.IO;

public class CreateAssets : EditorWindow

{

    [MenuItem("Window/CreatAssets")]

    static void Open ()

    {

        GetWindow<CreateAssets> ();

    }

    public string scriptName,materialName;

    void OnGUI()

    {

        var options = new []{GUILayout.Width (100), GUILayout.Height (20)};

        GUILayout.Label ("CreateScripts");

        EditorGUILayout.Space ();

        EditorGUILayout.BeginHorizontal ();

        EditorGUILayout.LabelField ("ScriptName",options);

        scriptName= EditorGUILayout.TextArea (scriptName);

        EditorGUILayout.EndHorizontal ();

        if (GUILayout.Button ("Create")) {

            CreateScript (scriptName);

        }

        GUILayout.Label ("CreateMaterial");

        EditorGUILayout .Space ();

        EditorGUILayout.BeginHorizontal ();

        EditorGUILayout.LabelField ("materialName",options);

        materialName=   EditorGUILayout.TextArea (materialName);

        EditorGUILayout.EndHorizontal ();

        if (GUILayout.Button ("Create")) {

            CreateMaterial (materialName);

        }

    }

//  新建自定义脚本

    static void CreateScript (string scriptName)

    {

        var resourceFile = Path.Combine (EditorApplication.applicationContentsPath,

            "Resources/ScriptTemplates/81-C# Script-NewBehaviourScript.cs.txt");

        Debug.Log (resourceFile);

        Texture2D csIcon =

            EditorGUIUtility.IconContent ("cs Script Icon").image as Texture2D;

        var endNameEditAction =

            ScriptableObject.CreateInstance<DoCreateScriptAsset> ();

        ProjectWindowUtil.StartNameEditingIfProjectWindowExists (0, endNameEditAction,

            scriptName+".cs", csIcon, resourceFile);

    }

    //新建Material

    static void CreateMaterial (string materialName)

    {

        var material = new Material (Shader.Find ("Standard"));

        var instanceID = material.GetInstanceID ();

        var icon = AssetPreview.GetMiniThumbnail (material);

        var endNameEditAction =

            ScriptableObject.CreateInstance<DoCreateMaterialAsset> ();

        ProjectWindowUtil.StartNameEditingIfProjectWindowExists (instanceID,

            endNameEditAction, materialName+".mat", icon, "");

    }

}

[CustomPropertyDrawer(typeof(LabelAttribute),false)]
public class LabelDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        label.text = (attribute as LabelAttribute).label;
        EditorGUI.PropertyField(position, property, label);
    }
}
public class LabelAttribute : PropertyAttribute
{
    public string label;
    public LabelAttribute(string label)
    {
        this.label = label;
    }
}

[Label("中文属性名")]
public int testInt;
[CustomPropertyDrawer(typeof(TabAttribute))]
public class TabDraw : PropertyDrawer
{
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return 0f;
    }
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        GUIStyle buttonActive = new GUIStyle(GUI.skin.button) { normal = GUI.skin.button.active };
        string[] tabNames = (attribute as TabAttribute).tabNames;
        EditorGUILayout.BeginHorizontal();
        int count = tabNames.Length;
        for (int i = 0; i < count; i++)
        {
            if (GUILayout.Button(tabNames[i], i == property.intValue ? buttonActive : GUI.skin.button))
            {
                property.intValue = i;
            }
        }
        EditorGUILayout.EndHorizontal();
    }
}
public class TabAttribute: PropertyAttribute
{
    public string[] tabNames;
}

//使用示例
[Tab(tabNames = new string[] { "tab1","tab2"})]
public int tabIndex;

publicTAddComponent<T>() whereT: EntityComponent,new()

        {

            if (_componentTypes.Contains(typeof(T)))

            {

                varcomp = components.Find(item=> item.GetType() == typeof(T));

                returncompasT;

            }

 

            Tcomponent= newT();

            components.Add(component);

            _componentTypes.Add(typeof(T));

 

            ProcessRequiredComponent(typeof(T));

            component.OnAttachToEntity(this);

            returncomponent;

       }

 

privatevoidProcessRequiredComponent(Typetype)

        {

            if (!typeof(EntityComponent).IsAssignableFrom(type))

            {

                Debugger.LogErrorFormat("type {0} must inherited from EntityComponent", type.Name);

                return;

            }

 

            RequireComponentattr = type.GetCustomAttribute<RequireComponent>();

            if (attr == null)

                return;

 

            Type[] typeArr= newType[3] { attr.m_Type0,attr.m_Type1, attr.m_Type2};

            for(inti = 0; i < 3; i++)

            {

                Typecomptype= typeArr[i];

                if (comptype!= null && typeof(EntityComponent).IsAssignableFrom(comptype))

                {

                    AddComponent(comptype);

                }

            }

           

       }

"<color=#FFFF00>dfafd</color>" Unity打印自定义颜色log

CreateAssetMenu(fileName = "bb", menuName = "aa", order = 100)
public class TerrainData : ScriptableObject {} 会在右键Create下有个aa,并生成bb的scriptableObject文件

transform.rotation.eulerAngles     transform.rotation = Quaternion.Euler(view.x, view.y, view.z);

static publicTLoadAsset<T> (stringpath)whereT: Object

    {

        Object obj = LoadAsset(path);

        if (obj ==null)returnnull;

        T val = obj asT;

        if (val !=null)returnval;

        if (typeof(T).IsSubclassOf(typeof(Component)))

        {

            if (obj.GetType() ==typeof(GameObject))

            {

                GameObjectgo =objas GameObject;

                return go.GetComponent(typeof(T))asT;

            }

        }

        return null;

    }

   public delegate void ActionClick(ActorData data);

public event ActionClick ActorDataDelegate;

public staticTCreateItemIcon<T>(ItemNumitemNum,Transformparent =null) where T : Object

   {

       GameObject go = ResUtil.LoadGameObject("UI/CommonIcon/ItemIconInfo");

       if (parent !=null)

            parent.AddChildEx(go.transform);

       go.name =string.Format("Item{0}",itemNum.ItemId);

       go.GetComponentOrAdd<ItemIconInfo>().Data =itemNum;

       T obj = go asT;

       if (obj !=null)returnobj;

       if(typeof(T).IsSubclassOf(typeof(Component)))

       {

            //if (go.GetType() == typeof(GameObject))

            {

                return go.GetComponent(typeof(T))asT;

            }

       }

       return null;

    }

代码生成AnimatorController

private void CreateAnimatorController(List<AnimationClip> clipList)
{
//创建一个控制器
AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath("Assets/youkexueyuan.controller");
//获取控制器的layer
AnimatorControllerLayer layer = animatorController.layers[0];
//获取状态机
AnimatorStateMachine machine = layer.stateMachine;
//添加一个坐标,让状态从这个位置开始摆放,防止状态乱摆,巨丑
Vector3 dpos = new Vector3(300,0,0);
foreach(AnimationClip clip in clipList)
{
AnimatorState state = new AnimatorState(); //machine.AddState(clip.name);
state.motion = clip;
state.name = clip.name;
machine.AddState(state, dpos);
dpos += new Vector3(0,50,0);//改变下一个坐标,让状态排成一列
if(state.name.Equals("idle"))
{
machine.defaultState = state;//设置默认状态
}
}
}

代码拷贝FBX模型动画剪辑

AnimationClip dstClip = new AnimationClip();
        dstClip.name = srcClip.name;
        string copyPath ="Assets/xiaobao.anim";
        AssetDatabase.CreateAsset(dstClip, copyPath);
        //拷贝Clip的浮点数据
        EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(srcClip);
        for (int i = 0; i &lt; bindings.Length; i++)
        {
            AnimationUtility.SetEditorCurve(dstClip, bindings[i], AnimationUtility.GetEditorCurve(srcClip, bindings[i]));
        }
        dstClip.frameRate = 30.0f;

Mesh材质合并

using UnityEngine;
using System.Collections;

public class Combine_Test : MonoBehaviour {

    // Use this for initialization
    void Start ()
    {
        //---------------- 先获取材质 -------------------------
        //获取自身和所有子物体中所有MeshRenderer组件
        MeshRenderer[] meshRenderers = GetComponentsInChildren<MeshRenderer>();  
        //新建材质球数组
        Material[] mats = new Material[meshRenderers.Length];  
        for (int i = 0; i < meshRenderers.Length; i++) {
            //生成材质球数组 
            mats[i] = meshRenderers[i].sharedMaterial;   
        }
        //---------------- 合并 Mesh -------------------------
        //获取自身和所有子物体中所有MeshFilter组件
        MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();  
        CombineInstance[] combine = new CombineInstance[meshFilters.Length];   
        for (int i = 0; i < meshFilters.Length; i++) {
            combine[i].mesh = meshFilters[i].sharedMesh;
            //矩阵(Matrix)自身空间坐标的点转换成世界空间坐标的点 
            combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
            meshFilters[i].gameObject.SetActive(false);
        } 
        //为新的整体新建一个mesh
        transform.GetComponent<MeshFilter>().mesh = new Mesh(); 
        //合并Mesh. 第二个false参数, 表示并不合并为一个网格, 而是一个子网格列表
        transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine, false);
        transform.gameObject.SetActive(true);

        //为合并后的新Mesh指定材质 ------------------------------
        transform.GetComponent<MeshRenderer>().sharedMaterials = mats; 
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}

反编译游戏资源得到的都是Altas大图片变成单张图片

  1. usingUnityEngine;
  2. usingSystem.Collections;
  3. usingUnityEditor;
  4. usingSystem.IO;
  5. publicclassSlipTexture:EditorWindow
  6. {
  7. publicTexture2DMainTex=null;
  8. [MenuItem("Window/分割图集")]
  9. publicstaticvoidCreateWindows()
  10. {
  11. SlipTexture sp =EditorWindow.CreateInstance<SlipTexture>();
  12. sp.title="分割图集";
  13. sp.Show(true);
  14. }
  15. voidOnGUI()
  16. {
  17. MainTex=EditorGUILayout.ObjectField("mainText",MainTex,typeof(Texture2D))asTexture2D;
  18. if(MainTex!=null)
  19. {
  20. if(GUILayout.Button("导出成小图片"))
  21. {
  22. string path =AssetDatabase.GetAssetPath(MainTex);
  23. TextureImporter importer =AssetImporter.GetAtPath(path)asTextureImporter;
  24. if(importer.textureType!=TextureImporterType.Sprite||
  25. importer.spriteImportMode!=SpriteImportMode.Multiple||
  26. importer.spritesheet.Length==0
  27. )
  28. {
  29. Debug.LogError("当前图片不是Sprite Multiple格式 或者没有分割");
  30. return;
  31. }
  32. importer.isReadable=true;
  33. AssetDatabase.ImportAsset(path);
  34. AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
  35. string savepath =EditorUtility.OpenFolderPanel("选择要保存的文件夹",Application.dataPath,"");
  36. if(!string.IsNullOrEmpty(savepath))
  37. {
  38. foreach(SpriteMetaData metaDatain importer.spritesheet)//遍历小图集
  39. {
  40. Texture2D myimage =newTexture2D((int)metaData.rect.width,(int)metaData.rect.height);
  41. for(int y=(int)metaData.rect.y; y < metaData.rect.y+ metaData.rect.height; y++)//Y轴像素
  42. {
  43. for(int x=(int)metaData.rect.x; x < metaData.rect.x+ metaData.rect.width; x++)
  44. myimage.SetPixel(x-(int)metaData.rect.x, y -(int)metaData.rect.y,MainTex.GetPixel(x, y));
  45. }
  46. //转换纹理到EncodeToPNG兼容格式
  47. if(myimage.format!=TextureFormat.ARGB32&& myimage.format!=TextureFormat.RGB24)
  48. {
  49. Texture2D newTexture =newTexture2D(myimage.width, myimage.height);
  50. newTexture.SetPixels(myimage.GetPixels(0),0);
  51. myimage= newTexture;
  52. }
  53. byte[] pngData = myimage.EncodeToPNG();
  54. //AssetDatabase.CreateAsset(myimage, rootPath + "/" + image.name + "/" + metaData.name + ".PNG");
  55. File.WriteAllBytes(savepath+"/"+ metaData.name+".PNG", pngData);
  56. }
  57. }
  58. }
  59. }
  60. }
  61. }

判断在不在摄像机裁剪范围

void Update()
	{
		if (renderer.IsVisibleFrom(Camera.main)) Debug.Log("Visible");
		else Debug.Log("Not visible");
	} Update()
	{
		if (renderer.IsVisibleFrom(Camera.main)) Debug.Log("Visible");
		else Debug.Log("Not visible");
	}
<span style="color:#008000">
</span>
 
static function IsRenderedFrom(renderer : Renderer, camera : Camera) : boolean
{
    var planes = GeometryUtility.CalculateFrustumPlanes(camera);
	return GeometryUtility.TestPlanesAABB(planes, renderer.bounds);
}function IsRenderedFrom(renderer : Renderer, camera : Camera) : boolean
{
    var planes = GeometryUtility.CalculateFrustumPlanes(camera);
	return GeometryUtility.TestPlanesAABB(planes, renderer.bounds);
}

/// 3D世界坐标转2DUI坐标并自适应的做法(血条,气泡)

UI
屏幕坐标系是从左下角为原点,Y轴向右为正,X轴向上为正。所有相关的UI的锚点都需要是设置成左下为锚点。其次,UI挂载的根节点需要做屏幕的自适应,保证和屏幕一样大。


脚本
常见的情况下有两种宽高。只要不是PC的固定界面大小,屏幕大小和设置的界面大小就会有对应的缩放情况。

第一种情况
Canvas使用固定屏幕大小。这种情况无论真机比例如何,都会按照预先设置好的大小比例进行缩放。

因为没有跟随屏幕分辨率进行缩放,所以我们在计算后需要再做多一步进行转换。根节点要做自适应。width和Height是屏幕宽高,位置是中心点(宽高/2)。
 

父节点的大小设置

           PlaneTransform.sizeDelta = CanvanTransform.sizeDelta;
           PlaneTransform.anchoredPosition = PlaneTransform.sizeDelta / 2;

UI的位置需要转化一下

        Vector3 pos = Camera.main.WorldToScreenPoint(m_TragetTransform.position + m_Offect);
        pos.x *= m_CanvasTransform.sizeDelta.x / Screen.width;
        pos.y *= m_CanvasTransform.sizeDelta.y / Screen.height;
        pos.z = 0;
        m_MyTransform.anchoredPosition = pos;

第二种情况
Canvas跟随屏幕大小,这样会跟随着分辨率的改变而改变。
因为根节点已经做了转换,所以直接设置即可。


           //m_TragetTransform是模型对象
           Vector3 pos = Camera.main.WorldToScreenPoint(m_TragetTransform.position + m_Offect);
           pos.z = 0;
           m_MyTransform.anchoredPosition = pos;


//

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值