|
二. 使用Gizoms繪制網(wǎng)格及矩陣轉(zhuǎn)換使用1. 創(chuàng)建Leve類(lèi),作為場(chǎng)景控制類(lèi):1 using UnityEngine; 2 //使用namespace方便腳本管理 3 namespace RunAndJump { 4 //使用部分類(lèi)partial將類(lèi)依據(jù)不同的功能分布到各個(gè)文件中,便于功能區(qū)分個(gè)管理 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 //繪制內(nèi)部線條 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默認(rèn)的OnDrawGizmos方法來(lái)繪制Gzimos 95 private void OnDrawGizmos() 96 { 97 Color oldColor = Gizmos.color;//修改的這些屬性都是靜態(tài)屬性,所以要在修改前保存其值,修改后再?gòu)?fù)原,防止后續(xù)使用該靜態(tài)屬性是修改后的 98 Matrix4x4 oldMatrix = Gizmos.matrix;//修改的這些屬性都是靜態(tài)屬性,所以要在修改前保存其值,修改后再?gòu)?fù)原,防止后續(xù)使用該靜態(tài)屬性是修改后的 99 Gizmos.matrix = transform.localToWorldMatrix;//該語(yǔ)句可以為gizmos提供該transform位移,旋轉(zhuǎn),縮放等特性 100 101 Gizmos.color = _normalColor; 102 GridGizmos(_totalColumns,_totalRows); 103 GridFrameGizmo(_totalColumns,_totalRows); 104 105 Gizmos.color = oldColor;//恢復(fù)修改后的靜態(tài)屬性 106 Gizmos.matrix = oldMatrix;//恢復(fù)修改后的靜態(tài)屬性 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 /// 將世界坐標(biāo)轉(zhuǎn)換為grid網(wǎng)格中的點(diǎn)坐標(biāo) 126 /// </summary> 127 /// <param name="point">世界坐標(biāo)</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網(wǎng)格中的位置轉(zhuǎn)換為世界坐標(biāo)坐標(biāo) 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 /// 坐標(biāo)位置是否在網(wǎng)格邊界內(nèi) 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 /// 坐標(biāo)位置是否在網(wǎng)格邊界內(nèi) 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. 創(chuàng)建EditorUtil類(lèi),作為輔助工具類(lèi):1 using UnityEngine; 2 using System.Collections; 3 using UnityEditor; 4 using UnityEditor.SceneManagement; 5 6 namespace RunAndJump.LevelCreator //為防止類(lèi)名沖突,使用namespace時(shí)一個(gè)好的解決方案 7 { 8 public class EditorUtil 9 { 10 11 //創(chuàng)建新場(chǎng)景 12 public static void NewScene() 13 { 14 //該方法后續(xù)過(guò)時(shí),被下面方法替代:EditorApplication.SaveCurrentSceneIfUserWantsTo(); 15 EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo();//當(dāng)前場(chǎng)景有未保存的東西是,彈出對(duì)話框提醒是否保存當(dāng)前場(chǎng)景 16 //該方法后續(xù)過(guò)時(shí),被下面方法替代:EditorApplication.NewScene(); 17 EditorSceneManager.NewScene(NewSceneSetup.EmptyScene); 18 } 19 20 21 //清空?qǐng)鼍?/span> 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 //創(chuàng)建新關(guān)卡 33 public static void NewLevel() 34 { 35 NewScene(); 36 CleanScene(); 37 38 //可以在創(chuàng)建新關(guān)卡時(shí)添加上必要的游戲?qū)ο?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. 創(chuàng)建MenuItems類(lèi),作為編輯器菜單工具類(lèi):1 using UnityEngine; 2 using System.Collections; 3 using UnityEditor; 4 5 namespace RunAndJump.LevelCreator 6 { 7 8 //菜單項(xiàng)管理類(lèi),用來(lái)控制擴(kuò)展方法在菜單項(xiàng)中顯示 9 public class MenuItems 10 { 11 [MenuItem("Tools/LevelCreator/NewLevelScene %q") ] 12 private static void NewLevel() 13 { 14 EditorUtil.NewLevel(); 15 } 16 } 17 } 4. 創(chuàng)建SnapToGridTest類(lèi),用來(lái)測(cè)試Leve類(lèi)中方法:1 using UnityEngine; 2 using System.Collections; 3 using RunAndJump; 4 5 [ExecuteInEditMode]//在editor場(chǎng)景模式下不用運(yùn)行就調(diào)用 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 } 效果:我們通過(guò)MenuItems創(chuàng)建的菜單調(diào)用EditorUtil中創(chuàng)建場(chǎng)景的方法,場(chǎng)景中在OnDrawGizoms方法中繪制出自己的網(wǎng)格?,F(xiàn)在創(chuàng)建一個(gè)空物體為其綁上SnapToGridTest腳本用來(lái)驗(yàn)證level中用來(lái)對(duì)齊坐標(biāo)到網(wǎng)格和驗(yàn)證是否出界的方法。
|
|
|
來(lái)自: kiki的號(hào) > 《編輯器擴(kuò)展》