根据输入的物体生成随机成组的物体.
1 /// <summary> 2 /// 本脚本可以由输入的预制 生成以本物体为中心的随机预制,支持预制打组 3 /// 随机物体生成器(尤其试用于场景中静态物体随机摆放) 4 /// </summary> 5 using UnityEngine; 6 using System.Collections; 7 using System.Collections.Generic; 8 9 public class PrefabMixer : MonoBehaviour 10 { 11 [Tooltip("输入预制")] 12 public GameObject[] 13 inputPrefabs; 14 [Tooltip("生成多少组")] 15 public int 16 maxGroupsNum = 3; 17 [Tooltip("每组最多的个数")] 18 public int 19 maxEachGroupsNum = 5; 20 [Tooltip("距离中心的距离")] 21 public float 22 distanceToSpawn = 50f; 23 [Tooltip("缩放范围")] 24 public float 25 scaleToSpawn = 5f; 26 27 //一共生成多少组 28 public List<Transform> asteroidsGroupList = new List<Transform> (); 29 //生成的陨石总数 30 private List<Transform> asteroidsList = new List<Transform> (); 31 32 private Transform _cacheTransform; 33 34 void OnEnable () 35 { 36 ResetList (); 37 _cacheTransform = transform; 38 Debug.Log("Cache Transform !!"); 39 } 40 41 void OnDisable () 42 { 43 ResetList (); 44 } 45 46 public void GenerateAsteroids () 47 { 48 if (inputPrefabs == null || inputPrefabs.Length <= 0) 49 { 50 Debug.LogError ("预制不能为空哦 !"); 51 return; 52 } 53 54 if(_cacheTransform == null) 55 { 56 _cacheTransform = transform; 57 } 58 59 int tempMap = 0; 60 ResetList (); 61 //按组数来判断 62 while (asteroidsGroupList.Count < maxGroupsNum) { 63 64 Transform o = new GameObject ("AsteroidsMap_" + tempMap ++).transform; 65 o.localPosition = _cacheTransform.position; 66 o.localRotation = Quaternion.identity; 67 o.localScale = Vector3.one; 68 if(o.GetComponent<RotateSelf>() == null) 69 o.gameObject.AddComponent<RotateSelf>(); 70 o.GetComponent<RotateSelf>().speed = Random.Range(1,5f); 71 72 73 for (int i = 0; i<Random.Range(1,maxEachGroupsNum + 1); i++) { 74 if (GetRandomPrefab () == null) 75 continue; 76 GameObject asteroid = Instantiate (GetRandomPrefab ()) as GameObject; 77 asteroid.transform.parent = o.transform; 78 asteroid.name = "asteroid_" + GetRandomPrefab ().name + "_" + i; 79 asteroid.transform.localRotation = Quaternion.Euler (Random.Range (0, 360), Random.Range (0, 360), Random.Range (0, 360)); 80 asteroid.transform.localPosition = Random.insideUnitSphere * distanceToSpawn; 81 asteroid.transform.localScale = new Vector3 (Random.Range (1, scaleToSpawn), Random.Range (1, scaleToSpawn), Random.Range (1, scaleToSpawn)); 82 83 } 84 asteroidsGroupList.Add (o); 85 } 86 } 87 88 public void ResetList () 89 { 90 for (int i = 0; i < asteroidsGroupList.Count && asteroidsGroupList.Count > 0; i++) { 91 if(asteroidsGroupList [i] == null) 92 continue; 93 // #if UNITY_3_5 94 // asteroidsGroupList[i].gameObject.active = false; 95 // #endif 96 // asteroidsGroupList [i].gameObject.SetActive (false); 97 DestroyImmediate(asteroidsGroupList [i].gameObject); 98 99 } 100 101 if (asteroidsGroupList.Count > 0) 102 asteroidsGroupList.Clear (); 103 } 104 105 GameObject GetRandomPrefab () 106 { 107 if (inputPrefabs != null && inputPrefabs.Length > 0) 108 return inputPrefabs [Random.Range (0, inputPrefabs.Length)]; 109 return null; 110 } 111 112 }
1 /// <summary> 2 /// Prefab mixer editor. 3 /// </summary> 4 using UnityEditor; 5 using UnityEngine; 6 using System.Collections.Generic; 7 8 [CustomEditor(typeof(PrefabMixer))] 9 public class PrefabMixerEditor : Editor { 10 SerializedObject myTarget; 11 12 SerializedProperty maxEachGroupsNum; 13 SerializedProperty maxGroupsNum; 14 SerializedProperty distanceToSpawn; 15 SerializedProperty scaleToSpawn; 16 SerializedProperty GenerateAsteroids; 17 // SerializedProperty asteroidsGroupList; 18 19 20 PrefabMixer prefabMixer; 21 private List<Transform> asteroidsGroupList = new List<Transform> (); 22 23 void OnEnable() 24 { 25 myTarget = new SerializedObject(target); 26 27 maxGroupsNum = myTarget.FindProperty("maxGroupsNum"); 28 maxEachGroupsNum = myTarget.FindProperty("maxEachGroupsNum"); 29 distanceToSpawn = myTarget.FindProperty("distanceToSpawn"); 30 scaleToSpawn = myTarget.FindProperty("scaleToSpawn"); 31 // asteroidsGroupList = myTarget.FindProperty("asteroidsGroupList"); 32 33 //获得实例 34 prefabMixer = target as PrefabMixer; 35 asteroidsGroupList = prefabMixer.asteroidsGroupList; 36 37 } 38 39 private bool _showPrefabs = true; 40 41 public override void OnInspectorGUI() 42 { 43 myTarget.Update(); 44 45 EditorGUILayout.Separator(); 46 47 _showPrefabs = EditorGUILayout.Foldout(_showPrefabs, "单个预制"); 48 EditorGUIUtility.LookLikeInspector(); 49 if (_showPrefabs) { 50 ArrayGUI(myTarget, "inputPrefabs"); 51 } 52 EditorGUIUtility.LookLikeControls(); 53 54 EditorGUILayout.Separator(); 55 56 maxGroupsNum.intValue = EditorGUILayout.IntSlider("生成多少组", maxGroupsNum.intValue, 1, 1000); 57 EditorGUILayout.Separator(); 58 59 maxEachGroupsNum.intValue = EditorGUILayout.IntSlider("每组最多的个数", maxEachGroupsNum.intValue, 1, 100); 60 EditorGUILayout.Separator(); 61 62 distanceToSpawn.floatValue = EditorGUILayout.Slider("距离中心的距离", distanceToSpawn.floatValue, 1f, 100f); 63 EditorGUILayout.Separator(); 64 65 scaleToSpawn.floatValue = EditorGUILayout.Slider("缩放范围", scaleToSpawn.floatValue, 1f, 10f); 66 EditorGUILayout.Separator(); 67 68 if(GUILayout.Button("生成")) 69 { 70 prefabMixer.GenerateAsteroids(); 71 } 72 EditorGUILayout.Separator(); 73 74 if(GUILayout.Button("清空")) 75 { 76 prefabMixer.ResetList(); 77 } 78 EditorGUILayout.Separator(); 79 80 myTarget.ApplyModifiedProperties(); 81 } 82 83 84 void ArrayGUI(SerializedObject obj, string name) { 85 int size = obj.FindProperty(name + ".Array.size").intValue; 86 int newSize = EditorGUILayout.IntField("数量", size); 87 if (newSize != size) obj.FindProperty(name + ".Array.size").intValue = newSize; 88 EditorGUI.indentLevel = 3; 89 for (int i=0;i<newSize;i++) { 90 var prop = obj.FindProperty(string.Format("{0}.Array.data[{1}]", name, i)); 91 EditorGUILayout.PropertyField(prop); 92 } 93 EditorGUI.indentLevel = 0; 94 } 95 }