zoukankan      html  css  js  c++  java
  • Unity 编辑器扩展 Chapter2—Gizmos

    二. 使用Gizoms绘制网格及矩阵转换使用

    1. 创建Leve类,作为场景控制类:

      1 using UnityEngine;
      2 //使用namespace方便脚本管理
      3 namespace RunAndJump {
      4 //使用部分类partial将类依据不同的功能分布到各个文件中,便于功能区分个管理
      5     public partial class Level : MonoBehaviour {
      6         [SerializeField]
      7         public int _totalTime = 60;
      8         [SerializeField]
      9         private float _gravity = -30;
     10         [SerializeField]
     11         private AudioClip _bgm;
     12         [SerializeField]
     13         private Sprite _background;
     14 
     15         [SerializeField]
     16         private int _totalColumns = 25;
     17 
     18         [SerializeField]
     19         private int _totalRows = 10;
     20 
     21         public const float GridSize = 1.28f;
     22 
     23         private readonly Color _normalColor = Color.grey;
     24         private readonly Color _selectedColor = Color.yellow;
     25         public int TotalTime {
     26             get { return _totalTime; }
     27             set { _totalTime = value; }
     28         }
     29 
     30         public float Gravity {
     31             get { return _gravity; }
     32             set { _gravity = value; }
     33         }
     34 
     35         public AudioClip Bgm {
     36             get { return _bgm;}
     37             set { _bgm = value; }
     38         }
     39 
     40         public Sprite Background {
     41             get { return _background; }
     42             set { _background = value; }
     43         }
     44 
     45         public int TotalColumns
     46         {
     47             get
     48             {
     49                 return _totalColumns;
     50             }
     51 
     52             set
     53             {
     54                 _totalColumns = value;
     55             }
     56         }
     57 
     58         public int TotalRows
     59         {
     60             get
     61             {
     62                 return _totalRows;
     63             }
     64 
     65             set
     66             {
     67                 _totalRows = value;
     68             }
     69         }
     70 
     71     //绘制边界
     72         private void GridFrameGizmo(int cols, int rows)
     73         {
     74             Gizmos.DrawLine(new Vector3(0,0,0),new Vector3(0,rows*GridSize,0) );
     75             Gizmos.DrawLine(new Vector3(0, 0, 0), new Vector3(cols*GridSize,0, 0));
     76             Gizmos.DrawLine(new Vector3(cols*GridSize, 0, 0), new Vector3(cols*GridSize, rows * GridSize, 0));
     77             Gizmos.DrawLine(new Vector3(0, rows*GridSize, 0), new Vector3(cols*GridSize, rows * GridSize, 0));
     78         }
     79 
     80 //绘制内部线条
     81         private void GridGizmos(int cols, int rows)
     82         {
     83             for (int i = 0; i < cols; i++)
     84             {
     85                 Gizmos.DrawLine(new Vector3(i*GridSize,0,0),new Vector3(i*GridSize,rows*GridSize,0) );
     86             }
     87 
     88             for (int j = 0; j < rows; j++)
     89             {
     90                 Gizmos.DrawLine(new Vector3(0,j * GridSize, 0), new Vector3(cols * GridSize, j * GridSize, 0));
     91             }
     92         }
     93 
     94     //D使用unity默认的OnDrawGizmos方法来绘制Gzimos
     95         private void OnDrawGizmos()
     96         {
     97             Color oldColor = Gizmos.color;//修改的这些属性都是静态属性,所以要在修改前保存其值,修改后再复原,防止后续使用该静态属性是修改后的
     98             Matrix4x4 oldMatrix = Gizmos.matrix;//修改的这些属性都是静态属性,所以要在修改前保存其值,修改后再复原,防止后续使用该静态属性是修改后的
     99             Gizmos.matrix = transform.localToWorldMatrix;//该语句可以为gizmos提供该transform位移,旋转,缩放等特性
    100 
    101             Gizmos.color = _normalColor;
    102             GridGizmos(_totalColumns,_totalRows);
    103             GridFrameGizmo(_totalColumns,_totalRows);
    104 
    105             Gizmos.color = oldColor;//恢复修改后的静态属性
    106             Gizmos.matrix = oldMatrix;//恢复修改后的静态属性
    107         }
    108 
    109         private void OnDrawGizmosSelected()
    110         {
    111             Color oldColor = Gizmos.color;
    112             Matrix4x4 oldMatrix = Gizmos.matrix;
    113             Gizmos.matrix = transform.localToWorldMatrix;
    114 
    115 
    116             Gizmos.color = _selectedColor;
    117             GridFrameGizmo(_totalColumns, _totalRows);
    118 
    119             Gizmos.color = oldColor;
    120             Gizmos.matrix = oldMatrix;
    121 
    122         }
    123 
    124         /// <summary>
    125         /// 将世界坐标转换为grid网格中的点坐标
    126         /// </summary>
    127         /// <param name="point">世界坐标</param>
    128         /// <returns></returns>
    129         public Vector3 WordToGridCoordinates(Vector3 point)
    130         {
    131             Vector3 gridPoint=new Vector3((int)((point.x-transform.position.x)/GridSize),(int)((point.y-transform.position.y)/GridSize),0.0f);
    132             return gridPoint;
    133         }
    134 
    135         /// <summary>
    136         /// Grid网格中的位置转换为世界坐标坐标
    137         /// </summary>
    138         /// <param name="col">行值</param>
    139         /// <param name="row">列值</param>
    140         /// <returns></returns>
    141         public Vector3 GridToWordCoordinates(int col,int row)
    142         {
    143             Vector3 wordPoint=new Vector3(transform.position.x+(col*GridSize/2.0f),transform.position.y+(row*GridSize/2.0f),0.0f);
    144             return wordPoint;
    145         }
    146         /// <summary>
    147         /// 坐标位置是否在网格边界内
    148         /// </summary>
    149         /// <param name="point"></param>
    150         /// <returns></returns>
    151         public bool IsInsideGridBounds(Vector3 point)
    152         {
    153             float minX = transform.position.x;
    154             float maxX = minX + _totalColumns*GridSize;
    155             float minY = transform.position.y;
    156             float maxY = minY + _totalRows*GridSize;
    157             return (point.x >= minX && point.x <= maxX && point.y >= minY && point.y <= maxY);
    158         }
    159     
    160         /// <summary>
    161             /// 坐标位置是否在网格边界内
    162             /// </summary>
    163             /// <param name="point"></param>
    164             /// <returns></returns>
    165     
    166         public bool IsInsideGridBounds(int col,int row)
    167         {
    168             return (col>=0&&col<_totalColumns&&row>=0&&row<=_totalRows);
    169         }
    170     }
    171 }

    2. 创建EditorUtil类,作为辅助工具类:

     1 using UnityEngine;
     2 using System.Collections;
     3 using UnityEditor;
     4 using UnityEditor.SceneManagement;
     5 
     6 namespace RunAndJump.LevelCreator  //为防止类名冲突,使用namespace时一个好的解决方案
     7 {
     8     public class EditorUtil
     9     {
    10 
    11         //创建新场景
    12         public static void NewScene()
    13         {
    14             //该方法后续过时,被下面方法替代:EditorApplication.SaveCurrentSceneIfUserWantsTo();
    15             EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo();//当前场景有未保存的东西是,弹出对话框提醒是否保存当前场景
    16             //该方法后续过时,被下面方法替代:EditorApplication.NewScene();
    17             EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
    18         }
    19 
    20 
    21         //清空场景
    22         public static void CleanScene()
    23         {
    24             GameObject[] allObjects = Object.FindObjectsOfType<GameObject>();
    25 
    26             foreach (GameObject go in allObjects)
    27             {
    28                 GameObject.DestroyImmediate(go);
    29             }
    30         }
    31 
    32         //创建新关卡
    33         public static void NewLevel()
    34         {
    35             NewScene();
    36             CleanScene();
    37 
    38             //可以在创建新关卡时添加上必要的游戏对象
    39             //add something...
    40 
    41             GameObject levelGo = new GameObject("Level");
    42             levelGo.transform.position=Vector3.zero;
    43             levelGo.AddComponent<Level>();
    44 
    45         }
    46     }
    47 }

    3. 创建MenuItems类,作为编辑器菜单工具类:

     1 using UnityEngine;
     2 using System.Collections;
     3 using UnityEditor;
     4 
     5 namespace RunAndJump.LevelCreator
     6 {
     7 
     8     //菜单项管理类,用来控制扩展方法在菜单项中显示
     9     public class MenuItems
    10     {
    11         [MenuItem("Tools/LevelCreator/NewLevelScene %q") ]
    12         private static void NewLevel()
    13         {
    14             EditorUtil.NewLevel();
    15         }
    16     }
    17 }

    4. 创建SnapToGridTest类,用来测试Leve类中方法:

     1 using UnityEngine;
     2 using System.Collections;
     3 using RunAndJump;
     4 
     5 [ExecuteInEditMode]//在editor场景模式下不用运行就调用
     6 public class SnapToGridTest : MonoBehaviour {
     7 
     8     // Update is called once per frame
     9     void Update ()
    10     {
    11         print(name+" in level");
    12         Vector3 gridCoord = Level.Instance.WordToGridCoordinates(transform.position);
    13         transform.position = Level.Instance.GridToWordCoordinates((int) gridCoord.x, (int) gridCoord.y);
    14     }
    15 
    16     private void OnDrawGizmos()
    17     {
    18         print("gizoms");
    19         Color oldColor = Gizmos.color;
    20         Gizmos.color = (Level.Instance.IsInsideGridBounds(transform.position)) ? Color.green : Color.red;
    21         Gizmos.DrawCube(transform.position,Vector3.one*Level.GridSize);
    22         Gizmos.color = oldColor;
    23     }
    24 }

    效果:

    我们通过MenuItems创建的菜单调用EditorUtil中创建场景的方法,场景中在OnDrawGizoms方法中绘制出自己的网格。现在创建一个空物体为其绑上SnapToGridTest脚本用来验证level中用来对齐坐标到网格和验证是否出界的方法。

  • 相关阅读:
    著名的二分查找的BUG
    C/C++ static用法
    浅谈C++虚函数
    git备忘(长久更新)
    【经典问题】最大子串和
    水波纹效果
    博客迁址 xpeng.scorpionstudio.com
    终于,我们的新产品Fotor Slideshow Maker上线了!!
    分享一款浏览器扩展--美图搜索-图片搜索工具
    分享网页微信防撤回插件
  • 原文地址:https://www.cnblogs.com/Firepad-magic/p/6399597.html
Copyright © 2011-2022 走看看