mirror of
http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite.git
synced 2025-11-20 15:27:13 +08:00
(client) feat:支持定义实体的碰撞体大小和偏移;建筑支持定义实体建筑和瓦片建筑,建筑支持指定按钮回调;添加存档管理器;Dev支持设置是否暂停;实体允许定义事件组;添加基地界面 (#57)
Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite/pulls/57
This commit is contained in:
@@ -5,9 +5,9 @@ using Item;
|
||||
using Managers;
|
||||
using Prefab;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Parsing;
|
||||
using UnityEngine;
|
||||
using Utils;
|
||||
|
||||
@@ -19,18 +19,7 @@ namespace Entity
|
||||
/// </summary>
|
||||
public class Entity : MonoBehaviour, ITick
|
||||
{
|
||||
/// <summary>
|
||||
/// 动画预制体,用于管理实体的动画逻辑。
|
||||
/// </summary>
|
||||
public SpriteAnimator animatorPrefab;
|
||||
|
||||
/// <summary>
|
||||
/// 图像预制体,用于管理实体的静态图像显示。
|
||||
/// </summary>
|
||||
public ImagePrefab imagePrefab;
|
||||
|
||||
public ProgressBarPrefab healthBarPrefab;
|
||||
|
||||
public EntityPrefab entityPrefab;
|
||||
public EntityDef entityDef;
|
||||
/// <summary>
|
||||
@@ -40,7 +29,7 @@ namespace Entity
|
||||
|
||||
public SpriteAnimator weaponItem;
|
||||
public SpriteAnimator weaponAttackAnimation;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 人工智能行为树,定义实体的行为逻辑。
|
||||
/// </summary>
|
||||
@@ -96,7 +85,7 @@ namespace Entity
|
||||
public bool canSelect = true;
|
||||
|
||||
|
||||
public string currentDimensionId = null;
|
||||
public string currentDimensionId;
|
||||
|
||||
|
||||
|
||||
@@ -110,18 +99,18 @@ namespace Entity
|
||||
if (value)
|
||||
{
|
||||
currentJob = null;
|
||||
// 逻辑修改:只有当存在一个不同的焦点实体时,才将其PlayerControlled设为false
|
||||
if (Program.Instance.FocusedEntity && Program.Instance.FocusedEntity != this)
|
||||
{
|
||||
Program.Instance.FocusedEntity.PlayerControlled = false;
|
||||
}
|
||||
|
||||
Program.Instance.SetFocusedEntity(this);
|
||||
gameObject.tag="Player";
|
||||
}
|
||||
// 逻辑修改:确保只有当自身是焦点实体时才取消焦点,避免不必要的逻辑执行
|
||||
else if (Program.Instance.FocusedEntity == this)
|
||||
{
|
||||
Program.Instance.SetFocusedEntity(null);
|
||||
gameObject.tag = "Untagged";
|
||||
}
|
||||
}
|
||||
get => Program.Instance.FocusedEntity == this;
|
||||
@@ -142,8 +131,8 @@ namespace Entity
|
||||
|
||||
public bool IsShowingHealthBarUI => _hitBarUIShowTimer > 0;
|
||||
public bool IsAttacking => _attackTimer > 0;
|
||||
private float _attackTimer = 0;
|
||||
private float _attackDetectionTime = 0;
|
||||
private float _attackTimer;
|
||||
private float _attackDetectionTime;
|
||||
private WeaponResource currentAttackWeapon;
|
||||
|
||||
/// <summary>
|
||||
@@ -158,11 +147,8 @@ namespace Entity
|
||||
/// </summary>
|
||||
public event Action<Entity> OnEntityDied;
|
||||
|
||||
private bool _warning = false;
|
||||
private bool _warning;
|
||||
|
||||
|
||||
private GameObject wearponAttackAnimationNodeRoot = null;
|
||||
|
||||
/// <summary>
|
||||
/// 存储不同朝向下的身体节点对象。
|
||||
/// </summary>
|
||||
@@ -171,19 +157,38 @@ namespace Entity
|
||||
/// <summary>
|
||||
/// 当前实体的朝向。
|
||||
/// </summary>
|
||||
private Orientation _currentOrientation = Orientation.Down;
|
||||
public Orientation CurrentOrientation { get; private set; } = Orientation.Down;
|
||||
|
||||
/// <summary>
|
||||
/// 当前实体的状态
|
||||
/// </summary>
|
||||
private EntityState _currentState = EntityState.Idle;
|
||||
public EntityState CurrentState { get; private set; } = EntityState.Idle;
|
||||
|
||||
public AudioSource Audio;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[SerializeField] private float _hitBarUIShowTime = 5;
|
||||
private float _hitBarUIShowTimer = 0;
|
||||
private int _walkingTimer = 0;
|
||||
private float _hitBarUIShowTimer;
|
||||
private int _walkingTimer;
|
||||
|
||||
private List<(Func<Entity, bool>,string)> _conditionalEvents=new();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化实体的基本属性和行为树。
|
||||
@@ -192,13 +197,14 @@ namespace Entity
|
||||
public virtual void Init(EntityDef entityDef)
|
||||
{
|
||||
attributes = new Attributes(entityDef.attributes);
|
||||
aiTree = AI.BehaviorTree.ConvertToAIBase(entityDef.behaviorTree);
|
||||
aiTree = BehaviorTree.ConvertToAIBase(entityDef.behaviorTree);
|
||||
affiliation = entityDef.affiliation?.defName;
|
||||
InitBody(entityDef.drawingOrder);
|
||||
this.entityDef = entityDef;
|
||||
|
||||
HideHealthBar();
|
||||
InitWeaponAnimator();
|
||||
InitConditionalEvents(entityDef.eventDef?.GetAllConditionalEvents());
|
||||
}
|
||||
|
||||
protected virtual void InitWeaponAnimator()
|
||||
@@ -231,7 +237,9 @@ namespace Entity
|
||||
protected virtual void InitBody(DrawingOrderDef drawingOrder)
|
||||
{
|
||||
// 预缓存枚举值(避免每次循环重复调用 Enum.GetValues)
|
||||
var states = Enum.GetValues(typeof(EntityState)).Cast<EntityState>().ToArray();
|
||||
var states = Enum.GetValues(typeof(EntityState)).Cast<EntityState>().ToList();
|
||||
states.Remove(EntityState.Death);
|
||||
|
||||
var orientations = Enum.GetValues(typeof(Orientation)).Cast<Orientation>().ToArray();
|
||||
// 预初始化字典结构(减少内层循环的字典检查)
|
||||
foreach (var state in states)
|
||||
@@ -250,15 +258,15 @@ namespace Entity
|
||||
GameObject targetObj;
|
||||
if (nodeDef == null)
|
||||
{
|
||||
if (imagePrefab && Managers.PackagesImageManager.Instance.defaultSprite != null)
|
||||
if (PackagesImageManager.Instance.defaultSprite)
|
||||
{
|
||||
targetObj = Instantiate(imagePrefab.gameObject, body.transform);
|
||||
targetObj = Instantiate(GameObjectCreate.ImagePrefab.gameObject, body.transform);
|
||||
targetObj.name = $"{state}_{orientation}_Default";
|
||||
targetObj.transform.localPosition = Vector3.zero;
|
||||
var imagePrefabCom = targetObj.GetComponent<ImagePrefab>();
|
||||
if (imagePrefabCom)
|
||||
{
|
||||
imagePrefabCom.SetSprite(Managers.PackagesImageManager.Instance.defaultSprite);
|
||||
imagePrefabCom.SetSprite(PackagesImageManager.Instance.defaultSprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -313,21 +321,37 @@ namespace Entity
|
||||
}
|
||||
|
||||
|
||||
protected void InitConditionalEvents(ConditionalEvent[] conditionalEvents)
|
||||
{
|
||||
if(conditionalEvents==null)return;
|
||||
_conditionalEvents.Clear();
|
||||
foreach (var conditionalEvent in conditionalEvents)
|
||||
{
|
||||
var condition = ConditionDelegateFactory.CreateConditionDelegate(conditionalEvent.parameter,
|
||||
typeof(Entity), typeof(ConditionFunctions));
|
||||
if(condition==null)continue;
|
||||
_conditionalEvents.Add((condition, conditionalEvent.defName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 更新实体的逻辑,包括玩家控制和自动行为。
|
||||
/// </summary>
|
||||
public virtual void Tick()
|
||||
{
|
||||
//行走动画切换
|
||||
if (_walkingTimer > 0)
|
||||
{
|
||||
_walkingTimer -= 1;
|
||||
if (_walkingTimer <= 0)
|
||||
{
|
||||
SetBodyTexture(EntityState.Idle, _currentOrientation);
|
||||
SetBodyTexture(EntityState.Idle, CurrentOrientation);
|
||||
}
|
||||
}
|
||||
|
||||
//行为控制
|
||||
if (PlayerControlled)
|
||||
{
|
||||
UpdatePlayerControls();
|
||||
@@ -336,7 +360,7 @@ namespace Entity
|
||||
{
|
||||
AutoBehave();
|
||||
}
|
||||
|
||||
//血条显示
|
||||
if (IsShowingHealthBarUI)
|
||||
{
|
||||
_hitBarUIShowTimer -= Time.deltaTime;
|
||||
@@ -345,7 +369,7 @@ namespace Entity
|
||||
HideHealthBar();
|
||||
}
|
||||
}
|
||||
|
||||
//攻击控制
|
||||
if (_attackTimer > 0)
|
||||
{
|
||||
_attackTimer -= Time.deltaTime;
|
||||
@@ -366,7 +390,15 @@ namespace Entity
|
||||
if (_attackTimer <= 0)
|
||||
{
|
||||
|
||||
SetBodyTexture(EntityState.Idle, _currentOrientation);
|
||||
SetBodyTexture(EntityState.Idle, CurrentOrientation);
|
||||
}
|
||||
}
|
||||
//条件事件控制
|
||||
foreach (var conditionalEvent in _conditionalEvents)
|
||||
{
|
||||
if (conditionalEvent.Item1(this))
|
||||
{
|
||||
EventManager.Instance.Action(conditionalEvent.Item2, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -407,7 +439,7 @@ namespace Entity
|
||||
{
|
||||
SetBodyTexture(
|
||||
weaponResource.Type == WeaponType.Melee ? EntityState.MeleeAttack : EntityState.RangedAttack,
|
||||
_currentOrientation);
|
||||
CurrentOrientation);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -430,14 +462,14 @@ namespace Entity
|
||||
}
|
||||
}
|
||||
|
||||
_currentState = state;
|
||||
_currentOrientation = orientation;
|
||||
CurrentState = state;
|
||||
CurrentOrientation = orientation;
|
||||
}
|
||||
|
||||
public void HideCurrentBodyTexture()
|
||||
{
|
||||
if (!bodyNodes.TryGetValue(_currentState, out var stateNode)) return;
|
||||
if (stateNode.TryGetValue(_currentOrientation, out var node))
|
||||
if (!bodyNodes.TryGetValue(CurrentState, out var stateNode)) return;
|
||||
if (stateNode.TryGetValue(CurrentOrientation, out var node))
|
||||
{
|
||||
node.SetActive(false);
|
||||
}
|
||||
@@ -451,7 +483,7 @@ namespace Entity
|
||||
// if (IsAttacking)
|
||||
// return;
|
||||
transform.position += direction * (attributes.moveSpeed * Time.deltaTime);
|
||||
SetBodyTexture(EntityState.Walking, _currentOrientation);
|
||||
SetBodyTexture(EntityState.Walking, CurrentOrientation);
|
||||
_walkingTimer = 2;
|
||||
}
|
||||
|
||||
@@ -551,7 +583,7 @@ namespace Entity
|
||||
ori = direction.x > 0 ? Orientation.Right : Orientation.Left;
|
||||
}
|
||||
|
||||
SetBodyTexture(_currentState, ori);
|
||||
SetBodyTexture(CurrentState, ori);
|
||||
if (!PlayerControlled)
|
||||
{
|
||||
attackDirection=direction;
|
||||
@@ -598,7 +630,7 @@ namespace Entity
|
||||
if (weaponItem)
|
||||
RotateTool.RotateTransformToDirection(weaponItem.transform, attackDirection);
|
||||
}
|
||||
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.V))
|
||||
{
|
||||
weaponItem.gameObject.SetActive(!weaponItem.gameObject.activeSelf);
|
||||
@@ -631,7 +663,6 @@ namespace Entity
|
||||
{
|
||||
TryAttack();
|
||||
}
|
||||
|
||||
// 如果有输入方向,则设置目标位置并尝试移动
|
||||
if (inputDirection == Vector2.zero) return;
|
||||
// 归一化方向向量,确保对角线移动速度一致
|
||||
@@ -698,9 +729,9 @@ namespace Entity
|
||||
|
||||
// 假设 EntityManage.Instance.GenerateBulletEntity 方法存在
|
||||
// (需要一个 EntityManage 单例来实现子弹生成)
|
||||
if (EntityManage.Instance != null && Program.Instance != null)
|
||||
if (EntityManager.Instance != null && Program.Instance != null)
|
||||
{
|
||||
EntityManage.Instance.GenerateBulletEntity(
|
||||
EntityManager.Instance.GenerateBulletEntity(
|
||||
Program.Instance.FocusedDimensionId,
|
||||
weapon.Bullet,
|
||||
transform.position, // 子弹的生成位置
|
||||
@@ -718,5 +749,15 @@ namespace Entity
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ExecuteEvent(EntityEventType type)
|
||||
{
|
||||
var eventDefs = entityDef?.eventDef?.GetEventsByType(type);
|
||||
if (eventDefs == null || eventDefs.Length == 0) return;
|
||||
foreach (var eventDef in eventDefs)
|
||||
{
|
||||
EventManager.Instance.Action(eventDef,this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user