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中用来对齐坐标到网格和验证是否出界的方法。

 

转载于:https://www.cnblogs.com/Firepad-magic/p/6399597.html

Unity3D脚本18:可视化辅助设置类 Gizmos GizmosGizmos用于场景中给出一个可视化的调试或辅助设置。 所有的Gizmos绘制都必须在脚本的OnDrawGizmos或OnDrawGizmosSelected函数中完成。 OnDrawGizmos在每一帧都被调用。所有在OnDrawGizmos内部渲染的Gizmos都是可见的。 OnDrawGizmosSelected尽在脚本所附加的物体被选中时调用。 类变量 ◆ static var color : Color // 描述:设置下次绘制的Gizmos的颜色。 function OnDrawGizmosSelected() { Gizmos.color = Color.red; var direction = transform.TransformDirection(Vector3.forward) * 5; // 在物体的前方绘制一个5米长的线 Gizmos.DrawRay(transform.position, direction); } ◆ static var matrix : Matrix4x4 // 描述:设置用于渲染所有gizmos的矩阵。 类方法 ◆ Static function DrawCube(center:Vector3,size:Vector3):void // 描述:用center和size绘制一个立方体. Function OnDrawGizmosSelected(){ Gizmos.color=Color(1,0,0,5); // 在变换位置处绘制一个变透明的蓝色立方体 Gizmos.DrawCube(transform.position,Vector3(1,1,1)); } ◆ Static function DrawGUITexture(screenRect:Rect,texture:Texture,mat:Material=null):void // 描述:在屏幕坐标下绘制一个纹理。用于GUI背景。 ◆ Static function DrawGUITexture(screenRect:Rect,texture:Texture,leftBorder:int,rightBorder:int,topBorder:int,bottomBorder:int,mat:Material=null):void // 描述:在屏幕坐标下绘制一个纹理。用于GUI背景。 ◆ Static function Drawicon(center:Vector3,name:string):void // 描述:在世界位置center处绘制一个图标.这个图标被命名为name并放置在Assets/Gizmos文件夹或Unity.app/Resoutces文件夹.DrawIcon允许你在游戏中快速选择重要的物体。 在物体位置处绘制光源灯泡图标.因为我们在OnDrawGizmos函数内部调用它,在场景视图中 ,这个图标总是可点选的. function OnDrawGizmos(){ Gizmos DrawIcon(transform.position,”Light Gizmo.tiff”); } ◆ Static function DrawLine(from:Vector3,to:Vector3):void // 描述:绘制一条线从from到to. Var Larget:Transform; function OnDrawGizmosSelected(){ if(target != null) { Gizmos.color = Color.blue; //从transform到target绘制一条蓝色的线 Gizmos.DrawLine(transform.position,target.position); } } ◆ static function DrawRay(r:Ray):void static function DrawRay(from:Vector3,direction:Vector3):void // 描述:绘制一个射线从from开始到from + direction. ◆ function OnDrawGizmosSelected(){ Gizmos.color = Color.red; Direction = transform.TransformDirection(Vector3.forward)*5; Gizmos.DrawRay(transform.positon,direction); } ◆ Static function DrawSphere(center:Vector3,radius:flont):void // 描述:用center和randins绘制一个球体. Function OnDrawGizmosSelected(){ Gizmos.color = Color.yellow; // 在变换位置处绘制一个黄色的球体 Gizmos.DrawSphere(transtorm.position,1); } ◆ Static function DrawWireCube(center:Vector3, size: Vector3):void // 描述:用center和radius绘制一个线框立方体. Function OnDrawGizmosSelected(){ Gizmos.color = Color.yellow; //在变换位置处绘制一个黄色立方体 Gizmos.DrawWireCube (transtorm.position, Vector3(1,1,1)); } ◆ Static function DrawWireSphere(center:Vector3,radius:float):void // 描述:用center和radius绘制一个线框球体. Var explosionRadius = 5.0; Function OnDrawGizmosSelected(){ Gizmos.color = Color.white; //选中的时候显示爆炸路劲 Gizmos.DrawSphere(transtorm.position,explpsionRadius); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值