博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity场景道具模型拓展自定义编辑器
阅读量:4914 次
发布时间:2019-06-11

本文共 12701 字,大约阅读时间需要 42 分钟。

(一)适用情况

当游戏主角进入特定的场景或者关卡,每个关卡需要加载不同位置的模型,道具等。这些信息需要先在unity编辑器里面配置好,一般由策划干这事,然后把这些位置道具信息保存在文件,当游戏主角进入后根据保存的文件信息加载模型道具。如 跑酷场景的金币 赛车赛道的道具 

(二)实例文件格式 Json

需要导入SimpleJson 具体使用方法可以看我另外一篇《》,有详细介绍 

(三)图例

 

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_EDITORusing UnityEngine;using System.Collections;using System.Collections.Generic;using System.IO;using UnityEditor;using PathEdit;public class PathPropManager : MonoBehaviour {    private PathProp[] mPathPropList; // 所有的道具点;    public TextAsset mData = null;  //道具点xml存储文件;    public PropsType type = PropsType.PT_ACCEL; //默认道具;    public bool AlignGround = true;     //是否对齐地面;    public int Layer = 0;               //地面层级;    public float GroundHeight = 0.5f;  //离地面距离;    public bool ShowIcon = true;    //是否用图片显示路点上的道具;    public bool ShowCube = true;    //是否用方块显示路点上的道具;    void Awake()    {    }    //刷新所有道具点;    private void UpdateList()    {        mPathPropList = transform.GetComponentsInChildren
(); } //当删除某个道具点后自动重新计算序号; public void ResetList() { UpdateList(); for (int i = 0; i < mPathPropList.Length; i++) { mPathPropList[i].gameObject.name = i.ToString(); mPathPropList[i].index = i; } } //从json表中重新加载道具会清除当前编辑的所有道具; public bool CreatePropBySaveData() { if (mPathPropList == null) { return false; } string fullPath = UnityEditor.AssetDatabase.GetAssetPath(mData); if (string.IsNullOrEmpty(fullPath)) { Debug.LogError("文件路径发生错误."); return false; } int startIndex = ("Assets/Resources/").Length; string filestr = fullPath.Substring(startIndex, fullPath.LastIndexOf('.') - startIndex); PathPropReader wpr = new PathPropReader(filestr); List
ppsa = wpr.Reader(); if (ppsa == null) { Debug.LogError("加载道具配置表失败"); } Transform[] trans = transform.GetComponentsInChildren
(); 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
(); pp.index = ppsa[i].index; pp.type = ppsa[i].type; } return true; } //保存道具点信息到json; public bool CreateXmlByProps() { UpdateList(); if (mData == null) { Debug.LogError("没有找到保存的路径,请拖动一个json文件到PathPropManager的第一个参数."); return false; } string fullPath = UnityEditor.AssetDatabase.GetAssetPath(mData); if (string.IsNullOrEmpty(fullPath)) { Debug.LogError("文件路径发生错误."); return false; } int startIndex = ("Assets/Resources/").Length; string filestr = fullPath.Substring(startIndex, fullPath.LastIndexOf('.') - startIndex); PathPropReader pr = new PathPropReader(filestr); return pr.SaveData(mPathPropList); } //添加新的道具点; public void AddProp() { UpdateList(); GameObject go = new GameObject(); go.transform.parent = transform; go.name = (mPathPropList.Length).ToString(); PathProp pp = go.AddComponent
(); 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; private bool SetPathPropPos(Transform trans, int index) { if (index < 0 || index >= mPathPropList.Length) { return false; } 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; return true; } 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
(); 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
PathPropManager.cs
/* * 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()    {    }    public override void 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);    }}
PathPropManagerWindow.cs
/* * 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; }    }    public class PathPropReader    {        private string mPath { get; set; }        private List
mWpAList = new List
(); // resources目录下的相对路径;如路径为Assets/Resouces/Xml/PathWayPoint/test.xml,path = Xml/PathWayPoint/test public PathPropReader(string path) { if (mWpAList == null) { mWpAList = new List
(); } if (string.IsNullOrEmpty(path)) { return; } mPath = path; } public List
GetPositionList() { return mWpAList; } public List
Reader() { if (string.IsNullOrEmpty(mPath)) { Debug.LogError("没有找到读取的路径."); return null; } mWpAList.Clear(); //读入; TextAsset ta = (TextAsset)Resources.Load(mPath); if (ta == null) { Debug.LogError("load props txt failed.path = "+mPath); return null; } 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 public bool SaveData(PathProp[] pathProps) { if (string.IsNullOrEmpty(mPath)) { Debug.LogError("没有找到保存的路径."); return false; } if (pathProps.Length <= 0) { Debug.LogError("至少有一个道具点才能保存."); return false; } //读入; 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); } return true; }#endif }
PathPropReader.cs

 

转载于:https://www.cnblogs.com/July7th/p/4812813.html

你可能感兴趣的文章
java中Class的使用详解
查看>>
css,js文件后面加一个版本号
查看>>
webpack第一节(2)
查看>>
python之asyncio三种应用方法
查看>>
Laravel 的文件存储 - Storage
查看>>
转:[Server] 在 Windows 上安裝 PHP 5.3 開發環境
查看>>
【IE6的疯狂之二】IE6中PNG Alpha透明(全集)
查看>>
第一个Shell脚本
查看>>
C++ 小笔记
查看>>
zabbix 安装rpm
查看>>
PhantomJS:Full web stack,No browser required
查看>>
Git远程操作详解
查看>>
java课后思考问题(七)
查看>>
5.9 容器
查看>>
创建oracle数据库的表空间、用户、目录、导入\导出文件等信息
查看>>
php禁止浏览器使用缓存页面的方法
查看>>
django的模型类管理器-----------数据库操作的封装
查看>>
java 回调
查看>>
CF1100E Andrew and Taxi 二分答案+拓扑排序
查看>>
子弹朝向问题的解决,移动方法的编写
查看>>