public static IAttributeState operator +(AttributeStateAdditional a, IAttributeState b) { if (a == null || b == null) { return(null); } AttributeStateAdditional result = new AttributeStateAdditional(); Type t = typeof(IAttributeState); PropertyInfo[] infos = t.GetProperties(); foreach (PropertyInfo info in infos) { MethodInfo getMethod = info.GetGetMethod(); MethodInfo setMethod = info.GetSetMethod(); if (getMethod != null && setMethod != null) { if (info.PropertyType.Equals(typeof(float))) { float a_v = (float)getMethod.Invoke(a, null); float b_v = (float)getMethod.Invoke(b, null); float r_v = a_v + b_v; setMethod.Invoke(result, new object[] { r_v }); } } } //处理数组的相加 float[] aElementResistances = a.ElementResistances; float[] bElementResistances = b.ElementResistances; if (aElementResistances.Length == bElementResistances.Length) { float[] elementResistances = new float[result.ElementResistances.Length]; for (int i = 0; i < result.ElementResistances.Length; i++) { elementResistances[i] = aElementResistances[i] + bElementResistances[i]; } result.ElementResistances = elementResistances; } float[] aStateResistances = a.StateResistances; float[] bStateResistances = b.StateResistances; if (aStateResistances.Length == bStateResistances.Length) { float[] stateResistances = new float[result.StateResistances.Length]; for (int i = 0; i < result.StateResistances.Length; i++) { stateResistances[i] = aStateResistances[i] + bStateResistances[i]; } result.StateResistances = stateResistances; } return(result); }
public void Init() { RoleOfRaceData roleOfRaceData = DataCenter.Instance.GetMetaData <RoleOfRaceData>(); RoleOfRaceInfoStruct roleOfRaceInfoStruct = roleOfRaceData[roleOfRace]; if (roleOfRaceInfoStruct != null) { //重置属性 IAttributeState tempAdditional = new AttributeStateAdditional();// MonsterBaseAttribute.Clone();//赋值出来一份用来计算种族成长 tempAdditional.SetRoleOfRaceAddition(roleOfRaceInfoStruct); tempAdditional.Power = MonsterBaseAttribute.Power; tempAdditional.Mental = MonsterBaseAttribute.Mental; tempAdditional.Quick = MonsterBaseAttribute.Quick; MonsterBaseAttribute = (AttributeStateAdditional)(MonsterBaseAttribute + tempAdditional); MonsterBaseAttribute.Power /= 2; MonsterBaseAttribute.Quick /= 2; MonsterBaseAttribute.Mental /= 2; //系数 PhysicAttackFactor = new PhysicAttackFactor() { IncreaseRatioInjuryFactor = roleOfRaceInfoStruct.physicAttackToDamageRateRatio, MinimumDamageFactor = roleOfRaceInfoStruct.physicQuickToMinDamageRatio }; PhysicDefenseFactor = new PhysicDefenseFactor() { CoefficientRatioReducingDamageFactor = roleOfRaceInfoStruct.physicDefenseToHurtRateRatio, ImmunityInjury = roleOfRaceInfoStruct.physicQuickToHurtExemptRatio }; MagicAttackFactor = new MagicAttackFactor() { IncreaseRatioInjuryFactor = roleOfRaceInfoStruct.magicAttackToDamageRateRatio }; MagicDefenseFactor = new MagicDefenseFactor() { CoefficientRatioReducingDamageFactor = roleOfRaceInfoStruct.magicDefenseToHurtRateRatio }; } }
void OnGUI() { if (monsterDataInfoCollections == null || monsterTypeToFieldNameDic == null || monsterAITypeToFieldNameDic == null) { return; } //获取当前场景对象 MonsterDataInfoCollection monsterDataInfoCollection = monsterDataInfoCollections.FirstOrDefault(temp => string.Equals(temp.sceneName, selectScene)); EditorGUILayout.BeginHorizontal(); #region 保存 场景 等按钮 EditorGUILayout.BeginVertical(GUILayout.Width(200)); if (GUILayout.Button("保存", GUILayout.Width(100))) { string valueText = SerializeNow(monsterDataInfoCollections); File.WriteAllText(dataDirectoryPath + "/Monster.txt", valueText, Encoding.UTF8); EditorUtility.DisplayDialog("提示!", "保存成功", "确认"); } if (monsterDataInfoCollection == null && GUILayout.Button("添加本场景", GUILayout.Width(100))) { monsterDataInfoCollection = new MonsterDataInfoCollection() { sceneName = selectScene }; MonsterDataInfoCollection[] tempArray = new MonsterDataInfoCollection[monsterDataInfoCollections.Length + 1]; Array.Copy(monsterDataInfoCollections, tempArray, monsterDataInfoCollections.Length); tempArray[tempArray.Length - 1] = monsterDataInfoCollection; monsterDataInfoCollections = tempArray; } saveSceneScrollPostion = EditorGUILayout.BeginScrollView(saveSceneScrollPostion); #region 显示所有的场景按钮 bool changedScene = false; List <MonsterDataInfoCollection> monsterDataInfoCollectionList = new List <MonsterDataInfoCollection>(monsterDataInfoCollections); for (int i = 0; i < monsterDataInfoCollections.Length; i++) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("删除", GUILayout.Width(35))) { if (EditorUtility.DisplayDialog("警告!", "请再次确认是否删除该场景的怪物配置信息?", "确认删除", "取消删除")) { monsterDataInfoCollectionList.Remove(monsterDataInfoCollections[i]); changedScene = true; } } if (monsterDataInfoCollections[i] == monsterDataInfoCollection) { EditorGUILayout.Toggle(true, GUILayout.Width(20)); } GUILayout.Button(monsterDataInfoCollections[i].sceneName); EditorGUILayout.EndHorizontal(); } if (changedScene) { monsterDataInfoCollections = monsterDataInfoCollectionList.ToArray(); if (!monsterDataInfoCollectionList.Contains(monsterDataInfoCollection)) { monsterDataInfoCollection = null; selectMonsterID = -1; } } #endregion EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical(); #endregion #region 择删除添加怪物id EditorGUILayout.BeginVertical(GUILayout.Width(175)); if (monsterDataInfoCollection != null) { if (GUILayout.Button("添加新策略", GUILayout.Width(75))) { int id = 0; if (monsterDataInfoCollection.MonsterDataInofs.Count > 0) { id = monsterDataInfoCollection.MonsterDataInofs.Max(temp => temp.ID) + 1; } monsterDataInfoCollection.MonsterDataInofs.Add(new MonsterDataInfo() { ID = id, Briefly = "空" }); } monsterIDScrollPostion = EditorGUILayout.BeginScrollView(monsterIDScrollPostion, GUILayout.Width(170)); List <MonsterDataInfo> tempMonsterDataInfos = new List <MonsterDataInfo>(monsterDataInfoCollection.MonsterDataInofs); foreach (MonsterDataInfo monsterDataInfo in tempMonsterDataInfos) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("删除", GUILayout.Width(35))) { if (EditorUtility.DisplayDialog("警告!", "请再次确认是否删除怪物配置信息?", "确认删除", "取消删除")) { monsterDataInfoCollection.MonsterDataInofs.Remove(monsterDataInfo); } } if (monsterDataInfo.ID == selectMonsterID) { EditorGUILayout.Toggle(true, GUILayout.Width(20)); } if (GUILayout.Button(monsterDataInfo.Briefly)) { selectMonsterID = monsterDataInfo.ID; //在这里重新赋值区域位置 if (rangeObj != null) { rangeObj.transform.position = monsterDataInfo.Center; rangeObj.transform.localScale = new Vector3(monsterDataInfo.Range * 2, monsterDataInfo.Range * 2, monsterDataInfo.Range * 2); } } EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndScrollView(); } EditorGUILayout.EndVertical(); #endregion //集合不等于0 选择的id大于等于0 并且存在该id if (monsterDataInfoCollection != null && selectMonsterID >= 0 && monsterDataInfoCollection.MonsterDataInofs.Count(temp => temp.ID == selectMonsterID) > 0) { MonsterDataInfo monsterDataInfo = monsterDataInfoCollection.MonsterDataInofs.FirstOrDefault(temp => temp.ID == selectMonsterID); #region 怪物的基本信息 EditorGUILayout.BeginVertical(GUILayout.Width(350)); baseDataScrollPostion = EditorGUILayout.BeginScrollView(baseDataScrollPostion); monsterDataInfo.Briefly = EditorGUILayout.TextField("配置:", monsterDataInfo.Briefly); monsterDataInfo.Explane = EditorGUILayout.TextField("说明:", monsterDataInfo.Explane, GUILayout.Width(300), GUILayout.Height(150)); string[] monsterTypeExplans = monsterTypeToFieldNameDic.Values.ToArray(); int[] monsterTypeValues = monsterTypeToFieldNameDic.Keys.Select(temp => (int)temp).ToArray(); int monsterTypeValue = EditorGUILayout.IntPopup("怪物类型:", (int)monsterDataInfo.MonsterType, monsterTypeExplans, monsterTypeValues); monsterDataInfo.MonsterType = (EnumMonsterType)monsterTypeValue; if (rangeObj != null) { rangeObj.transform.forward = Vector3.forward; monsterDataInfo.Center = rangeObj.transform.position; Vector3 scale = rangeObj.transform.localScale; float minRange = scale.x; minRange = scale.y < minRange ? scale.y : minRange; minRange = scale.z < minRange ? scale.z : minRange; monsterDataInfo.Range = minRange / 2; } monsterDataInfo.Center = EditorGUILayout.Vector3Field("区域中心:", monsterDataInfo.Center); monsterDataInfo.Range = EditorGUILayout.FloatField("区域范围:", monsterDataInfo.Range); if (rangeObj != null) { rangeObj.transform.position = monsterDataInfo.Center; rangeObj.transform.localScale = new Vector3(monsterDataInfo.Range * 2, monsterDataInfo.Range * 2, monsterDataInfo.Range * 2); } monsterDataInfo.Offset = EditorGUILayout.FloatField("高度偏差值:", monsterDataInfo.Offset); monsterDataInfo.Experience = EditorGUILayout.IntField("经验值:", monsterDataInfo.Experience); GameObject monsterPrefab = EditorGUILayout.ObjectField("怪物预设体:", monsterDataInfo.MonsterPrefab, typeof(GameObject), false) as GameObject; if (monsterPrefab == null) { monsterDataInfo.monsterPrefabName = ""; } else if (!string.Equals(monsterPrefab.name, monsterDataInfo.monsterPrefabName)) { string monsterPrefabName = monsterPrefab.name; if (monsterPrefabDic.ContainsKey(monsterPrefabName)) { monsterDataInfo.monsterPrefabName = monsterPrefabName; } } //设置属性 EditorGUILayout.BeginHorizontal(); if (monsterDataInfo.MonsterBaseAttribute == null) { monsterDataInfo.MonsterBaseAttribute = new AttributeStateAdditional(); } if (GUILayout.Button("设置属性")) { AttributeStateAdditionalEditor attributeStateAdditionalEditor = EditorWindow.GetWindow <AttributeStateAdditionalEditor>(); attributeStateAdditionalEditor.Show(); attributeStateAdditionalEditor.Target = monsterDataInfo.MonsterBaseAttribute; } if (GUILayout.Button("复制", GUILayout.Width(35))) { AttributeStateAdditional_Copy = monsterDataInfo.MonsterBaseAttribute.Clone(); } if (AttributeStateAdditional_Copy != null && GUILayout.Button("粘贴", GUILayout.Width(35)) && EditorUtility.DisplayDialog("请再次确认!", "是否覆盖当前数据?", "是", "否")) { monsterDataInfo.MonsterBaseAttribute = AttributeStateAdditional_Copy.Clone(); } EditorGUILayout.EndHorizontal(); //设置种族 List <RoleOfRace> roleOfRaceValues = roleOfRaceToFieldNameDic.Select(temp => temp.Key).ToList(); string[] roleOfRaceExplans = roleOfRaceToFieldNameDic.Select(temp => temp.Value).ToArray(); int roleOfRaceIndex = roleOfRaceValues.IndexOf(monsterDataInfo.roleOfRace); roleOfRaceIndex = EditorGUILayout.Popup("种族:", roleOfRaceIndex, roleOfRaceExplans); if (roleOfRaceIndex > -1) { monsterDataInfo.roleOfRace = roleOfRaceValues[roleOfRaceIndex]; } //设置显示和隐藏条件 List <TaskMap.Enums.EnumTaskProgress> taskProgressValues = taskProgressToFieldNameDic.Select(temp => temp.Key).ToList(); string[] taskProgressExplans = taskProgressToFieldNameDic.Select(temp => temp.Value).ToArray(); Action <List <KeyValuePair <int, TaskMap.Enums.EnumTaskProgress> > > ShowHideTaskAction = (targetList) => { for (int i = 0; i < targetList.Count; i++) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("×", GUILayout.Width(20)) && EditorUtility.DisplayDialog("请再次确认!", "是否删除该条件?", "确认删除", "取消")) { targetList.RemoveAt(i); EditorGUILayout.EndHorizontal(); break; } KeyValuePair <int, TaskMap.Enums.EnumTaskProgress> tempValue = targetList[i]; EditorGUILayout.LabelField("任务ID:", GUILayout.Width(40)); int tempKey = EditorGUILayout.IntField(tempValue.Key, GUILayout.Width(30)); EditorGUILayout.LabelField("任务状态:", GUILayout.Width(50)); int index = taskProgressValues.IndexOf(tempValue.Value); index = EditorGUILayout.Popup(index, taskProgressExplans, GUILayout.Width(50)); TaskMap.Enums.EnumTaskProgress tempTaskProgress = tempValue.Value; if (index >= 0) { tempTaskProgress = taskProgressValues[index]; } targetList[i] = new KeyValuePair <int, TaskMap.Enums.EnumTaskProgress>(tempKey, tempTaskProgress); EditorGUILayout.EndHorizontal(); } }; //显示条件 if (monsterDataInfo.TaskToShowList == null) { monsterDataInfo.TaskToShowList = new List <KeyValuePair <int, TaskMap.Enums.EnumTaskProgress> >(); } if (GUILayout.Button("添加显示条件")) { monsterDataInfo.TaskToShowList.Add(new KeyValuePair <int, TaskMap.Enums.EnumTaskProgress>()); } ShowHideTaskAction(monsterDataInfo.TaskToShowList); //隐藏条件 if (monsterDataInfo.TaskToHideList == null) { monsterDataInfo.TaskToHideList = new List <KeyValuePair <int, TaskMap.Enums.EnumTaskProgress> >(); } if (GUILayout.Button("添加隐藏条件")) { monsterDataInfo.TaskToHideList.Add(new KeyValuePair <int, TaskMap.Enums.EnumTaskProgress>()); } ShowHideTaskAction(monsterDataInfo.TaskToHideList); //物品掉落 if (monsterDataInfo.ItemDropRates == null) { monsterDataInfo.ItemDropRates = new float[0]; } if (monsterDataInfo.ItemDropTypes == null) { monsterDataInfo.ItemDropTypes = new EnumGoodsType[0]; } int dropCount = monsterDataInfo.ItemDropRates.Length > monsterDataInfo.ItemDropTypes.Length ? monsterDataInfo.ItemDropTypes.Length : monsterDataInfo.ItemDropRates.Length; int nowDropCount = EditorGUILayout.IntField("掉落物品种类数量(类型->概率):", dropCount); if (dropCount != nowDropCount) { monsterDataInfo.ItemDropRates = ChangedArrayLength(monsterDataInfo.ItemDropRates, nowDropCount); monsterDataInfo.ItemDropTypes = ChangedArrayLength(monsterDataInfo.ItemDropTypes, nowDropCount); } string[] goodsTypeExplans = goodsTypeToFieldNameDic.Values.ToArray(); int[] goodsTypeValues = goodsTypeToFieldNameDic.Keys.Select(temp => (int)temp).ToArray(); for (int i = 0; i < nowDropCount; i++) { EditorGUILayout.BeginHorizontal(); int goodsTypeValue = EditorGUILayout.IntPopup("物品类型", (int)monsterDataInfo.ItemDropTypes[i], goodsTypeExplans, goodsTypeValues); monsterDataInfo.ItemDropTypes[i] = (EnumGoodsType)goodsTypeValue; float rate = EditorGUILayout.FloatField(monsterDataInfo.ItemDropRates[i]); rate = Mathf.Clamp(rate, 0, 1); monsterDataInfo.ItemDropRates[i] = rate; EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical(); #endregion #region 怪物的AI信息 EditorGUILayout.BeginVertical(GUILayout.Width(350)); string[] monsterAITypeExplans = monsterAITypeToFieldNameDic.Values.ToArray(); int[] monsterAITypeValues = monsterAITypeToFieldNameDic.Keys.Select(temp => (int)temp).ToArray(); int monsterAITypeValue = EditorGUILayout.IntPopup("怪物AI类型:", (int)monsterDataInfo.AIType, monsterAITypeExplans, monsterAITypeValues); if ((int)monsterDataInfo.AIType != monsterAITypeValue || monsterDataInfo.AIData == null) { monsterDataInfo.AIType = (EnumMonsterAIType)monsterAITypeValue; MonsterAIDataStruct monsterAIDataStruct = monsterDataInfo.AIData; try { monsterDataInfo.AIData = (MonsterAIDataStruct)Activator.CreateInstance(typeof(MonsterAIDataStruct).Assembly.GetType("MonsterAIData_" + monsterDataInfo.AIType.ToString())); } catch { } if (monsterAIDataStruct != null && monsterDataInfo.AIData != null) { monsterDataInfo.AIData.FollowDistance = monsterAIDataStruct.FollowDistance; monsterDataInfo.AIData.UpdateTime = monsterAIDataStruct.UpdateTime; } } aiDataScrollPostion = EditorGUILayout.BeginScrollView(aiDataScrollPostion); if (monsterDataInfo.AIData != null) { monsterDataInfo.AIData.UpdateTime = EditorGUILayout.FloatField("怪物刷新时间:", monsterDataInfo.AIData.UpdateTime); monsterDataInfo.AIData.FollowDistance = EditorGUILayout.FloatField("跟随的最远距离:", monsterDataInfo.AIData.FollowDistance); //反射出不同类型的数据 Type thisAIDataType = typeof(MonsterAIDataStruct).Assembly.GetType("MonsterAIData_" + monsterDataInfo.AIType.ToString()); FieldInfo[] fieldInfos = thisAIDataType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); foreach (FieldInfo fieldInfo in fieldInfos) { FieldExplanAttribute fieldExplan = fieldInfo.GetCustomAttributes(typeof(FieldExplanAttribute), false).OfType <FieldExplanAttribute>().FirstOrDefault(); if (fieldExplan != null) { if (fieldInfo.FieldType.Equals(typeof(float))) { float value = EditorGUILayout.FloatField(fieldExplan.GetExplan(), (float)fieldInfo.GetValue(monsterDataInfo.AIData)); fieldInfo.SetValue(monsterDataInfo.AIData, value); } else if (fieldInfo.FieldType.Equals(typeof(int))) { int value = EditorGUILayout.IntField(fieldExplan.GetExplan(), (int)fieldInfo.GetValue(monsterDataInfo.AIData)); fieldInfo.SetValue(monsterDataInfo.AIData, value); } else if (fieldInfo.FieldType.Equals(typeof(bool))) { bool value = EditorGUILayout.Toggle(fieldExplan.GetExplan(), (bool)fieldInfo.GetValue(monsterDataInfo.AIData)); fieldInfo.SetValue(monsterDataInfo.AIData, value); } //还有其他的在后面添加..... } } } EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical(); #endregion } EditorGUILayout.EndHorizontal(); }
/// <summary> /// 更新位置到地面并初始化导航网格 /// </summary> public void Start() { #if UNITY_EDITOR if (DontInit) { return; } #endif Vector3 rayStart = transform.position + Vector3.up * 100; Ray ray = new Ray(rayStart, Vector3.down); RaycastHit[] rayCastHits = Physics.RaycastAll(ray); RaycastHit rayCastHit = rayCastHits.FirstOrDefault(temp => string.Equals(temp.transform.tag, "Terrain")); if (rayCastHit.collider != null) { transform.position = rayCastHit.point + Vector3.up * monsterDataInfo.Offset; } NavMeshAgent navMeshAgent = gameObject.AddComponent <NavMeshAgent>(); navMeshAgent.radius = 0.2f; navMeshAgent.height = 1.8f; navMeshAgent.baseOffset = 0; blackboard = GetComponent <Blackboard>(); IPlayerState iPlayerState = GameState.Instance.GetEntity <IPlayerState>(); if (blackboard != null) { if (monsterDataInfo.MonsterBaseAttribute != null) { blackboard.SetValue("HP", monsterDataInfo.MonsterBaseAttribute.MaxHP); if (monsterDataInfo.MonsterBaseAttribute.MoveSpeed > 0.5f) { blackboard.SetValue("Speed", monsterDataInfo.MonsterBaseAttribute.MoveSpeed); } } switch (monsterDataInfo.AIType) { case EnumMonsterAIType.Trigger: blackboard.SetValue("StartPoint", transform.position); blackboard.SetValue("Target", iPlayerState.PlayerObj); break; case EnumMonsterAIType.GoOnPatrol: //巡逻点 List <Vector3> goOnPatrolList = new List <Vector3>(); Vector3 result = Vector3.zero; int maxText = 0; for (int i = 0; i < 3; i++) { if (GetPointAtTerrainPosition(monsterDataInfo.Center + RandomVector3(monsterDataInfo.Range), out result)) { goOnPatrolList.Add(result); } else { if (maxText < 100) { i--; maxText++; } } } blackboard.SetValue("StartPoint", transform.position); blackboard.SetValue("GoOnPatrolPointList", goOnPatrolList); break; case EnumMonsterAIType.Boss: blackboard.SetValue("StartPoint", transform.position); break; } } //给对象添加一个子物体,子物体设置触发(这个不是用来检测攻击的而是用来检测发现目标的) SphereCollider thisSphereCollider = GetComponent <SphereCollider>(); if (thisSphereCollider != null) { GameObject childCheckObj = new GameObject(); childCheckObj.layer = LayerMask.NameToLayer("MonsterFindPlayer"); childCheckObj.transform.SetParent(transform); MonsterCheckPlayer monsterCheckPlayer = childCheckObj.AddComponent <MonsterCheckPlayer>(); monsterCheckPlayer.TriggerEnter = _OnTriggerEnter; monsterCheckPlayer.TriggerExit = _OnTriggerExit; childCheckObj.transform.localPosition = Vector3.zero; SphereCollider childSphereCollider = childCheckObj.AddComponent <SphereCollider>(); childSphereCollider.radius = thisSphereCollider.radius * (1 + monsterDataInfo.MonsterBaseAttribute.View); thisSphereCollider.enabled = false; childSphereCollider.isTrigger = true; } //注册监听 if (monsterDataInfo != null && monsterDataInfo.MonsterBaseAttribute != null) { thisAttribute = monsterDataInfo.MonsterBaseAttribute.Clone(); thisAttribute.Registor <IAttributeState>(IAttribute_Changed); } //监听玩家的血量 GameState.Instance.Registor <IPlayerAttributeState>(PlayerAttributeStateChanged); }
private void Awake() { Target = new AttributeStateAdditional(); }