(client) feat:实现子弹的生成
This commit is contained in:
111
Client/Assets/Prefab/CharacterPrefab Variant.prefab
Normal file
111
Client/Assets/Prefab/CharacterPrefab Variant.prefab
Normal file
@ -0,0 +1,111 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &92380775595425480
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: -0.80437
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: -3.38364
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 697189026367054479, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 887327274103887133, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: CharacterPrefab Variant
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1550000129210799929, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: entity
|
||||
value:
|
||||
objectReference: {fileID: 1108911649520063592}
|
||||
- target: {fileID: 3332598847335032684, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: entity
|
||||
value:
|
||||
objectReference: {fileID: 1108911649520063592}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents:
|
||||
- targetCorrespondingSourceObject: {fileID: 887327274103887133, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
insertIndex: 2
|
||||
addedObject: {fileID: 1108911649520063592}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
--- !u!1 &943601596972592085 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 887327274103887133, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
m_PrefabInstance: {fileID: 92380775595425480}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &1108911649520063592
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 943601596972592085}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 757576bb4354ac54da09868e1be02eec, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
animatorPrefab: {fileID: 2113064398104960506, guid: ea9af70ce0f4c8b4a9de58ac63074156, type: 3}
|
||||
imagePrefab: {fileID: 1922746734790246249, guid: a6657f26d735fab4690c8185980fda29, type: 3}
|
||||
healthBarPrefab: {fileID: 8215007830330368681}
|
||||
direction: {x: 0, y: 0, z: 0}
|
||||
body: {fileID: 2750404322221410198}
|
||||
affiliation:
|
||||
canSelect: 1
|
||||
hitBarUIShowTime: 5
|
||||
--- !u!1 &2750404322221410198 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 2838206730318674270, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
m_PrefabInstance: {fileID: 92380775595425480}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &8215007830330368681 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 8307348883874536545, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
m_PrefabInstance: {fileID: 92380775595425480}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 605f185650fe46d89a6e0d60fb8fb11c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
7
Client/Assets/Prefab/CharacterPrefab Variant.prefab.meta
Normal file
7
Client/Assets/Prefab/CharacterPrefab Variant.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5218adfb8e855a9459df63de8b2f323c
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -97,7 +97,6 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 697189026367054479}
|
||||
- component: {fileID: 3332598847335032684}
|
||||
- component: {fileID: 7300440714681954677}
|
||||
- component: {fileID: 1550000129210799929}
|
||||
- component: {fileID: 1724818962207668775}
|
||||
- component: {fileID: 4717642781780051128}
|
||||
@ -138,28 +137,8 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: b20b1846b9ef47db83c2ac8c4c4e82cb, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
entity: {fileID: 7300440714681954677}
|
||||
entity: {fileID: 0}
|
||||
outline: {fileID: 1550000129210799929}
|
||||
--- !u!114 &7300440714681954677
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 887327274103887133}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fbde354e0bcc4409b3378ee9b698ddc0, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
animatorPrefab: {fileID: 2113064398104960506, guid: ea9af70ce0f4c8b4a9de58ac63074156, type: 3}
|
||||
imagePrefab: {fileID: 1922746734790246249, guid: a6657f26d735fab4690c8185980fda29, type: 3}
|
||||
healthBarPrefab: {fileID: 8307348883874536545}
|
||||
direction: {x: 0, y: 0, z: 0}
|
||||
body: {fileID: 2838206730318674270}
|
||||
affiliation:
|
||||
canSelect: 1
|
||||
hitBarUIShowTime: 5
|
||||
--- !u!114 &1550000129210799929
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -176,7 +155,7 @@ MonoBehaviour:
|
||||
outlineRenderer: {fileID: 3992139212329961548}
|
||||
outlineCollider: {fileID: 1724818962207668775}
|
||||
progressBarPrefab: {fileID: 8307348883874536545}
|
||||
entity: {fileID: 7300440714681954677}
|
||||
entity: {fileID: 0}
|
||||
--- !u!70 &1724818962207668775
|
||||
CapsuleCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -130,6 +130,18 @@ PrefabInstance:
|
||||
propertyPath: m_IsActive
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1550000129210799929, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: entity
|
||||
value:
|
||||
objectReference: {fileID: 8780386748333639840}
|
||||
- target: {fileID: 1550000129210799929, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: progressBarPrefab
|
||||
value:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3332598847335032684, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: entity
|
||||
value:
|
||||
objectReference: {fileID: 8780386748333639840}
|
||||
- target: {fileID: 3992139212329961548, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
propertyPath: m_Enabled
|
||||
value: 0
|
||||
@ -139,15 +151,44 @@ PrefabInstance:
|
||||
value: Default
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_RemovedGameObjects:
|
||||
- {fileID: 1328271255896522146, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
m_AddedGameObjects:
|
||||
- targetCorrespondingSourceObject: {fileID: 5549544358816209289, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: 5706548514770437405}
|
||||
m_AddedComponents: []
|
||||
m_AddedComponents:
|
||||
- targetCorrespondingSourceObject: {fileID: 887327274103887133, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
insertIndex: 2
|
||||
addedObject: {fileID: 8780386748333639840}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
--- !u!4 &978302365984264250 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 5549544358816209289, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
m_PrefabInstance: {fileID: 4652308439801383347}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1 &5530484753491532974 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 887327274103887133, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
m_PrefabInstance: {fileID: 4652308439801383347}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &8780386748333639840
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5530484753491532974}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fbde354e0bcc4409b3378ee9b698ddc0, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
animatorPrefab: {fileID: 0}
|
||||
imagePrefab: {fileID: 0}
|
||||
healthBarPrefab: {fileID: 0}
|
||||
direction: {x: 0, y: 0, z: 0}
|
||||
body: {fileID: 0}
|
||||
affiliation:
|
||||
canSelect: 1
|
||||
hitBarUIShowTime: 5
|
||||
|
@ -283,9 +283,11 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
isGlobal: 1
|
||||
entityLevel: {fileID: 1891846098}
|
||||
entityPrefab: {fileID: 3332598847335032684, guid: 6cd8b01a0f57372438dc30c864ae1530, type: 3}
|
||||
entityPrefab: {fileID: 3420474218334607780, guid: 5218adfb8e855a9459df63de8b2f323c, type: 3}
|
||||
buildingLevel: {fileID: 651025902}
|
||||
buildingPrefab: {fileID: 5615006624229444611, guid: d7b9277d8e6ac4541800044bdb0da063, type: 3}
|
||||
bulletLevel: {fileID: 466785510}
|
||||
bulletPrefab: {fileID: 8687677644466399534, guid: 29b2450a8636a104586e36333878f4d9, type: 3}
|
||||
defaultEntityPrefab: {fileID: 7975757421877276383, guid: 89661daa5f100c64783f0ad9cd37a7ff, type: 3}
|
||||
--- !u!4 &164739122
|
||||
Transform:
|
||||
@ -381,6 +383,37 @@ Transform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &466785510
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 466785511}
|
||||
m_Layer: 0
|
||||
m_Name: BulletLevel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &466785511
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 466785510}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1423222968}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &603423466
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -1042,6 +1075,7 @@ Transform:
|
||||
m_Children:
|
||||
- {fileID: 1891846100}
|
||||
- {fileID: 651025903}
|
||||
- {fileID: 466785511}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1468918169
|
||||
|
@ -77,7 +77,7 @@ namespace AI
|
||||
public class TrackPlayerJob : JobBase
|
||||
{
|
||||
private EntityPrefab currentTarget; // 当前追踪的目标玩家
|
||||
private List<EntityPrefab> players; // 玩家实体列表
|
||||
private LinkedList<EntityPrefab> players; // 玩家实体列表
|
||||
|
||||
public override void StartJob(Entity.Entity target)
|
||||
{
|
||||
@ -87,13 +87,13 @@ namespace AI
|
||||
|
||||
protected override void UpdateJob()
|
||||
{
|
||||
if (currentTarget == null || currentTarget.entity.IsDead)
|
||||
if (!currentTarget || currentTarget.entity.IsDead)
|
||||
{
|
||||
// 如果当前目标无效,则重新查找最近的玩家
|
||||
UpdateTarget();
|
||||
}
|
||||
|
||||
if (currentTarget != null)
|
||||
if (currentTarget)
|
||||
{
|
||||
var targetPosition = new Vector3(currentTarget.Position.x, currentTarget.Position.y, 0);
|
||||
entity.SetTarget(targetPosition);
|
||||
@ -114,7 +114,7 @@ namespace AI
|
||||
currentTarget = GetNearestPlayer(players);
|
||||
}
|
||||
|
||||
private EntityPrefab GetNearestPlayer(List<EntityPrefab> players)
|
||||
private EntityPrefab GetNearestPlayer(LinkedList<EntityPrefab> players)
|
||||
{
|
||||
EntityPrefab nearestPlayer = null;
|
||||
float minDistance = float.MaxValue;
|
||||
@ -144,7 +144,7 @@ namespace AI
|
||||
|
||||
protected override void UpdateJob()
|
||||
{
|
||||
if (player == null || !IsPlayerInRange())
|
||||
if (!player || !IsPlayerInRange())
|
||||
{
|
||||
StopJob(); // 如果玩家不在范围内,停止攻击工作
|
||||
return;
|
||||
@ -167,11 +167,11 @@ namespace AI
|
||||
base.StartJob(target);
|
||||
|
||||
// 查找最近的玩家作为目标
|
||||
List<EntityPrefab> players = Managers.EntityManage.Instance.FindEntitiesByFaction("Player");
|
||||
LinkedList<EntityPrefab> players = Managers.EntityManage.Instance.FindEntitiesByFaction("Player");
|
||||
player = GetNearestPlayer(players);
|
||||
}
|
||||
|
||||
private EntityPrefab GetNearestPlayer(List<EntityPrefab> players)
|
||||
private EntityPrefab GetNearestPlayer(LinkedList<EntityPrefab> players)
|
||||
{
|
||||
EntityPrefab nearestPlayer = null;
|
||||
float minDistance = float.MaxValue;
|
||||
@ -197,7 +197,7 @@ namespace AI
|
||||
|
||||
private bool IsPlayerValid(EntityPrefab player)
|
||||
{
|
||||
return player != null && !player.entity.IsDead;
|
||||
return player && !player.entity.IsDead;
|
||||
}
|
||||
}
|
||||
public class RangedAttackJob : JobBase
|
||||
@ -206,7 +206,7 @@ namespace AI
|
||||
|
||||
protected override void UpdateJob()
|
||||
{
|
||||
if (player == null || !IsPlayerValid(player))
|
||||
if (!player || !IsPlayerValid(player))
|
||||
{
|
||||
StopJob(); // 如果当前目标无效,停止工作
|
||||
return;
|
||||
@ -256,11 +256,11 @@ namespace AI
|
||||
base.StartJob(target);
|
||||
|
||||
// 查找最近的玩家作为目标
|
||||
List<EntityPrefab> players = Managers.EntityManage.Instance.FindEntitiesByFaction("Player");
|
||||
var players = Managers.EntityManage.Instance.FindEntitiesByFaction("Player");
|
||||
player = GetNearestPlayer(players);
|
||||
}
|
||||
|
||||
private EntityPrefab GetNearestPlayer(List<EntityPrefab> players)
|
||||
private EntityPrefab GetNearestPlayer(LinkedList<EntityPrefab> players)
|
||||
{
|
||||
EntityPrefab nearestPlayer = null;
|
||||
float minDistance = float.MaxValue;
|
||||
@ -286,7 +286,7 @@ namespace AI
|
||||
|
||||
private bool IsPlayerValid(EntityPrefab player)
|
||||
{
|
||||
return player != null && !player.entity.IsDead;
|
||||
return player && !player.entity.IsDead;
|
||||
}
|
||||
|
||||
private const float MaxTrackDistance = 20f; // 最大追踪距离
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace Data
|
||||
{
|
||||
public class BuildingDef : PawnDef
|
||||
public class BuildingDef : EntityDef
|
||||
{
|
||||
public float slowDown = 0f;
|
||||
}
|
||||
|
8
Client/Assets/Scripts/Data/BulletDef.cs
Normal file
8
Client/Assets/Scripts/Data/BulletDef.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Data
|
||||
{
|
||||
public class BulletDef:EntityDef
|
||||
{
|
||||
public string className;
|
||||
public string value;
|
||||
}
|
||||
}
|
3
Client/Assets/Scripts/Data/BulletDef.cs.meta
Normal file
3
Client/Assets/Scripts/Data/BulletDef.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f32fe058231409aaef631564bc51317
|
||||
timeCreated: 1755173999
|
@ -7,7 +7,7 @@ using UnityEngine;
|
||||
|
||||
namespace Data
|
||||
{
|
||||
public class CharacterDef : PawnDef
|
||||
public class CharacterDef : EntityDef
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ using System.Xml.Linq;
|
||||
|
||||
namespace Data
|
||||
{
|
||||
public class PawnDef : Define
|
||||
public class EntityDef : Define
|
||||
{
|
||||
public AttributesDef attributes;
|
||||
public DrawingOrderDef drawingOrder;
|
@ -1,6 +1,6 @@
|
||||
namespace Data
|
||||
{
|
||||
public class MonsterDef:PawnDef
|
||||
public class MonsterDef:EntityDef
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -3,8 +3,14 @@ using UnityEngine;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public class Bullet:Entity
|
||||
public class Bullet : Entity
|
||||
{
|
||||
public override void SetTarget(Vector3 pos)
|
||||
{
|
||||
base.SetTarget(pos);
|
||||
RotateTransformToDirection(transform, direction);
|
||||
}
|
||||
|
||||
protected override void AutoBehave()
|
||||
{
|
||||
TryMove();
|
||||
@ -13,6 +19,19 @@ namespace Entity
|
||||
private void OnTriggerEnter2D(Collider2D other)
|
||||
{
|
||||
other.GetComponent<Entity>()?.OnHit(this);
|
||||
attributes.health -= 1;
|
||||
}
|
||||
// 旋转对象到指定方向
|
||||
public static void RotateTransformToDirection(Transform transform, Vector3 targetDirection)
|
||||
{
|
||||
// 默认向上方向
|
||||
Vector3 upDirection = Vector3.up;
|
||||
|
||||
// 计算旋转角度
|
||||
float angle = Mathf.Atan2(targetDirection.x, targetDirection.y) * Mathf.Rad2Deg;
|
||||
|
||||
// 设置旋转
|
||||
transform.rotation = Quaternion.Euler(0, 0, angle);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,5 +23,16 @@ namespace Entity
|
||||
return;
|
||||
}
|
||||
|
||||
public override void TryAttack()
|
||||
{
|
||||
if (IsAttacking)
|
||||
return;
|
||||
if (!Managers.DefineManager.Instance.defines.TryGetValue(nameof(BulletDef), out var def))
|
||||
return;
|
||||
var buttonDef = def.Values.First();
|
||||
Vector3 dir = Utils.MousePosition.GetWorldPosition();
|
||||
Managers.EntityManage.Instance.GenerateBulletEntity((BulletDef)buttonDef, Position,
|
||||
dir - Position);
|
||||
}
|
||||
}
|
||||
}
|
@ -134,7 +134,7 @@ namespace Entity
|
||||
// 协程引用
|
||||
private Coroutine attackCoroutine;
|
||||
|
||||
protected PawnDef entityDef;
|
||||
protected EntityDef entityDef;
|
||||
|
||||
|
||||
public float hitBarUIShowTime = 5;
|
||||
@ -144,14 +144,14 @@ namespace Entity
|
||||
/// <summary>
|
||||
/// 初始化实体的基本属性和行为树。
|
||||
/// </summary>
|
||||
/// <param name="pawnDef">实体的定义数据。</param>
|
||||
public virtual void Init(PawnDef pawnDef)
|
||||
/// <param name="entityDef">实体的定义数据。</param>
|
||||
public virtual void Init(EntityDef entityDef)
|
||||
{
|
||||
attributes = pawnDef.attributes.Clone();
|
||||
aiTree = Utils.BehaviorTree.ConvertToAIBase(pawnDef.behaviorTree);
|
||||
affiliation = pawnDef.affiliation;
|
||||
InitBody(pawnDef.drawingOrder);
|
||||
entityDef = pawnDef;
|
||||
attributes = entityDef.attributes.Clone();
|
||||
aiTree = Utils.BehaviorTree.ConvertToAIBase(entityDef.behaviorTree);
|
||||
affiliation = entityDef.affiliation;
|
||||
InitBody(entityDef.drawingOrder);
|
||||
this.entityDef = entityDef;
|
||||
|
||||
HideHealthBar();
|
||||
}
|
||||
@ -288,9 +288,18 @@ namespace Entity
|
||||
/// <param name="orientation">新的朝向。</param>
|
||||
public virtual void SetOrientation(Orientation orientation)
|
||||
{
|
||||
bodyNodes[currentOrientation]?.SetActive(false);
|
||||
// 禁用当前朝向的节点
|
||||
if (bodyNodes.TryGetValue(currentOrientation, out var currentNode))
|
||||
{
|
||||
currentNode.SetActive(false);
|
||||
}
|
||||
// 设置新的朝向
|
||||
currentOrientation = orientation;
|
||||
bodyNodes[orientation]?.SetActive(true);
|
||||
// 激活新朝向的节点
|
||||
if (bodyNodes.TryGetValue(orientation, out var newNode))
|
||||
{
|
||||
newNode.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -475,20 +484,13 @@ namespace Entity
|
||||
|
||||
public void DetectAndAttackEnemies()
|
||||
{
|
||||
const int attackRange = 3;
|
||||
var attackCount = 3;
|
||||
|
||||
// 获取攻击范围内的所有碰撞体,使用LayerMask过滤掉非敌人
|
||||
var attackCount = attributes.attackTargetCount;
|
||||
// 获取攻击范围内的所有碰撞体
|
||||
var hits = Physics2D.OverlapCircleAll(
|
||||
transform.position,
|
||||
attackRange,
|
||||
attributes.attackRange,
|
||||
LayerMask.GetMask("Entity"));
|
||||
|
||||
// 或者使用标签过滤(如果敌人有特定标签)
|
||||
// Collider2D[] hits = Physics2D.OverlapCircleAll(transform.position, attackRange);
|
||||
|
||||
Debug.Log($"Found {hits.Length} potential targets in attack range");
|
||||
|
||||
foreach (var hit in hits)
|
||||
{
|
||||
if (attackCount <= 0) break;
|
||||
|
@ -7,24 +7,29 @@ using UnityEngine;
|
||||
|
||||
namespace Managers
|
||||
{
|
||||
public class EntityManage:Utils.MonoSingleton<EntityManage>,ITick
|
||||
public class EntityManage : Utils.MonoSingleton<EntityManage>, ITick
|
||||
{
|
||||
public Dictionary<string, List<EntityPrefab>> factionEntities = new();
|
||||
public Dictionary<string, LinkedList<EntityPrefab>> factionEntities = new();
|
||||
|
||||
public GameObject entityLevel;
|
||||
public EntityPrefab entityPrefab;
|
||||
public GameObject buildingLevel;
|
||||
public EntityPrefab buildingPrefab;
|
||||
public GameObject bulletLevel;
|
||||
public EntityPrefab bulletPrefab;
|
||||
|
||||
public EntityPrefab defaultEntityPrefab;
|
||||
public List<EntityPrefab> FindEntitiesByFaction(string factionKey)
|
||||
|
||||
public LinkedList<EntityPrefab> FindEntitiesByFaction(string factionKey)
|
||||
{
|
||||
if (factionEntities.TryGetValue(factionKey, out var entities))
|
||||
{
|
||||
return entities; // 如果找到,返回对应的实体列表
|
||||
}
|
||||
return new List<EntityPrefab>(); // 如果未找到,返回一个空列表
|
||||
|
||||
return new(); // 如果未找到,返回一个空列表
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
foreach (var faction in factionEntities)
|
||||
@ -43,6 +48,7 @@ namespace Managers
|
||||
itike.Tick();
|
||||
}
|
||||
}
|
||||
|
||||
// 删除所有标记为死亡的实体
|
||||
foreach (var entityToRemove in entitiesToRemove)
|
||||
{
|
||||
@ -53,149 +59,175 @@ namespace Managers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据给定的PawnDef生成一个实体对象。
|
||||
/// 根据给定的Def生成实体对象(内部通用方法)。
|
||||
/// </summary>
|
||||
/// <param name="pawnDef">定义实体属性的PawnDef对象。</param>
|
||||
/// <param name="pos">实体生成的位置。</param>
|
||||
/// <remarks>
|
||||
/// 1. 如果entityPrefab或pawnDef为null,则不会生成实体。
|
||||
/// 2. 实体将被创建在entityLevel.transform下。
|
||||
/// 3. 使用EntityPrefab组件初始化实体。
|
||||
/// </remarks>
|
||||
public void GenerateEntity(Data.PawnDef pawnDef, Vector3 pos)
|
||||
/// <param name="prefab">要实例化的预制体</param>
|
||||
/// <param name="parent">生成的父级Transform</param>
|
||||
/// <param name="pos">生成位置</param>
|
||||
/// <param name="def">实体定义对象</param>
|
||||
/// <param name="extraInit">额外的初始化操作(如子弹方向设置)</param>
|
||||
/// <returns>成功时返回EntityPrefab组件,失败时返回null</returns>
|
||||
private EntityPrefab GenerateEntityInternal(
|
||||
GameObject prefab,
|
||||
Transform parent,
|
||||
Vector3 pos,
|
||||
Data.EntityDef def, // 所有Def类型需继承自BaseDef
|
||||
Action<EntityPrefab> extraInit = null)
|
||||
{
|
||||
// 检查 entityPrefab 是否为空
|
||||
if (!entityPrefab)
|
||||
{
|
||||
Debug.LogError("Error: entityPrefab is null. Please assign a valid prefab.");
|
||||
GenerateDefaultEntity(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查 pawnDef 是否为空
|
||||
if (pawnDef == null)
|
||||
{
|
||||
Debug.LogError("Error: PawnDef is null. Cannot generate entity without a valid PawnDef.");
|
||||
GenerateDefaultEntity(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject instantiatedEntity = null; // 用于跟踪已实例化的对象
|
||||
|
||||
GameObject instantiatedEntity = null;
|
||||
try
|
||||
{
|
||||
// 实例化实体对象
|
||||
instantiatedEntity = Instantiate(entityPrefab.gameObject, pos, Quaternion.identity, entityLevel.transform);
|
||||
// 实例化实体
|
||||
instantiatedEntity = Instantiate(prefab, pos, Quaternion.identity, parent);
|
||||
|
||||
// 获取 EntityPrefab 组件
|
||||
// 获取并验证EntityPrefab组件
|
||||
var entityComponent = instantiatedEntity.GetComponent<EntityPrefab>();
|
||||
|
||||
// 检查 EntityPrefab 组件是否存在
|
||||
if (!entityComponent)
|
||||
{
|
||||
throw new InvalidOperationException($"Error: EntityPrefab component not found on the instantiated object: {instantiatedEntity.name}");
|
||||
throw new InvalidOperationException(
|
||||
$"EntityPrefab component missing on: {instantiatedEntity.name}");
|
||||
}
|
||||
|
||||
// 初始化实体组件
|
||||
entityComponent.Init(pawnDef);
|
||||
// 初始化核心数据
|
||||
entityComponent.Init(def);
|
||||
|
||||
// 确保派系键存在,并初始化对应的列表
|
||||
var factionKey = pawnDef.attributes.label ?? "default"; // 使用 null 合并运算符简化代码
|
||||
// 执行类型特有的额外初始化
|
||||
extraInit?.Invoke(entityComponent);
|
||||
|
||||
// 管理派系列表
|
||||
var factionKey = def.attributes.label ?? "default";
|
||||
if (!factionEntities.ContainsKey(factionKey))
|
||||
{
|
||||
factionEntities[factionKey] = new List<EntityPrefab>();
|
||||
factionEntities[factionKey] = new LinkedList<EntityPrefab>();
|
||||
}
|
||||
factionEntities[factionKey].Add(entityComponent);
|
||||
|
||||
factionEntities[factionKey].AddLast(entityComponent);
|
||||
|
||||
return entityComponent;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// 如果有已实例化的对象,则销毁它
|
||||
if (instantiatedEntity)
|
||||
{
|
||||
Destroy(instantiatedEntity); // 删除已创建的对象
|
||||
}
|
||||
// 清理失败实例
|
||||
if (instantiatedEntity) Destroy(instantiatedEntity);
|
||||
|
||||
// 捕获并记录任何异常
|
||||
Debug.LogError($"An error occurred while generating the entity: {ex.Message}\nStack Trace: {ex.StackTrace}");
|
||||
|
||||
// 调用默认生成方法
|
||||
GenerateDefaultEntity(pos);
|
||||
Debug.LogError($"Entity generation failed: {ex.Message}\n{ex.StackTrace}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据PawnDef生成普通实体
|
||||
/// </summary>
|
||||
public void GenerateEntity(Data.EntityDef entityDef, Vector3 pos)
|
||||
{
|
||||
// 验证关键参数
|
||||
if (!entityPrefab)
|
||||
{
|
||||
Debug.LogError("entityPrefab is null! Assign a valid prefab.");
|
||||
GenerateDefaultEntity(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entityDef == null)
|
||||
{
|
||||
Debug.LogError("EntityDef is null! Cannot generate entity.");
|
||||
GenerateDefaultEntity(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用通用生成逻辑
|
||||
var result = GenerateEntityInternal(
|
||||
entityPrefab.gameObject,
|
||||
entityLevel.transform,
|
||||
pos,
|
||||
entityDef
|
||||
);
|
||||
|
||||
if (!result) GenerateDefaultEntity(pos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成建筑实体(位置使用Vector3Int)
|
||||
/// </summary>
|
||||
public void GenerateBuildingEntity(Data.BuildingDef buildingDef, Vector3Int pos)
|
||||
{
|
||||
// 检查 entityPrefab 是否为空
|
||||
if (!entityPrefab)
|
||||
// 修正:检查正确的预制体 (buildingPrefab)
|
||||
if (!buildingPrefab)
|
||||
{
|
||||
Debug.LogError("Error: entityPrefab is null. Please assign a valid prefab.");
|
||||
Debug.LogError("buildingPrefab is null! Assign a valid prefab.");
|
||||
GenerateDefaultEntity(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查 pawnDef 是否为空
|
||||
if (buildingDef == null)
|
||||
{
|
||||
Debug.LogError("Error: PawnDef is null. Cannot generate entity without a valid PawnDef.");
|
||||
Debug.LogError("BuildingDef is null! Cannot generate building.");
|
||||
GenerateDefaultEntity(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject instantiatedEntity = null; // 用于跟踪已实例化的对象
|
||||
var worldPos = new Vector3(pos.x, pos.y, pos.z);
|
||||
|
||||
try
|
||||
{
|
||||
// 实例化实体对象
|
||||
instantiatedEntity = Instantiate(buildingPrefab.gameObject, pos, Quaternion.identity, buildingLevel.transform);
|
||||
var result = GenerateEntityInternal(
|
||||
buildingPrefab.gameObject,
|
||||
buildingLevel.transform,
|
||||
worldPos,
|
||||
buildingDef
|
||||
);
|
||||
|
||||
// 获取 EntityPrefab 组件
|
||||
var entityComponent = instantiatedEntity.GetComponent<EntityPrefab>();
|
||||
|
||||
// 检查 EntityPrefab 组件是否存在
|
||||
if (!entityComponent)
|
||||
{
|
||||
throw new InvalidOperationException($"Error: EntityPrefab component not found on the instantiated object: {instantiatedEntity.name}");
|
||||
}
|
||||
|
||||
// 初始化实体组件
|
||||
entityComponent.Init(buildingDef);
|
||||
|
||||
// 确保派系键存在,并初始化对应的列表
|
||||
var factionKey = buildingDef.attributes.label ?? "default"; // 使用 null 合并运算符简化代码
|
||||
if (!factionEntities.ContainsKey(factionKey))
|
||||
{
|
||||
factionEntities[factionKey] = new List<EntityPrefab>();
|
||||
}
|
||||
factionEntities[factionKey].Add(entityComponent);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// 如果有已实例化的对象,则销毁它
|
||||
if (instantiatedEntity)
|
||||
{
|
||||
Destroy(instantiatedEntity); // 删除已创建的对象
|
||||
}
|
||||
|
||||
// 捕获并记录任何异常
|
||||
Debug.LogError($"An error occurred while generating the entity: {ex.Message}\nStack Trace: {ex.StackTrace}");
|
||||
|
||||
// 调用默认生成方法
|
||||
GenerateDefaultEntity(pos);
|
||||
}
|
||||
if (!result) GenerateDefaultEntity(pos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成子弹实体(含方向设置)
|
||||
/// </summary>
|
||||
public void GenerateBulletEntity(Data.BulletDef bulletDef, Vector3 pos, Vector3 dir)
|
||||
{
|
||||
// 修正:检查正确的预制体 (bulletPrefab)
|
||||
if (!bulletPrefab)
|
||||
{
|
||||
Debug.LogError("bulletPrefab is null! Assign a valid prefab.");
|
||||
GenerateDefaultEntity(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bulletDef == null)
|
||||
{
|
||||
Debug.LogError("BulletDef is null! Cannot generate bullet.");
|
||||
GenerateDefaultEntity(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
var result = GenerateEntityInternal(
|
||||
bulletPrefab.gameObject,
|
||||
bulletLevel.transform,
|
||||
pos,
|
||||
bulletDef,
|
||||
// 子弹特有的方向设置
|
||||
entityComponent => entityComponent.entity.SetTarget(pos + dir)
|
||||
);
|
||||
|
||||
if (!result) GenerateDefaultEntity(pos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成默认实体(错误回退)
|
||||
/// </summary>
|
||||
public void GenerateDefaultEntity(Vector3 pos)
|
||||
{
|
||||
var entity = Instantiate(defaultEntityPrefab.gameObject, pos, Quaternion.identity, entityLevel.transform);
|
||||
var entity = Instantiate(defaultEntityPrefab, pos, Quaternion.identity, entityLevel.transform);
|
||||
var entityComponent = entity.GetComponent<EntityPrefab>();
|
||||
|
||||
const string factionKey = "default";
|
||||
if (!factionEntities.ContainsKey(factionKey))
|
||||
{
|
||||
factionEntities[factionKey] = new List<EntityPrefab>();
|
||||
factionEntities[factionKey] = new LinkedList<EntityPrefab>();
|
||||
}
|
||||
|
||||
entityComponent.DefaultInit();
|
||||
factionEntities[factionKey].Add(entityComponent);
|
||||
factionEntities[factionKey].AddLast(entityComponent);
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
factionEntities.Clear();
|
||||
|
@ -377,7 +377,7 @@ namespace Managers
|
||||
// 尝试解析编号
|
||||
if (int.TryParse(suffix, out var number))
|
||||
{
|
||||
sprites.Add((number, Value: value));
|
||||
sprites.Add((number, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,9 @@ namespace Prefab
|
||||
}
|
||||
}
|
||||
|
||||
public void Init(Data.PawnDef pawnDef)
|
||||
public void Init(Data.EntityDef entityDef)
|
||||
{
|
||||
entity.Init(pawnDef);
|
||||
entity.Init(entityDef);
|
||||
|
||||
outline.Init();
|
||||
outline.Hide();
|
||||
|
@ -141,13 +141,13 @@ namespace UI
|
||||
return instantiatedComponent;
|
||||
}
|
||||
|
||||
private void GenerateEntityCallback(PawnDef pawnDef)
|
||||
private void GenerateEntityCallback(EntityDef entityDef)
|
||||
{
|
||||
entityPlacementUI.currentAction = () =>
|
||||
{
|
||||
Managers.EntityManage.Instance.GenerateEntity(pawnDef, Utils.MousePosition.GetWorldPosition());
|
||||
Managers.EntityManage.Instance.GenerateEntity(entityDef, Utils.MousePosition.GetWorldPosition());
|
||||
};
|
||||
entityPlacementUI.Prompt = $"当前生成器:\n名称:{pawnDef.label}\n描述:{pawnDef.description}";
|
||||
entityPlacementUI.Prompt = $"当前生成器:\n名称:{entityDef.label}\n描述:{entityDef.description}";
|
||||
entityPlacementUI.snapEnabled = false;
|
||||
Base.UIInputControl.Instance.Show(entityPlacementUI);
|
||||
}
|
||||
|
@ -21,12 +21,19 @@
|
||||
|
||||
<BulletDef>
|
||||
<defName>yellowBullet</defName>
|
||||
<moveSpeed>10</moveSpeed>
|
||||
<texture>
|
||||
<path>Resources\Item\YellowBullet.png</path>
|
||||
</texture>
|
||||
<attributes>
|
||||
<health>1</health>
|
||||
<moveSpeed>20</moveSpeed>
|
||||
</attributes>
|
||||
<drawingOrder>
|
||||
<texturePath>Resources\Item</texturePath>
|
||||
<pixelsPerUnit>20</pixelsPerUnit>
|
||||
<drawingOrder_down>
|
||||
<node name="YellowBullet"/>
|
||||
</drawingOrder_down>
|
||||
</drawingOrder>
|
||||
<behaviorTree>
|
||||
<Node className="ContinuousMove"/>
|
||||
<Node className="JobGiver_ContinuousMove"/>
|
||||
</behaviorTree>
|
||||
</BulletDef>
|
||||
|
||||
|
Before Width: | Height: | Size: 137 B After Width: | Height: | Size: 137 B |
Reference in New Issue
Block a user