using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class SoSkill : ScriptableObject
{
///
/// 攻击类型
/// 配置的组合类型应该为 0x0000 0000 0000 0000
/// 前8位表示攻击类型,后8位表示数据id索引
///
public enum E_AttackType
{
Sweep,
FlyObject,
}
///
/// 动画状态名哈希值
///
//public int action;
///
/// 动画时间
///
//public float time;
///
/// 动画帧率
///
//public float frameRate;
///
/// 可衔接的下一个技能id
///
//public int nextSkillId;
///
/// 前置技能id
///
//public int prevSkillId = -1;
public int effectOnTargetHead;
public int ghostEffectID;
public int rushArriveEffectID;
public bool acceptInput;
public bool hideWeapon = false;
public E_HitTestType hitTestType = E_HitTestType.Sector;// 碰撞检测类型
public E_CastBaseType bastType = E_CastBaseType.Self;// 碰撞检测基于类型
public int chkRange;// 矩形检测的宽度,扇形检测时候的角度
public float chkDistance;// 矩形检测的时候的距离, 扇形检测的时候的半径
public bool interrupt = true;
public bool forceMove = false;
#region 动画帧事件相关定义
public List animationEventList = new List();
[System.Serializable]
public class exAnimationClipEvent
{
public int index;
public E_FrameEventType frameEventType;
public int intParam;
}
#endregion
public static E_AttackType GetAttactType(int value)
{
return (E_AttackType)(value >> 16);
}
public static int GetFrameEventId(int value)
{
return (value & 0x00FFFF);
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(SoSkill))]
public class SoSkillEditor : Editor
{
//private AnimatorController m_AnimatorController;
//private AnimationClip m_AnimationClip;
//private float _animationClipLength;
private bool m_NewingData = false;
private int m_NewDataIndex = 0;
private E_FrameEventType m_NewFrameEventType;
private SoSkill.E_AttackType m_NewAttackType;
private int m_NewFrameEventId;
private int m_EditIndex = -1;
private E_FrameEventType m_EditFrameEventType;
private int m_EditFrameIdex;
private SoSkill.E_AttackType m_EditAttackType;
private int m_EditFrameEventId;
private void OnEnable()
{
m_NewDataIndex = 0;
m_EditIndex = -1;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
SoSkill _target = target as SoSkill;
_target.acceptInput = EditorGUILayout.Toggle("接受输入", _target.acceptInput);
_target.hideWeapon = EditorGUILayout.Toggle("隐藏武器", _target.hideWeapon);
_target.interrupt = EditorGUILayout.Toggle("是否能被打断", _target.interrupt);
_target.forceMove = EditorGUILayout.Toggle("移动至", _target.forceMove);
_target.effectOnTargetHead = EditorGUILayout.IntField("目标头顶特效", _target.effectOnTargetHead);
_target.rushArriveEffectID = EditorGUILayout.IntField("冲锋到达特效", _target.rushArriveEffectID);
_target.ghostEffectID = EditorGUILayout.IntField("幻影配置ID", _target.ghostEffectID);
EditorGUILayout.LabelField("[碰撞检测]");
_target.bastType = (E_CastBaseType)EditorGUILayout.EnumPopup("碰撞检测基于", _target.bastType);
_target.hitTestType = (E_HitTestType)EditorGUILayout.EnumPopup("碰撞检测方式", _target.hitTestType);
if (_target.hitTestType == E_HitTestType.Rect)
{
_target.chkRange = EditorGUILayout.IntField("矩形宽度(米)", _target.chkRange);
_target.chkDistance = EditorGUILayout.FloatField("检测距离(米)", _target.chkDistance);
}
else if (_target.hitTestType == E_HitTestType.Sector)
{
_target.chkRange = EditorGUILayout.IntField("扇形角度(0~359,0认为是360)", _target.chkRange);
_target.chkRange = Mathf.Clamp(_target.chkRange, 0, 359);
_target.chkDistance = EditorGUILayout.FloatField("检测半径(米)", _target.chkDistance);
}
// ---------------------------------------------------------------------------------
GUILayout.Space(5);
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
EditorGUILayout.LabelField("帧事件编辑");
GUILayout.FlexibleSpace();
Color _originalColor = GUI.color;
GUI.color = Color.green;
if (GUILayout.Button("+", EditorStyles.toolbarButton))
{
m_NewingData = true;
}
GUI.color = _originalColor;
EditorGUILayout.EndHorizontal();
DrawNewFrameEvent(_target);
DrawAnimationEvent(_target);
if (GUI.changed)
{
EditorUtility.SetDirty(target);
serializedObject.ApplyModifiedProperties();
}
}
private void DrawAnimationEvent(SoSkill target)
{
if (target.animationEventList.Count == 0)
{
EditorGUILayout.HelpBox("暂时没有任何的动画事件,请添加.", MessageType.Info);
return;
}
int _toDeleteIndex = -1;
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
EditorGUILayout.LabelField("帧", EditorStyles.wordWrappedLabel, GUILayout.Width(40));
EditorGUILayout.LabelField("方法", EditorStyles.wordWrappedLabel, GUILayout.Width(100));
EditorGUILayout.LabelField("配置", EditorStyles.wordWrappedLabel, GUILayout.Width(150));
EditorGUILayout.LabelField("", GUILayout.Width(80));
EditorGUILayout.LabelField("");
EditorGUILayout.EndHorizontal();
for (int i = 0; i < target.animationEventList.Count; ++i)
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
EditorGUILayout.LabelField(target.animationEventList[i].index.ToString(),
EditorStyles.wordWrappedLabel,
GUILayout.Width(40));
target.animationEventList[i].frameEventType = (E_FrameEventType)EditorGUILayout.EnumPopup(target.animationEventList[i].frameEventType,
EditorStyles.toolbarPopup,
GUILayout.Width(100));
if (target.animationEventList[i].frameEventType == E_FrameEventType.OnSkillEvent)
{
SoSkill.E_AttackType _type = SoSkill.GetAttactType(target.animationEventList[i].intParam);
int _id = SoSkill.GetFrameEventId(target.animationEventList[i].intParam);
string _content = string.Format("{0}: {1}", _type, _id);
if (GUILayout.Button(_content, EditorStyles.toolbarButton, GUILayout.Width(110)))
{
if (_type == SoSkill.E_AttackType.Sweep)
{
string _path = ResourcesPath.ResourcesOutAssetPath + "Refdata/ScriptableObject/SoSweepHit/SoSweepHit_" + _id + ".asset";
SoSweepHit _sh = AssetDatabase.LoadAssetAtPath(_path);
if (_sh != null)
{
Selection.activeObject = _sh;
}
}
else if (_type == SoSkill.E_AttackType.FlyObject)
{
string _path = ResourcesPath.ResourcesOutAssetPath + "Refdata/ScriptableObject/SoFlyObject/SoFlyObject_" + _id + ".asset";
SoFlyObject _fo = AssetDatabase.LoadAssetAtPath(_path);
if (_fo != null)
{
Selection.activeObject = _fo;
}
}
}
}
else if (target.animationEventList[i].frameEventType == E_FrameEventType.OnPlayEffect
|| target.animationEventList[i].frameEventType == E_FrameEventType.OnPlayAudio)
{
string _content = target.animationEventList[i].intParam.ToString();
if (GUILayout.Button(_content, EditorStyles.toolbarButton, GUILayout.Width(110)))
{
}
}
else if (target.animationEventList[i].frameEventType == E_FrameEventType.OnCreateGhost)
{
string _content = string.Format("Ghost: {0}", target.animationEventList[i].intParam);
if (GUILayout.Button(_content, EditorStyles.toolbarButton, GUILayout.Width(110)))
{
string _path = ResourcesPath.ResourcesOutAssetPath + "Refdata/ScriptableObject/SoGhostShadow/SoGhostShadow_" + target.animationEventList[i].intParam + ".asset";
SoGhostShadow _fo = AssetDatabase.LoadAssetAtPath(_path);
if (_fo != null)
{
Selection.activeObject = _fo;
}
}
}
else
{
GUILayout.Label("", EditorStyles.wordWrappedLabel, GUILayout.Width(102));
}
if (GUILayout.Button("编辑", EditorStyles.toolbarButton, GUILayout.Width(40)))
{
m_EditIndex = i;
m_EditAttackType = SoSkill.GetAttactType(target.animationEventList[i].intParam);
m_EditFrameEventId = SoSkill.GetFrameEventId(target.animationEventList[i].intParam);
m_EditFrameIdex = target.animationEventList[i].index;
m_EditFrameEventType = target.animationEventList[i].frameEventType;
}
if (GUILayout.Button("删除", EditorStyles.toolbarButton, GUILayout.Width(40)))
{
_toDeleteIndex = i;
}
EditorGUILayout.LabelField("");
EditorGUILayout.EndHorizontal();
if (i == m_EditIndex)
{
DrawEditorFrameEvent(target, target.animationEventList[i]);
}
}
if (_toDeleteIndex != -1)
{
target.animationEventList.RemoveAt(_toDeleteIndex);
}
}
private void DrawEditorFrameEvent(SoSkill target, SoSkill.exAnimationClipEvent clipEvent)
{
GUILayout.Space(4);
m_EditFrameEventType = (E_FrameEventType)EditorGUILayout.EnumPopup("方法名", m_EditFrameEventType);
if (clipEvent.frameEventType == E_FrameEventType.OnSkillEvent)
{
m_EditFrameIdex = EditorGUILayout.IntField("触发帧", m_EditFrameIdex);
m_EditAttackType = (SoSkill.E_AttackType)EditorGUILayout.EnumPopup("攻击方式", m_EditAttackType);
m_EditFrameEventId = EditorGUILayout.IntField("配置ID", m_EditFrameEventId);
}
else if (clipEvent.frameEventType == E_FrameEventType.OnPlayEffect)
{
m_EditFrameIdex = EditorGUILayout.IntField("触发帧", m_EditFrameIdex);
m_EditFrameEventId = EditorGUILayout.IntField("特效ID", m_EditFrameEventId);
}
else if (clipEvent.frameEventType == E_FrameEventType.OnSkillComplete
|| clipEvent.frameEventType == E_FrameEventType.OnSkillPrepare)
{
m_EditFrameIdex = EditorGUILayout.IntField("触发帧", m_EditFrameIdex);
}
else if (clipEvent.frameEventType == E_FrameEventType.OnAnimationPause
|| clipEvent.frameEventType == E_FrameEventType.OnTimePause)
{
m_EditFrameIdex = EditorGUILayout.IntField("触发帧", m_EditFrameIdex);
m_EditFrameEventId = EditorGUILayout.IntField("停顿时间(毫秒)", m_EditFrameEventId);
}
else if (clipEvent.frameEventType == E_FrameEventType.OnCreateGhost
|| clipEvent.frameEventType == E_FrameEventType.OnPlayAudio)
{
m_EditFrameIdex = EditorGUILayout.IntField("触发帧", m_EditFrameIdex);
m_EditFrameEventId = EditorGUILayout.IntField("配置ID", m_EditFrameEventId);
}
EditorGUILayout.BeginHorizontal();
if (SoSkill.GetAttactType(clipEvent.intParam) != m_EditAttackType
|| SoSkill.GetFrameEventId(clipEvent.intParam) != m_EditFrameEventId
|| m_EditFrameIdex != clipEvent.index
|| m_EditFrameEventType != clipEvent.frameEventType)
{
if (GUILayout.Button("修改"))
{
if (m_EditFrameEventType == E_FrameEventType.OnSkillEvent)
{
clipEvent.intParam = (((int)m_EditAttackType) << 16) | m_EditFrameEventId;
}
else
{
clipEvent.intParam = m_EditFrameEventId;
}
if (clipEvent.index != m_EditFrameIdex)
{
clipEvent.index = m_EditFrameIdex;
SortAnimationEventList(target);
}
clipEvent.frameEventType = m_EditFrameEventType;
m_EditIndex = -1;
}
}
if (GUILayout.Button("取消"))
{
m_EditIndex = -1;
}
EditorGUILayout.EndHorizontal();
GUILayout.Space(4);
}
private void DrawNewFrameEvent(SoSkill target)
{
if (m_NewingData)
{
GUILayout.Space(5);
m_NewDataIndex = EditorGUILayout.IntField("触发帧", m_NewDataIndex);
m_NewFrameEventType = (E_FrameEventType)EditorGUILayout.EnumPopup("方法名", m_NewFrameEventType);
if (m_NewFrameEventType == E_FrameEventType.OnSkillEvent)
{
m_NewAttackType = (SoSkill.E_AttackType)EditorGUILayout.EnumPopup("攻击方式", m_NewAttackType);
m_NewFrameEventId = EditorGUILayout.IntField("配置ID", m_NewFrameEventId);
}
else if (m_NewFrameEventType == E_FrameEventType.OnPlayEffect)
{
m_NewFrameEventId = EditorGUILayout.IntField("特效ID", m_NewFrameEventId);
}
else if (m_NewFrameEventType == E_FrameEventType.OnAnimationPause
|| m_NewFrameEventType == E_FrameEventType.OnTimePause)
{
m_NewFrameEventId = EditorGUILayout.IntField("停顿时间(毫秒)", m_NewFrameEventId);
}
else if (m_NewFrameEventType == E_FrameEventType.OnCreateGhost
|| m_NewFrameEventType == E_FrameEventType.OnPlayAudio)
{
m_NewFrameEventId = EditorGUILayout.IntField("配置ID", m_NewFrameEventId);
}
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("添加"))
{
SoSkill.exAnimationClipEvent _animationEvent = new SoSkill.exAnimationClipEvent();
_animationEvent.index = m_NewDataIndex;
_animationEvent.frameEventType = m_NewFrameEventType;
if (m_NewFrameEventType == E_FrameEventType.OnSkillEvent)
{
_animationEvent.intParam = (((int)m_NewAttackType) << 16) | m_NewFrameEventId;
}
else
{
_animationEvent.intParam = m_NewFrameEventId;
}
target.animationEventList.Add(_animationEvent);
SortAnimationEventList(target);
m_NewingData = false;
}
if (GUILayout.Button("取消"))
{
m_NewingData = false;
}
EditorGUILayout.EndHorizontal();
}
}
private void SortAnimationEventList(SoSkill target)
{
target.animationEventList.Sort((SoSkill.exAnimationClipEvent a, SoSkill.exAnimationClipEvent b) =>
{
if (a.index > b.index)
{
return 1;
}
else if (a.index < b.index)
{
return -1;
}
return 0;
});
}
}
#endif