目标:实现一个数据编辑器,编辑敌人属性 波数等
该应用在XYGame 里面应用 http://www.dreamyouxi.com/xygame.html
项目中的相关文件有
EnemyPrototype.cs
OneEnemyBornData.cs
TerrainObjectEnemyBornPointData.cs
EnemyBornEdit.cs
EnemyPrototypeEdit.cs
EnemyPrototypeEditor.cs
1.怪物种类原型编辑器
EnemyPrototypeEdit.cs
/*
* Author: caoshanshan
* Email: me@dreamyouxi.com
怪物原型 编辑器
*/
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
//[RequireComponent(typeof(EnemyPrototypeEditor))]
[CustomEditor(typeof(EnemyPrototypeEditor))]
public class EnemyPrototypeEdit : Editor
{
static int damage = 200;
static int exp = 100;
static int hp = 100;
static string code="202001";
static EnemyProtoType type = EnemyProtoType.小怪1;
public override void OnInspectorGUI()
{
serializedObject.Update();
DrawDefaultInspector();
EnemyPrototypeEditor obj = target as EnemyPrototypeEditor;
if (obj == null) return;
{
EnemyPrototype[] comps = obj.gameObject.GetComponents<EnemyPrototype>();
GUILayout.Label("--------怪物原型编辑器---------");
GUILayout.Label("--------生成设置---------");
GUILayout.BeginHorizontal();
GUILayout.Label("怪物Code");
code = EditorGUILayout.TextField(code, GUILayout.Width(100));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("血量hp");
hp = EditorGUILayout.IntField(hp, GUILayout.Width(100));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("经验exp");
exp = EditorGUILayout.IntField(exp, GUILayout.Width(100));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("基础伤害damage");
damage = EditorGUILayout.IntField(damage, GUILayout.Width(100));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("类型type");
type = (EnemyProtoType)EditorGUILayout.EnumPopup("", type, GUILayout.Width(100)); // 单选
GUILayout.EndHorizontal();
}
GUILayout.BeginHorizontal();
if (GUILayout.Button("添加一个原型"))
{
EnemyPrototype data = obj.gameObject.AddComponent<EnemyPrototype>();
data.hp = hp;
data.type = type;
data.damage = damage;
data.exp = exp;
data.code = code;
serializedObject.ApplyModifiedProperties();
}
if (GUILayout.Button("倒序删除一个原型"))
{
Component[] comp = obj.gameObject.GetComponents<EnemyPrototype>();
if (comp != null && comp.Length >= 1)
{
if (comp[comp.Length - 1] != null)
{
GameObject.DestroyImmediate(comp[comp.Length - 1]);
serializedObject.ApplyModifiedProperties();
}
}
}
if (GUILayout.Button("清空"))
{
Component[] comp = obj.gameObject.GetComponents<EnemyPrototype>();
foreach (Component cm in comp)
{
GameObject.DestroyImmediate(cm);
}
serializedObject.ApplyModifiedProperties();
}
GUILayout.EndHorizontal();
serializedObject.Update();
}
}
#else
public class EnemyPrototypeEdit : MonoBehaviour
{
}
#endif
2.怪物波数等 编辑器
EnemyBornEdit.cs
/*
* Author: caoshanshan
* Email: me@dreamyouxi.com
刷新点 编辑器
*/
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
//[RequireComponent(typeof(TerrainObjectEnemyBornPointData))]
[CustomEditor(typeof(TerrainObjectEnemyBornPointData))]
//[CanEditMultipleObjects]
public class EnemyBornEdit : Editor
{
void OnEnable()
{
}
static float time_add = 1;
static string type = "202001";// 原型类型
static int count = 10;//数量
public override void OnInspectorGUI()
{
serializedObject.Update();
DrawDefaultInspector();
TerrainObjectEnemyBornPointData obj = target as TerrainObjectEnemyBornPointData;
if (obj == null) return;
{
OneEnemyBornData[] comps = obj.gameObject.GetComponents<OneEnemyBornData>();
GUILayout.Label("--------该刷新点数据汇总---------");
GUILayout.BeginHorizontal();
GUILayout.Label("敌人总数:");
GUILayout.Label(comps.Length.ToString(), GUILayout.Width(50));
GUILayout.EndHorizontal();
GUILayout.Label("-------批量生成设置---------");
GUILayout.BeginHorizontal();
GUILayout.Label("每个单位时间增量");
time_add = EditorGUILayout.FloatField(time_add, GUILayout.Width(100));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("怪物原型");
type = EditorGUILayout.TextField(type, GUILayout.Width(100));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("生成个数");
count = EditorGUILayout.IntField(count, GUILayout.Width(100));
GUILayout.EndHorizontal();
}
GUILayout.BeginHorizontal();
if (GUILayout.Button("顺序批量添加"))
{
OneEnemyBornData[] comps = obj.gameObject.GetComponents<OneEnemyBornData>();
float t = 0f;
if (comps.Length > 0)
{
t = time_add + comps[comps.Length - 1].time;
}
for (int i = 0; i < count; i++)
{
OneEnemyBornData data = obj.gameObject.AddComponent<OneEnemyBornData>();
data.time = t;
data.enemy_code = type;
t += time_add;
}
serializedObject.ApplyModifiedProperties();
}
if (GUILayout.Button("顺序添加一个"))
{
OneEnemyBornData[] comps = obj.gameObject.GetComponents<OneEnemyBornData>();
OneEnemyBornData data = obj.gameObject.AddComponent<OneEnemyBornData>();
if (comps.Length > 0)
{
data.time = time_add + comps[comps.Length - 1].time;
data.enemy_code = type;
}
serializedObject.ApplyModifiedProperties();
}
if (GUILayout.Button("倒序删除"))
{
Component[] comp = obj.gameObject.GetComponents<OneEnemyBornData>();
if (comp != null && comp.Length >= 1)
{
if (comp[comp.Length - 1] != null)
{
GameObject.DestroyImmediate(comp[comp.Length - 1]);
serializedObject.ApplyModifiedProperties();
}
}
}
if (GUILayout.Button("清空"))
{
Component[] comp = obj.gameObject.GetComponents<OneEnemyBornData>();
foreach (Component cm in comp)
{
GameObject.DestroyImmediate(cm);
}
serializedObject.ApplyModifiedProperties();
}
GUILayout.EndHorizontal();
serializedObject.Update();
}
}
#else
public class EnemyBornEdit : MonoBehaviour
{
}
#endif
3.以上数据准备好后 ,接入代码
CustomObjects.cs
/// <summary>
/// Enemy 启动器
/// </summary>
class EnemyLauncher : Model
{
public OneEnemyBornData data = null;
public static EnemyLauncher Create(OneEnemyBornData data)
{
EnemyLauncher ret = new EnemyLauncher();
ret.Init();
ret.data = data;
return ret;
}
public override void UpdateMS()
{
if (tick.Tick())
{
return;
}
EnemyPrototype proto = EnemyPrototype.GetPrototype(data.enemy_code);
if (proto != null)
{
Enemy enemy = EnemyMgr.Create(proto.GetClassType());
// one enemy data
enemy.team = 333;
enemy.x = data.gameObject.transform.localPosition.x;
enemy.z = data.gameObject.transform.localPosition.y;
enemy.y = 2;
//prototype
enemy.hp = proto.hp;
enemy.current_hp = enemy.hp;
enemy.damage = proto.damage;
enemy.exp = proto.exp;
}
this.SetInValid();
}
public override void OnEnter()
{
tick.SetMax(Utils.ConvertToFPS(data.time));
}
Counter tick = Counter.Create();
}
/// <summary>
/// 刷新点
/// 只提供数据
/// </summary>
public class TerrainObjectEnemyBornPoint : CustomObject
{
public override bool Init()
{
base.Init();
return true;
}
public override void UpdateMS()
{
}
public override void InitWithData(object obj)
{
TerrainObjectEnemyBornPointData data = obj as TerrainObjectEnemyBornPointData;
this.x = data.gameObject.transform.localPosition.x;
this.y = data.gameObject.transform.localPosition.y;
this.z = data.gameObject.transform.localPosition.z;
this.name = data.gameObject.name;
OneEnemyBornData[] enemys = data.gameObject.GetComponents<OneEnemyBornData>();
foreach (OneEnemyBornData enemy in enemys)
{//初始化 启动器
EnemyLauncher launch = EnemyLauncher.Create(enemy); // ModelMgr.Create<EnemyLauncher>();
ModelMgr.ins.Add(launch);
}
Debug.Log("TerrainObjectEnemyBornPoint OK " + enemys.Length);
}
}
TODO:由于目前数据是以预设方式提供,发行时 应该序列化为json 或xml