Unity场景道具模型拓展自定义编辑器
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Unity场景道具模型拓展自定义编辑器,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含10327字,纯文字阅读大概需要15分钟。
内容图文
(一)适用情况
当游戏主角进入特定的场景或者关卡,每个关卡需要加载不同位置的模型,道具等。这些信息需要先在unity编辑器里面配置好,一般由策划干这事,然后把这些位置道具信息保存在文件,当游戏主角进入后根据保存的文件信息加载模型道具。如 跑酷场景的金币 赛车赛道的道具
(二)实例文件格式 Json
需要导入SimpleJson 具体使用方法可以看我另外一篇《Unity游戏数据用Json保存》,有详细介绍 http://www.cnblogs.com/July7th/p/4808095.html
(三)图例
PathPropManager节点管理所有的道具信息.
(四)示例代码
// 道具类型; public enum PropsType { PT_ACCEL = 0, PT_MISSILE = 1, PT_BULLET = 2, PT_SHIELD = 3, PT_NONE = 4, }
/* * filename : PathPropManager.cs ; * function : 道具点管理编辑; * */ #if UNITY_EDITOR using UnityEngine; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEditor; using PathEdit; publicclass PathPropManager : MonoBehaviour { private PathProp[] mPathPropList; // 所有的道具点;public TextAsset mData = null; //道具点xml存储文件;public PropsType type = PropsType.PT_ACCEL; //默认道具;publicbool AlignGround = true; //是否对齐地面;publicint Layer = 0; //地面层级;publicfloat GroundHeight = 0.5f; //离地面距离;publicbool ShowIcon = true; //是否用图片显示路点上的道具;publicbool ShowCube = true; //是否用方块显示路点上的道具;void Awake() { } //刷新所有道具点;privatevoid UpdateList() { mPathPropList = transform.GetComponentsInChildren<PathProp>(); } //当删除某个道具点后自动重新计算序号;publicvoid ResetList() { UpdateList(); for (int i = 0; i < mPathPropList.Length; i++) { mPathPropList[i].gameObject.name = i.ToString(); mPathPropList[i].index = i; } } //从json表中重新加载道具会清除当前编辑的所有道具;publicbool CreatePropBySaveData() { if (mPathPropList == null) { returnfalse; } string fullPath = UnityEditor.AssetDatabase.GetAssetPath(mData); if (string.IsNullOrEmpty(fullPath)) { Debug.LogError("文件路径发生错误."); returnfalse; } int startIndex = ("Assets/Resources/").Length; string filestr = fullPath.Substring(startIndex, fullPath.LastIndexOf(‘.‘) - startIndex); PathPropReader wpr = new PathPropReader(filestr); List<PathPropAttributes> ppsa = wpr.Reader(); if (ppsa == null) { Debug.LogError("加载道具配置表失败"); } Transform[] trans = transform.GetComponentsInChildren<Transform>(); foreach (Transform child in trans) { if (child == transform) { continue; } DestroyImmediate(child.gameObject); } for (int i = 0; i < ppsa.Count; i++) { GameObject go = new GameObject(); go.transform.parent = transform; go.name = ppsa[i].index.ToString(); go.transform.position = ppsa[i].position; go.transform.rotation = Quaternion.Euler(ppsa[i].rotation); go.transform.localScale = ppsa[i].scale; PathProp pp = go.AddComponent<PathProp>(); pp.index = ppsa[i].index; pp.type = ppsa[i].type; } returntrue; } //保存道具点信息到json;publicbool CreateXmlByProps() { UpdateList(); if (mData == null) { Debug.LogError("没有找到保存的路径,请拖动一个json文件到PathPropManager的第一个参数."); returnfalse; } string fullPath = UnityEditor.AssetDatabase.GetAssetPath(mData); if (string.IsNullOrEmpty(fullPath)) { Debug.LogError("文件路径发生错误."); returnfalse; } int startIndex = ("Assets/Resources/").Length; string filestr = fullPath.Substring(startIndex, fullPath.LastIndexOf(‘.‘) - startIndex); PathPropReader pr = new PathPropReader(filestr); return pr.SaveData(mPathPropList); } //添加新的道具点;publicvoid AddProp() { UpdateList(); GameObject go = new GameObject(); go.transform.parent = transform; go.name = (mPathPropList.Length).ToString(); PathProp pp = go.AddComponent<PathProp>(); if (mPathPropList != null) { if (mPathPropList.Length < 1) { //生成的路标点移动到视窗内; Debug.Log("move to view"); UnityEditor.EditorApplication.ExecuteMenuItem("GameObject/Move To View"); } else { SetPathPropPos(go.transform, mPathPropList.Length - 1); } } pp.index = mPathPropList.Length; UnityEditor.Selection.activeTransform = go.transform; //UnityEditor.EditorApplication.ExecuteMenuItem("Edit/Lock View to Selected"); } //生成的道具点在最后一个路标点的前方,index为前一个路标的index;privatebool SetPathPropPos(Transform trans, int index) { if (index < 0 || index >= mPathPropList.Length) { returnfalse; } Vector3 pos = mPathPropList[index].transform.position + Vector3.up * 10f; Quaternion q = mPathPropList[index].transform.rotation; //生成的路标点在最后一个路标点的前方; //当前位置 = 上个路标点位置 + 上个路标点旋转 * 世界位置前 * 最大两点距离; trans.position = pos + q * Vector3.forward * (10); trans.rotation = q; returntrue; } void OnDrawGizmos() { UpdateList(); if (UnityEditor.Selection.activeTransform == null) { return; } //移动路点更新数据;if (UnityEditor.Selection.activeTransform.parent == transform) { int temIndex = int.Parse(UnityEditor.Selection.activeTransform.name); for (int i = 0; i < mPathPropList.Length; i++) { PathProp pp = mPathPropList[i].GetComponent<PathProp>(); if (pp == null) { Debug.LogError("get PathProp failed,i=" + i); return; } if (temIndex == pp.index) { if (AlignGround == false) { break; } //对齐地面; RaycastHit hit; if (Physics.Raycast(UnityEditor.Selection.activeTransform.position, -Vector3.up, out hit, 100.0f, 1 << Layer)) { //float dis = Vector3.Distance(Selection.activeTransform.position, hit.point); //调整高度; UnityEditor.Selection.activeTransform.position = new Vector3(UnityEditor.Selection.activeTransform.position.x, hit.point.y + GroundHeight, UnityEditor.Selection.activeTransform.position.z); } } } } //绘图; for (int i = 0; i < mPathPropList.Length; i++) { if (ShowIcon) { string str = ""; switch(mPathPropList[i].type) { case PropsType.PT_ACCEL: str = "js"; break; case PropsType.PT_BULLET: str = "zd"; break; case PropsType.PT_MISSILE: str = "dd"; break; case PropsType.PT_SHIELD: str = "fy"; break; } Gizmos.DrawIcon(mPathPropList[i].transform.position, str + ".png"); } if (ShowCube) { Gizmos.color = Color.red; Gizmos.DrawCube(mPathPropList[i].transform.position,Vector3.one); } } } } #endif
/* * filename : PathPropManagerWindow.cs ; * function : 道具点管理自定义编辑; * */ using UnityEngine; using System.Collections; using UnityEditor; using System.IO; [CustomEditor( typeof (PathPropManager))] public class PathPropManagerWindow : Editor { private PathPropManager mPathPropManager = null; void OnEnable() { } publicoverridevoid OnInspectorGUI() { mPathPropManager = target as PathPropManager; if (mPathPropManager == null) return; EditorGUILayout.Space(); GUILayout.BeginHorizontal(); //刷新路标点;if (GUILayout.Button("ReLoad", GUILayout.Height(20))) { mPathPropManager.CreatePropBySaveData(); } //获取Json文件数据 mPathPropManager.mData = (TextAsset)EditorGUILayout.ObjectField(mPathPropManager.mData, typeof(TextAsset), false); GUILayout.EndHorizontal(); EditorGUILayout.Space(); mPathPropManager.type = (PropsType)EditorGUILayout.EnumPopup("DefaultProp", mPathPropManager.type); mPathPropManager.Layer = EditorGUILayout.LayerField("AligndLayer", LayerMask.NameToLayer("Floor")); mPathPropManager.AlignGround = EditorGUILayout.Toggle("AlignGround", mPathPropManager.AlignGround); mPathPropManager.GroundHeight = EditorGUILayout.FloatField("GroundHeight", mPathPropManager.GroundHeight); mPathPropManager.ShowIcon = EditorGUILayout.Toggle("ShowIcon", mPathPropManager.ShowIcon); mPathPropManager.ShowCube = EditorGUILayout.Toggle("ShowCube", mPathPropManager.ShowCube); EditorGUILayout.Space(); GUILayout.BeginHorizontal(); //保存到Json文件;if (GUILayout.Button("SaveToXml", GUILayout.Height(20))) { if (mPathPropManager.CreateXmlByProps()) { Debug.Log("保存成功"); } } GUILayout.EndHorizontal(); EditorGUILayout.Space(); //标记路点已改变; EditorUtility.SetDirty(mPathPropManager); } }
/* * filename : PathPropReader.cs ; * function : 道具点l读取; * */ using UnityEngine; using System.Collections; using System.Collections.Generic; public class PathPropAttributes { public int index { get; set; } public Vector3 position { get; set; } public Vector3 rotation { get; set; } public Vector3 scale { get; set; } public PropsType type { get; set; } } publicclass PathPropReader { privatestring mPath { get; set; } private List<PathPropAttributes> mWpAList = new List<PathPropAttributes>(); // resources目录下的相对路径;如路径为Assets/Resouces/Xml/PathWayPoint/test.xml,path = Xml/PathWayPoint/test</param>public PathPropReader(string path) { if (mWpAList == null) { mWpAList = new List<PathPropAttributes>(); } if (string.IsNullOrEmpty(path)) { return; } mPath = path; } public List<PathPropAttributes> GetPositionList() { return mWpAList; } public List<PathPropAttributes> Reader() { if (string.IsNullOrEmpty(mPath)) { Debug.LogError("没有找到读取的路径."); returnnull; } mWpAList.Clear(); //读入; TextAsset ta = (TextAsset)Resources.Load(mPath); if (ta == null) { Debug.LogError("load props txt failed.path = "+mPath); returnnull; } string txt = ta.text; SimpleJSON.JSONArray jsArray = SimpleJSON.JSON.Parse(txt).AsArray; for (int i = 0; i < jsArray.Count; i++) { SimpleJSON.JSONNode node = jsArray[i]; PathPropAttributes wpa = new PathPropAttributes(); wpa.index = node["index"].AsInt; wpa.position = Helper.StringToVector3(Helper.DeleteChar(node["position"], ‘(‘, ‘)‘)); wpa.rotation = Helper.StringToVector3(Helper.DeleteChar(node["rotation"], ‘(‘, ‘)‘)); wpa.scale = Helper.StringToVector3(Helper.DeleteChar(node["scale"], ‘(‘, ‘)‘)); wpa.type = (PropsType)System.Enum.Parse(typeof(PropsType), node["type"]); mWpAList.Add(wpa); } return mWpAList; } #if UNITY_EDITOR publicbool SaveData(PathProp[] pathProps) { if (string.IsNullOrEmpty(mPath)) { Debug.LogError("没有找到保存的路径."); returnfalse; } if (pathProps.Length <= 0) { Debug.LogError("至少有一个道具点才能保存."); returnfalse; } //读入; TextAsset ta = (TextAsset)Resources.Load(mPath); string txt = ta.text; SimpleJSON.JSONArray jsArray = SimpleJSON.JSON.Parse(txt).AsArray; jsArray.RemoveAll(); string str = "{\"index\":\"0000\", \"position\":\"0000\" , \"rotation\":\"0000\", \"scale\":\"0000\" , \"type\":\"0000\"}"; for (int j = 0; j < pathProps.Length; j++) { SimpleJSON.JSONNode newNode = SimpleJSON.JSON.Parse(str); newNode["index"].Value = pathProps[j].index.ToString(); newNode["position"] = pathProps[j].gameObject.transform.position.ToString(); newNode["rotation"] = pathProps[j].gameObject.transform.rotation.eulerAngles.ToString(); newNode["scale"] = pathProps[j].gameObject.transform.localScale.ToString(); newNode["type"] = pathProps[j].type.ToString(); jsArray.Add(newNode); } //写入;string fp = Application.dataPath + "/Resources/" + mPath + ".json"; byte[] myByte = System.Text.Encoding.UTF8.GetBytes(jsArray.ToString()); using (System.IO.FileStream stream = new System.IO.FileStream(fp, System.IO.FileMode.Create)) { stream.Write(myByte, 0, myByte.Length); } returntrue; } #endif }
原文:http://www.cnblogs.com/July7th/p/4812813.html
内容总结
以上是互联网集市为您收集整理的Unity场景道具模型拓展自定义编辑器全部内容,希望文章能够帮你解决Unity场景道具模型拓展自定义编辑器所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。