Compare commits
2 Commits
be8dd86b29
...
84a0b1d608
Author | SHA1 | Date | |
---|---|---|---|
84a0b1d608 | |||
83089eb80f |
|
@ -24,7 +24,7 @@ size = Vector2(12, 18)
|
|||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ka171"]
|
||||
|
||||
[node name="Role0001" node_paths=PackedStringArray("HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "TipRoot", "TipSprite", "AnimationPlayer", "MountPoint", "BackMountPoint", "MeleeAttackArea", "MeleeAttackCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_10c2n")]
|
||||
collision_layer = 8
|
||||
collision_layer = 24
|
||||
script = ExtResource("2_6xwnt")
|
||||
HurtArea = NodePath("HurtArea")
|
||||
HurtCollision = NodePath("HurtArea/HurtCollision")
|
||||
|
|
|
@ -46,7 +46,7 @@ position = Vector2(0, -2)
|
|||
shape = SubResource("CircleShape2D_5pj80")
|
||||
|
||||
[node name="HurtArea" type="Area2D" parent="."]
|
||||
collision_layer = 0
|
||||
collision_layer = 1024
|
||||
collision_mask = 0
|
||||
monitoring = false
|
||||
script = ExtResource("2_2eey0")
|
||||
|
|
|
@ -246,13 +246,13 @@ roulette={
|
|||
2d_physics/layer_2="bullet"
|
||||
2d_physics/layer_3="prop"
|
||||
2d_physics/layer_4="player"
|
||||
2d_physics/layer_5="enemy"
|
||||
2d_physics/layer_5="role"
|
||||
2d_physics/layer_6="affiliation"
|
||||
2d_physics/layer_7="onHand"
|
||||
2d_physics/layer_8="debris"
|
||||
2d_physics/layer_9="throwing"
|
||||
2d_physics/layer_10="obstacle"
|
||||
2d_physics/layer_11="npc"
|
||||
2d_physics/layer_11="hurtArea"
|
||||
2d_physics/layer_14="ui_mouse"
|
||||
|
||||
[mono]
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
using Godot;
|
||||
|
||||
/// <summary>
|
||||
/// 可被子弹击中的区域
|
||||
/// </summary>
|
||||
[Tool]
|
||||
public partial class HurtArea : Area2D, IHurt
|
||||
{
|
||||
public delegate void HurtDelegate(ActivityObject target, int damage, float angle);
|
||||
/// <summary>
|
||||
/// 所属角色
|
||||
/// </summary>
|
||||
public Role Master { get; private set; }
|
||||
|
||||
public event HurtDelegate OnHurtEvent;
|
||||
|
||||
public ActivityObject ActivityObject { get; private set; }
|
||||
|
||||
public void InitActivityObject(ActivityObject activityObject)
|
||||
public void InitRole(Role role)
|
||||
{
|
||||
ActivityObject = activityObject;
|
||||
Master = role;
|
||||
}
|
||||
|
||||
public override void _Ready()
|
||||
|
@ -19,11 +21,23 @@ public partial class HurtArea : Area2D, IHurt
|
|||
Monitoring = false;
|
||||
}
|
||||
|
||||
public bool CanHurt(ActivityObject target)
|
||||
{
|
||||
//无敌状态
|
||||
if (Master.Invincible)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target is Role role)
|
||||
{
|
||||
return Master.IsEnemy(role);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Hurt(ActivityObject target, int damage, float angle)
|
||||
{
|
||||
if (OnHurtEvent != null)
|
||||
{
|
||||
OnHurtEvent(target, damage, angle);
|
||||
}
|
||||
Master.CallDeferred(nameof(Master.HurtHandler), target, damage, angle);
|
||||
}
|
||||
}
|
|
@ -3,6 +3,12 @@ using Godot;
|
|||
|
||||
public interface IHurt
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回是否可以造成伤害
|
||||
/// </summary>
|
||||
/// <param name="target">触发伤害的对象, 为 null 表示不存在对象或者对象已经被销毁</param>
|
||||
bool CanHurt(ActivityObject target);
|
||||
|
||||
/// <summary>
|
||||
/// 受到伤害
|
||||
/// </summary>
|
||||
|
|
|
@ -21,7 +21,7 @@ public static class NodeExtend
|
|||
|
||||
if (hurt is HurtArea hurtArea)
|
||||
{
|
||||
return hurtArea.ActivityObject;
|
||||
return hurtArea.Master;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -64,7 +64,7 @@ public partial class AffiliationArea : Area2D, IDestroy
|
|||
Monitoring = true;
|
||||
Monitorable = false;
|
||||
CollisionLayer = PhysicsLayer.None;
|
||||
CollisionMask = PhysicsLayer.Prop | PhysicsLayer.Player | PhysicsLayer.Enemy | PhysicsLayer.Debris | PhysicsLayer.Throwing;
|
||||
CollisionMask = PhysicsLayer.Prop | PhysicsLayer.Role | PhysicsLayer.Debris | PhysicsLayer.Throwing | PhysicsLayer.Obstacle;
|
||||
|
||||
BodyEntered += OnBodyEntered;
|
||||
BodyExited += OnBodyExited;
|
||||
|
|
|
@ -317,7 +317,7 @@ public class RoomPreinstall : IDestroy
|
|||
foreach (var preloadData in _readyList)
|
||||
{
|
||||
//有敌人
|
||||
if (!hasEnemy && preloadData.ActivityObject.CollisionWithMask(PhysicsLayer.Enemy))
|
||||
if (!hasEnemy && preloadData.ActivityObject is Role role && role.IsEnemyWithPlayer())
|
||||
{
|
||||
hasEnemy = true;
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ public class RoomPreinstall : IDestroy
|
|||
if (!hasEnemy)
|
||||
{
|
||||
hasEnemy = RoomInfo.AffiliationArea.ExistIncludeItem(
|
||||
activityObject => activityObject.CollisionWithMask(PhysicsLayer.Enemy)
|
||||
activityObject => activityObject is Role role && role.IsEnemyWithPlayer()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -474,7 +474,7 @@ public class RoomInfo : IDestroy
|
|||
|
||||
//房间内有敌人, 或者会刷新敌人才会关门
|
||||
var hasEnemy = false;
|
||||
if (AffiliationArea.ExistEnterItem(activityObject => activityObject.CollisionWithMask(PhysicsLayer.Enemy))) //先判断房间里面是否有敌人
|
||||
if (AffiliationArea.ExistEnterItem(activityObject => activityObject is Role role && role.IsEnemyWithPlayer())) //先判断房间里面是否有敌人
|
||||
{
|
||||
hasEnemy = true;
|
||||
}
|
||||
|
|
|
@ -25,11 +25,6 @@ public partial class Explode : Area2D, IPoolItem
|
|||
/// </summary>
|
||||
public CircleShape2D CircleShape { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 爆炸攻击的层级
|
||||
/// </summary>
|
||||
public uint AttackLayer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产生爆炸的子弹数据
|
||||
/// </summary>
|
||||
|
@ -40,7 +35,12 @@ public partial class Explode : Area2D, IPoolItem
|
|||
private int _harm;
|
||||
private float _repelledRadius;
|
||||
private float _maxRepelled;
|
||||
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
CollisionMask = Role.AttackLayer;
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
if (IsDestroyed)
|
||||
|
@ -56,12 +56,11 @@ public partial class Explode : Area2D, IPoolItem
|
|||
/// 初始化爆炸数据
|
||||
/// </summary>
|
||||
/// <param name="bulletData">产生爆炸的子弹数据</param>
|
||||
/// <param name="attackLayer">攻击的层级</param>
|
||||
/// <param name="hitRadius">伤害半径</param>
|
||||
/// <param name="harm">造成的伤害</param>
|
||||
/// <param name="repelledRadius">击退半径</param>
|
||||
/// <param name="maxRepelled">最大击退速度</param>
|
||||
public void Init(BulletData bulletData, uint attackLayer, float hitRadius, int harm, float repelledRadius, float maxRepelled)
|
||||
public void Init(BulletData bulletData, float hitRadius, int harm, float repelledRadius, float maxRepelled)
|
||||
{
|
||||
if (!_init)
|
||||
{
|
||||
|
@ -75,12 +74,10 @@ public partial class Explode : Area2D, IPoolItem
|
|||
}
|
||||
|
||||
BulletData = bulletData;
|
||||
AttackLayer = attackLayer;
|
||||
_hitRadius = hitRadius;
|
||||
_harm = harm;
|
||||
_repelledRadius = repelledRadius;
|
||||
_maxRepelled = maxRepelled;
|
||||
CollisionMask = attackLayer | PhysicsLayer.Prop | PhysicsLayer.Debris;
|
||||
CircleShape.Radius = Mathf.Max(hitRadius, maxRepelled);
|
||||
|
||||
//冲击波
|
||||
|
@ -162,18 +159,22 @@ public partial class Explode : Area2D, IPoolItem
|
|||
var len = temp.Length();
|
||||
var angle = temp.Angle();
|
||||
|
||||
if (len <= _hitRadius) //在伤害半径内
|
||||
var target = BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole;
|
||||
if (hurt.CanHurt(target))
|
||||
{
|
||||
hurt.Hurt(BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole, _harm, angle);
|
||||
}
|
||||
|
||||
if (len <= _repelledRadius) //击退半径内
|
||||
{
|
||||
var o = hurt.GetActivityObject();
|
||||
if (o != null)
|
||||
if (len <= _hitRadius) //在伤害半径内
|
||||
{
|
||||
var repelled = (_repelledRadius - len) / _repelledRadius * _maxRepelled;
|
||||
o.AddRepelForce(Vector2.FromAngle(angle) * repelled);
|
||||
hurt.Hurt(target, _harm, angle);
|
||||
}
|
||||
|
||||
if (len <= _repelledRadius) //击退半径内
|
||||
{
|
||||
var o = hurt.GetActivityObject();
|
||||
if (o != null)
|
||||
{
|
||||
var repelled = (_repelledRadius - len) / _repelledRadius * _maxRepelled;
|
||||
o.AddRepelForce(Vector2.FromAngle(angle) * repelled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,18 +24,14 @@ public partial class Laser : Area2D, IBullet
|
|||
public Sprite2D LineSprite { get; private set; }
|
||||
public RectangleShape2D Shape { get; private set; }
|
||||
|
||||
public CampEnum Camp { get; set; }
|
||||
|
||||
public event Action OnReclaimEvent;
|
||||
public event Action OnLeavePoolEvent;
|
||||
|
||||
public bool IsRecycled { get; set; }
|
||||
public string Logotype { get; set; }
|
||||
|
||||
public uint AttackLayer
|
||||
{
|
||||
get => CollisionMask;
|
||||
set => CollisionMask = value;
|
||||
}
|
||||
|
||||
public BulletData BulletData { get; private set; }
|
||||
public BulletStateEnum State { get; protected set; } = BulletStateEnum.Normal;
|
||||
|
||||
|
@ -49,12 +45,17 @@ public partial class Laser : Area2D, IBullet
|
|||
private Tween _tween;
|
||||
private bool _init = false;
|
||||
|
||||
public void InitData(BulletData data, uint attackLayer)
|
||||
public override void _Ready()
|
||||
{
|
||||
InitData(data, attackLayer, LaserDefaultWidth);
|
||||
CollisionMask = Role.AttackLayer;
|
||||
}
|
||||
|
||||
public void InitData(BulletData data, uint attackLayer, float width)
|
||||
public void InitData(BulletData data, CampEnum camp)
|
||||
{
|
||||
InitData(data, camp, LaserDefaultWidth);
|
||||
}
|
||||
|
||||
public void InitData(BulletData data, CampEnum camp, float width)
|
||||
{
|
||||
if (!_init)
|
||||
{
|
||||
|
@ -70,9 +71,9 @@ public partial class Laser : Area2D, IBullet
|
|||
_init = true;
|
||||
}
|
||||
|
||||
Camp = camp;
|
||||
ZIndex = 1;
|
||||
BulletData = data;
|
||||
AttackLayer = attackLayer;
|
||||
|
||||
Position = data.Position;
|
||||
Rotation = data.Rotation;
|
||||
|
@ -103,7 +104,7 @@ public partial class Laser : Area2D, IBullet
|
|||
LineSprite.Scale = new Vector2(0, width * _pixelScale);
|
||||
|
||||
//如果子弹会对玩家造成伤害, 则显示成红色
|
||||
if (BulletData.World.Player.CollisionWithMask(attackLayer))
|
||||
if (BulletData.TriggerRole != null && BulletData.TriggerRole.IsEnemyWithPlayer())
|
||||
{
|
||||
LineSprite.Modulate = new Color(2.5f, 0.5f, 0.5f);
|
||||
}
|
||||
|
@ -191,7 +192,7 @@ public partial class Laser : Area2D, IBullet
|
|||
bulletData.BounceCount -= 1;
|
||||
bulletData.MaxDistance = newDistance;
|
||||
bulletData.Rotation = rotation;
|
||||
FireManager.ShootBullet(bulletData, AttackLayer);
|
||||
FireManager.ShootBullet(bulletData, Camp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,17 +215,21 @@ public partial class Laser : Area2D, IBullet
|
|||
|
||||
private void HandlerCollision(IHurt hurt)
|
||||
{
|
||||
if (BulletData.Repel != 0)
|
||||
var target = BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole;
|
||||
if (hurt.CanHurt(target))
|
||||
{
|
||||
var o = hurt.GetActivityObject();
|
||||
if (o != null && o is not Player) //目标不是玩家才会触发击退
|
||||
if (BulletData.Repel != 0)
|
||||
{
|
||||
o.AddRepelForce(Vector2.FromAngle(Rotation) * BulletData.Repel);
|
||||
var o = hurt.GetActivityObject();
|
||||
if (o != null && o is not Player) //目标不是玩家才会触发击退
|
||||
{
|
||||
o.AddRepelForce(Vector2.FromAngle(Rotation) * BulletData.Repel);
|
||||
}
|
||||
}
|
||||
|
||||
//造成伤害
|
||||
hurt.Hurt(target, BulletData.Harm, Rotation);
|
||||
}
|
||||
|
||||
//造成伤害
|
||||
hurt.Hurt(BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole, BulletData.Harm, Rotation);
|
||||
}
|
||||
|
||||
public long StartCoroutine(IEnumerator able)
|
||||
|
|
|
@ -10,9 +10,9 @@ public partial class Arrow : Bullet, IMountItem
|
|||
[Export, ExportFillNode]
|
||||
public AnimatedSprite2D HalfSprite { get; set; }
|
||||
|
||||
public override void InitData(BulletData data, uint attackLayer)
|
||||
public override void InitData(BulletData data, CampEnum camp)
|
||||
{
|
||||
base.InitData(data, attackLayer);
|
||||
base.InitData(data, camp);
|
||||
SetEnableMovement(true);
|
||||
EnableVerticalMotion = false;
|
||||
DefaultLayer = RoomLayerEnum.NormalLayer;
|
||||
|
|
|
@ -59,7 +59,7 @@ public partial class BoomBullet : Bullet
|
|||
explode.Position = pos;
|
||||
explode.RotationDegrees = Utils.Random.RandomRangeInt(0, 360);
|
||||
explode.AddToActivityRootDeferred(RoomLayerEnum.YSortLayer);
|
||||
explode.Init(BulletData, AttackLayer, 25, BulletData.Harm, 50, BulletData.Repel);
|
||||
explode.Init(BulletData, 25, BulletData.Harm, 50, BulletData.Repel);
|
||||
explode.RunPlay(BulletData.TriggerRole);
|
||||
if (AffiliationArea != null)
|
||||
{
|
||||
|
|
|
@ -12,9 +12,12 @@ public partial class Bullet : ActivityObject, IBullet
|
|||
{
|
||||
public event Action OnReclaimEvent;
|
||||
public event Action OnLeavePoolEvent;
|
||||
|
||||
public bool IsRecycled { get; set; }
|
||||
public string Logotype { get; set; }
|
||||
|
||||
public CampEnum Camp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子弹伤害碰撞区域
|
||||
/// </summary>
|
||||
|
@ -33,15 +36,6 @@ public partial class Bullet : ActivityObject, IBullet
|
|||
[Export]
|
||||
public Array<GpuParticles2D> Particles2D { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 攻击的层级
|
||||
/// </summary>
|
||||
public uint AttackLayer
|
||||
{
|
||||
get => CollisionArea.CollisionMask;
|
||||
set => CollisionArea.CollisionMask = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 子弹使用的数据
|
||||
/// </summary>
|
||||
|
@ -77,9 +71,11 @@ public partial class Bullet : ActivityObject, IBullet
|
|||
base.OnInit();
|
||||
OutlineColor = new Color(2.5f, 0, 0);
|
||||
SetBlendColor(new Color(2.5f, 2.5f, 2.5f));
|
||||
|
||||
CollisionArea.CollisionMask = Role.AttackLayer;
|
||||
}
|
||||
|
||||
public virtual void InitData(BulletData data, uint attackLayer)
|
||||
public virtual void InitData(BulletData data, CampEnum camp)
|
||||
{
|
||||
if (!_init)
|
||||
{
|
||||
|
@ -87,13 +83,13 @@ public partial class Bullet : ActivityObject, IBullet
|
|||
CollisionArea.BodyEntered += OnBodyEntered;
|
||||
_init = true;
|
||||
}
|
||||
|
||||
|
||||
Camp = camp;
|
||||
CurrentBounce = 0;
|
||||
CurrentPenetration = 0;
|
||||
CurrFlyDistance = 0;
|
||||
|
||||
BulletData = data;
|
||||
AttackLayer = attackLayer;
|
||||
Rotation = data.Rotation;
|
||||
|
||||
var triggerRole = data.TriggerRole;
|
||||
|
@ -120,7 +116,7 @@ public partial class Bullet : ActivityObject, IBullet
|
|||
MoveController.AddForce(new Vector2(data.FlySpeed, 0).Rotated(Rotation));
|
||||
|
||||
//如果子弹会对玩家造成伤害, 则显示红色描边
|
||||
if (World.Player != null && World.Player.CollisionWithMask(attackLayer))
|
||||
if (triggerRole != null && triggerRole.IsEnemyWithPlayer())
|
||||
{
|
||||
if (!IsEnemyBullet)
|
||||
{
|
||||
|
@ -193,25 +189,29 @@ public partial class Bullet : ActivityObject, IBullet
|
|||
/// </summary>
|
||||
public virtual void OnCollisionTarget(IHurt hurt)
|
||||
{
|
||||
OnPlayDisappearEffect();
|
||||
if (BulletData.Repel != 0)
|
||||
var target = BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole;
|
||||
if (hurt.CanHurt(target))
|
||||
{
|
||||
var o = hurt.GetActivityObject();
|
||||
if (o != null && o is not Player) //目标不是玩家才会触发击退
|
||||
OnPlayDisappearEffect();
|
||||
if (BulletData.Repel != 0)
|
||||
{
|
||||
o.AddRepelForce(Velocity.Normalized() * BulletData.Repel);
|
||||
var o = hurt.GetActivityObject();
|
||||
if (o != null && o is not Player) //目标不是玩家才会触发击退
|
||||
{
|
||||
o.AddRepelForce(Velocity.Normalized() * BulletData.Repel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//造成伤害
|
||||
hurt.Hurt(BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole, BulletData.Harm, Rotation);
|
||||
|
||||
//穿透次数
|
||||
CurrentPenetration++;
|
||||
if (CurrentPenetration > BulletData.Penetration)
|
||||
{
|
||||
State = BulletStateEnum.CollisionTarget;
|
||||
CallDeferred(nameof(LogicalFinish));
|
||||
|
||||
//造成伤害
|
||||
hurt.Hurt(target, BulletData.Harm, Rotation);
|
||||
|
||||
//穿透次数
|
||||
CurrentPenetration++;
|
||||
if (CurrentPenetration > BulletData.Penetration)
|
||||
{
|
||||
State = BulletStateEnum.CollisionTarget;
|
||||
CallDeferred(nameof(LogicalFinish));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,10 @@ public interface IBullet : ICoroutine, IPoolItem
|
|||
event Action OnLeavePoolEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 攻击的层级
|
||||
/// 子弹所在阵营
|
||||
/// </summary>
|
||||
uint AttackLayer { get; set; }
|
||||
CampEnum Camp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 子弹数据
|
||||
/// </summary>
|
||||
|
@ -30,7 +31,8 @@ public interface IBullet : ICoroutine, IPoolItem
|
|||
/// <summary>
|
||||
/// 初始化子弹数据
|
||||
/// </summary>
|
||||
void InitData(BulletData data, uint attackLayer);
|
||||
void InitData(BulletData data, CampEnum camp);
|
||||
|
||||
/// <summary>
|
||||
/// 子弹运行逻辑执行完成
|
||||
/// </summary>
|
||||
|
|
|
@ -8,9 +8,9 @@ public partial class TrailBullet : Bullet
|
|||
private static Color EnemyTerrainColor = new Color(1.5f, 0, 0, 0.7f);
|
||||
private Trail trail;
|
||||
|
||||
public override void InitData(BulletData data, uint attackLayer)
|
||||
public override void InitData(BulletData data, CampEnum camp)
|
||||
{
|
||||
base.InitData(data, attackLayer);
|
||||
base.InitData(data, camp);
|
||||
|
||||
trail = ObjectManager.GetPoolItem<Trail>(ResourcePath.prefab_effect_common_Trail0001_tscn);
|
||||
trail.SetTarget(AnimatedSprite);
|
||||
|
|
|
@ -7,6 +7,11 @@ using Godot;
|
|||
[Tool]
|
||||
public partial class ObstacleObject : ActivityObject, IHurt
|
||||
{
|
||||
public virtual bool CanHurt(ActivityObject target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Hurt(ActivityObject target, int damage, float angle)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,10 +1,28 @@
|
|||
|
||||
public enum CampEnum
|
||||
{
|
||||
// 阵营1, 玩家
|
||||
/// <summary>
|
||||
/// 无阵营, 所有角色都视为敌人
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// 和平阵营, 不会被攻击
|
||||
/// </summary>
|
||||
Peace,
|
||||
/// <summary>
|
||||
/// 阵营1, 玩家
|
||||
/// </summary>
|
||||
Camp1,
|
||||
// 阵营2, 敌人
|
||||
/// <summary>
|
||||
/// 阵营2, 敌人
|
||||
/// </summary>
|
||||
Camp2,
|
||||
// 阵营3, 中立单位
|
||||
Camp3
|
||||
/// <summary>
|
||||
/// 阵营3, 敌人2
|
||||
/// </summary>
|
||||
Camp3,
|
||||
/// <summary>
|
||||
/// 阵营4, 敌人3
|
||||
/// </summary>
|
||||
Camp4,
|
||||
}
|
|
@ -10,6 +10,11 @@ using Godot;
|
|||
/// </summary>
|
||||
public abstract partial class Role : ActivityObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 攻击目标的碰撞器所属层级, 数据源自于: <see cref="PhysicsLayer"/>
|
||||
/// </summary>
|
||||
public const uint AttackLayer = PhysicsLayer.Wall | PhysicsLayer.Obstacle | PhysicsLayer.HurtArea;
|
||||
|
||||
/// <summary>
|
||||
/// 当前角色对其他角色造成伤害时对回调
|
||||
/// 参数1为目标角色
|
||||
|
@ -27,11 +32,6 @@ public abstract partial class Role : ActivityObject
|
|||
/// </summary>
|
||||
public RoleState RoleState { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认攻击对象层级
|
||||
/// </summary>
|
||||
public const uint DefaultAttackLayer = PhysicsLayer.Player | PhysicsLayer.Enemy | PhysicsLayer.Obstacle;
|
||||
|
||||
/// <summary>
|
||||
/// 伤害区域
|
||||
/// </summary>
|
||||
|
@ -47,17 +47,7 @@ public abstract partial class Role : ActivityObject
|
|||
/// <summary>
|
||||
/// 所属阵营
|
||||
/// </summary>
|
||||
public CampEnum Camp;
|
||||
|
||||
/// <summary>
|
||||
/// 攻击目标的碰撞器所属层级, 数据源自于: <see cref="PhysicsLayer"/>
|
||||
/// </summary>
|
||||
public uint AttackLayer { get; set; } = PhysicsLayer.Wall | PhysicsLayer.Obstacle;
|
||||
|
||||
/// <summary>
|
||||
/// 该角色敌对目标的碰撞器所属层级, 数据源自于: <see cref="PhysicsLayer"/>
|
||||
/// </summary>
|
||||
public uint EnemyLayer { get; set; } = PhysicsLayer.Enemy;
|
||||
public CampEnum Camp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 携带的被动道具列表
|
||||
|
@ -282,20 +272,11 @@ public abstract partial class Role : ActivityObject
|
|||
{
|
||||
if (value) //无敌状态
|
||||
{
|
||||
if (HurtArea != null)
|
||||
{
|
||||
HurtArea.CollisionLayer = _currentLayer;
|
||||
}
|
||||
|
||||
_flashingInvincibleTimer = -1;
|
||||
_flashingInvincibleFlag = false;
|
||||
}
|
||||
else //正常状态
|
||||
{
|
||||
if (HurtArea != null)
|
||||
{
|
||||
HurtArea.CollisionLayer = _currentLayer;
|
||||
}
|
||||
SetBlendModulate(new Color(1, 1, 1, 1));
|
||||
}
|
||||
}
|
||||
|
@ -335,7 +316,6 @@ public abstract partial class Role : ActivityObject
|
|||
private Vector2 _startScale;
|
||||
//当前可互动的物体
|
||||
private CheckInteractiveResult _currentResultData;
|
||||
private uint _currentLayer;
|
||||
//闪烁计时器
|
||||
private float _flashingInvincibleTimer = -1;
|
||||
//闪烁状态
|
||||
|
@ -479,15 +459,7 @@ public abstract partial class Role : ActivityObject
|
|||
|
||||
_startScale = Scale;
|
||||
|
||||
HurtArea.InitActivityObject(this);
|
||||
HurtArea.CollisionLayer = CollisionLayer;
|
||||
HurtArea.CollisionMask = PhysicsLayer.None;
|
||||
_currentLayer = HurtArea.CollisionLayer;
|
||||
//CollisionLayer = PhysicsLayer.None;
|
||||
HurtArea.OnHurtEvent += (target, damage, angle) =>
|
||||
{
|
||||
CallDeferred(nameof(HurtHandler), target, damage, angle);
|
||||
};
|
||||
HurtArea.InitRole(this);
|
||||
|
||||
Face = FaceDirection.Right;
|
||||
|
||||
|
@ -857,7 +829,7 @@ public abstract partial class Role : ActivityObject
|
|||
/// <param name="target">触发伤害的对象, 为 null 表示不存在对象或者对象已经被销毁</param>
|
||||
/// <param name="damage">伤害的量</param>
|
||||
/// <param name="angle">伤害角度(弧度制)</param>
|
||||
protected virtual void HurtHandler(ActivityObject target, int damage, float angle)
|
||||
public virtual void HurtHandler(ActivityObject target, int damage, float angle)
|
||||
{
|
||||
//受伤闪烁, 无敌状态
|
||||
if (Invincible)
|
||||
|
@ -1016,6 +988,33 @@ public abstract partial class Role : ActivityObject
|
|||
return this == World.Player;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 返回指定角色是否是敌人
|
||||
/// </summary>
|
||||
public bool IsEnemy(Role other)
|
||||
{
|
||||
if (other.Camp == Camp || other.Camp == CampEnum.Peace || Camp == CampEnum.Peace)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回指定阵营是否是敌人
|
||||
/// </summary>
|
||||
public bool IsEnemy(CampEnum otherCamp)
|
||||
{
|
||||
if (otherCamp == Camp || otherCamp == CampEnum.Peace || Camp == CampEnum.Peace)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是玩家的敌人
|
||||
/// </summary>
|
||||
|
@ -1025,7 +1024,7 @@ public abstract partial class Role : ActivityObject
|
|||
{
|
||||
return false;
|
||||
}
|
||||
return CollisionWithMask(World.Player.EnemyLayer);
|
||||
return IsEnemy(World.Player);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1413,8 +1412,7 @@ public abstract partial class Role : ActivityObject
|
|||
}
|
||||
else if (body is Bullet bullet) //攻击子弹
|
||||
{
|
||||
var attackLayer = bullet.AttackLayer;
|
||||
if (CollisionWithMask(attackLayer)) //是攻击玩家的子弹
|
||||
if (IsEnemy(bullet.BulletData.TriggerRole))
|
||||
{
|
||||
bullet.OnPlayDisappearEffect();
|
||||
bullet.Destroy();
|
||||
|
@ -1424,21 +1422,24 @@ public abstract partial class Role : ActivityObject
|
|||
|
||||
private void HandlerCollision(IHurt hurt, Weapon activeWeapon)
|
||||
{
|
||||
var damage = Utils.Random.RandomConfigRange(activeWeapon.Attribute.MeleeAttackHarmRange);
|
||||
damage = RoleState.CalcDamage(damage);
|
||||
|
||||
var o = hurt.GetActivityObject();
|
||||
var pos = hurt.GetPosition();
|
||||
if (o != null && o is not Player) //不是玩家才能被击退
|
||||
if (hurt.CanHurt(this))
|
||||
{
|
||||
var attr = IsAi ? activeWeapon.AiUseAttribute : activeWeapon.PlayerUseAttribute;
|
||||
var repel = Utils.Random.RandomConfigRange(attr.MeleeAttackRepelRange);
|
||||
var position = pos - MountPoint.GlobalPosition;
|
||||
var v2 = position.Normalized() * repel;
|
||||
o.AddRepelForce(v2);
|
||||
var damage = Utils.Random.RandomConfigRange(activeWeapon.Attribute.MeleeAttackHarmRange);
|
||||
damage = RoleState.CalcDamage(damage);
|
||||
|
||||
var o = hurt.GetActivityObject();
|
||||
var pos = hurt.GetPosition();
|
||||
if (o != null && o is not Player) //不是玩家才能被击退
|
||||
{
|
||||
var attr = IsAi ? activeWeapon.AiUseAttribute : activeWeapon.PlayerUseAttribute;
|
||||
var repel = Utils.Random.RandomConfigRange(attr.MeleeAttackRepelRange);
|
||||
var position = pos - MountPoint.GlobalPosition;
|
||||
var v2 = position.Normalized() * repel;
|
||||
o.AddRepelForce(v2);
|
||||
}
|
||||
|
||||
hurt.Hurt(this, damage, (pos - GlobalPosition).Angle());
|
||||
}
|
||||
|
||||
hurt.Hurt(this, damage, (pos - GlobalPosition).Angle());
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
|
|
|
@ -63,9 +63,6 @@ public partial class Enemy : AiRole
|
|||
public override void OnInit()
|
||||
{
|
||||
base.OnInit();
|
||||
|
||||
AttackLayer = PhysicsLayer.Obstacle | PhysicsLayer.Player;
|
||||
EnemyLayer = PhysicsLayer.Player;
|
||||
Camp = CampEnum.Camp2;
|
||||
|
||||
RoleState.MoveSpeed = 20;
|
||||
|
|
|
@ -56,7 +56,7 @@ public partial class NoWeaponEnemy : Enemy
|
|||
var data = bulletData.Clone();
|
||||
var tempPos = new Vector2(targetPosition.X + Utils.Random.RandomRangeInt(-30, 30), targetPosition.Y + Utils.Random.RandomRangeInt(-30, 30));
|
||||
FireManager.SetParabolaTarget(data, tempPos);
|
||||
FireManager.ShootBullet(data, AttackLayer);
|
||||
FireManager.ShootBullet(data, Camp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,6 @@ public partial class Player : Role
|
|||
|
||||
IsAi = false;
|
||||
StateController = AddComponent<StateController<Player, PlayerStateEnum>>();
|
||||
AttackLayer = PhysicsLayer.Obstacle | PhysicsLayer.Enemy;
|
||||
EnemyLayer = EnemyLayer = PhysicsLayer.Enemy;
|
||||
Camp = CampEnum.Camp1;
|
||||
|
||||
MaxHp = 6;
|
||||
|
@ -223,10 +221,14 @@ public partial class Player : Role
|
|||
}
|
||||
else if (Input.IsKeyPressed(Key.O)) //测试用, 消灭房间内所有敌人
|
||||
{
|
||||
var enemyList = AffiliationArea.FindIncludeItems(o => o.CollisionWithMask(PhysicsLayer.Enemy));
|
||||
var enemyList = AffiliationArea.FindIncludeItems(o => o is Role role && role.IsEnemyWithPlayer());
|
||||
foreach (var enemy in enemyList)
|
||||
{
|
||||
((Enemy)enemy).HurtArea.Hurt(this, 1000, 0);
|
||||
var hurt = ((Enemy)enemy).HurtArea;
|
||||
if (hurt.CanHurt(this))
|
||||
{
|
||||
hurt.Hurt(this, 1000, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
// //测试用
|
||||
|
|
|
@ -27,11 +27,6 @@ public abstract partial class Weapon : ActivityObject, IPackageItem<Role>
|
|||
private ExcelConfig.WeaponBase _playerWeaponAttribute;
|
||||
private ExcelConfig.WeaponBase _aiWeaponAttribute;
|
||||
|
||||
/// <summary>
|
||||
/// 武器攻击的目标阵营
|
||||
/// </summary>
|
||||
public CampEnum TargetCamp { get; set; }
|
||||
|
||||
public Role Master { get; set; }
|
||||
|
||||
public int PackageIndex { get; set; } = -1;
|
||||
|
@ -149,11 +144,6 @@ public abstract partial class Weapon : ActivityObject, IPackageItem<Role>
|
|||
/// </summary>
|
||||
public Role TriggerRole { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上一次触发改武器开火的触发开火攻击的层级, 数据源自于: <see cref="PhysicsLayer"/>
|
||||
/// </summary>
|
||||
public long TriggerRoleAttackLayer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 武器当前射速
|
||||
/// </summary>
|
||||
|
@ -850,13 +840,11 @@ public abstract partial class Weapon : ActivityObject, IPackageItem<Role>
|
|||
if (triggerRole != null)
|
||||
{
|
||||
TriggerRole = triggerRole;
|
||||
TriggerRoleAttackLayer = triggerRole.AttackLayer;
|
||||
SetCurrentWeaponAttribute(triggerRole.IsAi ? _aiWeaponAttribute : _playerWeaponAttribute);
|
||||
}
|
||||
else if (Master != null)
|
||||
{
|
||||
TriggerRole = Master;
|
||||
TriggerRoleAttackLayer = Master.AttackLayer;
|
||||
SetCurrentWeaponAttribute(Master.IsAi ? _aiWeaponAttribute : _playerWeaponAttribute);
|
||||
}
|
||||
|
||||
|
@ -1275,19 +1263,6 @@ public abstract partial class Weapon : ActivityObject, IPackageItem<Role>
|
|||
return AiUseAttribute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取武器攻击的目标层级
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public uint GetAttackLayer()
|
||||
{
|
||||
if (TriggerRoleAttackLayer > 0)
|
||||
{
|
||||
return (uint)TriggerRoleAttackLayer;
|
||||
}
|
||||
return Master != null ? Master.AttackLayer : Role.DefaultAttackLayer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回弹药是否到达上限
|
||||
/// </summary>
|
||||
|
|
|
@ -26,7 +26,7 @@ public partial class Knife : Weapon
|
|||
public override void OnInit()
|
||||
{
|
||||
base.OnInit();
|
||||
|
||||
|
||||
//没有Master时不能触发开火
|
||||
NoMasterCanTrigger = false;
|
||||
_hitArea = GetNode<Area2D>("HitArea");
|
||||
|
@ -40,6 +40,9 @@ public partial class Knife : Weapon
|
|||
_hitArea.Monitorable = false;
|
||||
_hitArea.BodyEntered += OnBodyEntered;
|
||||
_hitArea.AreaEntered += OnArea2dEntered;
|
||||
|
||||
//更新碰撞层级
|
||||
_hitArea.CollisionMask = Role.AttackLayer | PhysicsLayer.Bullet;
|
||||
|
||||
//禁用自动播放动画
|
||||
IsAutoPlaySpriteFrames = false;
|
||||
|
@ -74,8 +77,6 @@ public partial class Knife : Weapon
|
|||
protected override void OnFire()
|
||||
{
|
||||
Debug.Log("近战武器攻击! 蓄力时长: " + GetTriggerChargeTime() + ", 扳机按下时长: " + GetTriggerDownTime());
|
||||
//更新碰撞层级
|
||||
_hitArea.CollisionMask = GetAttackLayer() | PhysicsLayer.Bullet;
|
||||
//启用碰撞
|
||||
_hitArea.Monitoring = true;
|
||||
_attackIndex = 0;
|
||||
|
@ -130,8 +131,7 @@ public partial class Knife : Weapon
|
|||
}
|
||||
else if (body is Bullet bullet) //攻击子弹
|
||||
{
|
||||
var attackLayer = bullet.AttackLayer;
|
||||
if (TriggerRole != null && TriggerRole.CollisionWithMask(attackLayer)) //是攻击玩家的子弹
|
||||
if (TriggerRole != null && TriggerRole.IsEnemy(bullet.BulletData.TriggerRole))
|
||||
{
|
||||
//反弹子弹
|
||||
bullet.OnPlayDisappearEffect();
|
||||
|
@ -143,7 +143,7 @@ public partial class Knife : Weapon
|
|||
}
|
||||
bullet.MoveController.ScaleAllVelocity(scale);
|
||||
bullet.Rotation += Mathf.Pi;
|
||||
bullet.AttackLayer = TriggerRole.AttackLayer;
|
||||
bullet.Camp = Master.Camp;
|
||||
bullet.RefreshBulletColor(false);
|
||||
}
|
||||
}
|
||||
|
@ -159,42 +159,45 @@ public partial class Knife : Weapon
|
|||
|
||||
private void HandlerCollision(IHurt hurt)
|
||||
{
|
||||
var damage = Utils.Random.RandomConfigRange(Attribute.Bullet.HarmRange);
|
||||
//计算子弹造成的伤害
|
||||
if (TriggerRole != null)
|
||||
if (hurt.CanHurt(TriggerRole))
|
||||
{
|
||||
damage = TriggerRole.RoleState.CalcDamage(damage);
|
||||
}
|
||||
//击退
|
||||
var attr = GetUseAttribute(TriggerRole);
|
||||
var repel = Utils.Random.RandomConfigRange(attr.Bullet.RepelRange);
|
||||
//计算击退
|
||||
if (TriggerRole != null)
|
||||
{
|
||||
repel = TriggerRole.RoleState.CalcBulletRepel(repel);
|
||||
}
|
||||
|
||||
var globalPosition = GlobalPosition;
|
||||
if (repel != 0)
|
||||
{
|
||||
var o = hurt.GetActivityObject();
|
||||
if (o != null && o is not Player) //不是玩家才能被击退
|
||||
var damage = Utils.Random.RandomConfigRange(Attribute.Bullet.HarmRange);
|
||||
//计算子弹造成的伤害
|
||||
if (TriggerRole != null)
|
||||
{
|
||||
Vector2 position;
|
||||
if (TriggerRole != null)
|
||||
{
|
||||
position = o.GlobalPosition - TriggerRole.MountPoint.GlobalPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
position = o.GlobalPosition - globalPosition;
|
||||
}
|
||||
var v2 = position.Normalized() * repel;
|
||||
o.AddRepelForce(v2);
|
||||
damage = TriggerRole.RoleState.CalcDamage(damage);
|
||||
}
|
||||
//击退
|
||||
var attr = GetUseAttribute(TriggerRole);
|
||||
var repel = Utils.Random.RandomConfigRange(attr.Bullet.RepelRange);
|
||||
//计算击退
|
||||
if (TriggerRole != null)
|
||||
{
|
||||
repel = TriggerRole.RoleState.CalcBulletRepel(repel);
|
||||
}
|
||||
}
|
||||
|
||||
//造成伤害
|
||||
hurt.Hurt(TriggerRole, damage, (hurt.GetPosition() - globalPosition).Angle());
|
||||
var globalPosition = GlobalPosition;
|
||||
if (repel != 0)
|
||||
{
|
||||
var o = hurt.GetActivityObject();
|
||||
if (o != null && o is not Player) //不是玩家才能被击退
|
||||
{
|
||||
Vector2 position;
|
||||
if (TriggerRole != null)
|
||||
{
|
||||
position = o.GlobalPosition - TriggerRole.MountPoint.GlobalPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
position = o.GlobalPosition - globalPosition;
|
||||
}
|
||||
var v2 = position.Normalized() * repel;
|
||||
o.AddRepelForce(v2);
|
||||
}
|
||||
}
|
||||
|
||||
//造成伤害
|
||||
hurt.Hurt(TriggerRole, damage, (hurt.GetPosition() - globalPosition).Angle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ public class PhysicsLayer
|
|||
/// </summary>
|
||||
public const uint Player = 0b1000;
|
||||
/// <summary>
|
||||
/// 敌人
|
||||
/// 角色基类
|
||||
/// </summary>
|
||||
public const uint Enemy = 0b10000;
|
||||
public const uint Role = 0b10000;
|
||||
/// <summary>
|
||||
/// 归属区域判断层级
|
||||
/// </summary>
|
||||
|
@ -48,7 +48,7 @@ public class PhysicsLayer
|
|||
/// </summary>
|
||||
public const uint Obstacle = 0b1000000000;
|
||||
/// <summary>
|
||||
/// npc
|
||||
/// 可被子弹击中的区域
|
||||
/// </summary>
|
||||
public const uint Npc = 0b10000000000;
|
||||
public const uint HurtArea = 0b10000000000;
|
||||
}
|
|
@ -97,11 +97,13 @@ public static class FireManager
|
|||
{
|
||||
if (bullet.Type == 1) //实体子弹
|
||||
{
|
||||
return ShootSolidBullet(CreateSolidBulletData(weapon, fireRotation, bullet), weapon.GetAttackLayer());
|
||||
return ShootSolidBullet(CreateSolidBulletData(weapon, fireRotation, bullet),
|
||||
weapon.TriggerRole != null ? weapon.TriggerRole.Camp : CampEnum.None);
|
||||
}
|
||||
else if (bullet.Type == 2) //激光子弹
|
||||
{
|
||||
return ShootLaser(CreateLaserData(weapon, fireRotation, bullet), weapon.GetAttackLayer());
|
||||
return ShootLaser(CreateLaserData(weapon, fireRotation, bullet),
|
||||
weapon.TriggerRole != null ? weapon.TriggerRole.Camp : CampEnum.None);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -118,7 +120,7 @@ public static class FireManager
|
|||
{
|
||||
if (bullet.Type == 1) //实体子弹
|
||||
{
|
||||
return ShootSolidBullet(CreateSolidBulletData(trigger, fireRotation, bullet), trigger.AttackLayer);
|
||||
return ShootSolidBullet(CreateSolidBulletData(trigger, fireRotation, bullet), trigger.Camp);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -127,15 +129,15 @@ public static class FireManager
|
|||
/// <summary>
|
||||
/// 通过 BulletData 直接发射子弹
|
||||
/// </summary>
|
||||
public static IBullet ShootBullet(BulletData bulletData, uint attackLayer)
|
||||
public static IBullet ShootBullet(BulletData bulletData, CampEnum camp)
|
||||
{
|
||||
if (bulletData.BulletBase.Type == 1) //实体子弹
|
||||
{
|
||||
return ShootSolidBullet(bulletData, attackLayer);
|
||||
return ShootSolidBullet(bulletData, camp);
|
||||
}
|
||||
else if (bulletData.BulletBase.Type == 2) //激光子弹
|
||||
{
|
||||
return ShootLaser(bulletData, attackLayer);
|
||||
return ShootLaser(bulletData, camp);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -148,23 +150,23 @@ public static class FireManager
|
|||
/// <summary>
|
||||
/// 发射子弹的默认实现方式
|
||||
/// </summary>
|
||||
private static Bullet ShootSolidBullet(BulletData bulletData, uint attackLayer)
|
||||
private static Bullet ShootSolidBullet(BulletData bulletData, CampEnum camp)
|
||||
{
|
||||
//创建子弹
|
||||
var bulletInstance = ObjectManager.GetBullet(bulletData.BulletBase.Prefab);
|
||||
bulletInstance.InitData(bulletData, attackLayer);
|
||||
bulletInstance.InitData(bulletData, camp);
|
||||
return bulletInstance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发射射线的默认实现方式
|
||||
/// </summary>
|
||||
private static Laser ShootLaser(BulletData bulletData, uint attackLayer)
|
||||
private static Laser ShootLaser(BulletData bulletData, CampEnum camp)
|
||||
{
|
||||
//创建激光
|
||||
var laser = ObjectManager.GetLaser(bulletData.BulletBase.Prefab);
|
||||
laser.AddToActivityRoot(RoomLayerEnum.YSortLayer);
|
||||
laser.InitData(bulletData, attackLayer, Laser.LaserDefaultWidth);
|
||||
laser.InitData(bulletData, camp, Laser.LaserDefaultWidth);
|
||||
return laser;
|
||||
}
|
||||
|
||||
|
|
|
@ -904,7 +904,7 @@ public partial class DungeonManager : Node2D
|
|||
{
|
||||
//房间内是否有存活的敌人
|
||||
var flag = ActiveAffiliationArea.ExistEnterItem(
|
||||
activityObject => activityObject.CollisionWithMask(PhysicsLayer.Enemy)
|
||||
activityObject => activityObject is Role role && role.IsEnemyWithPlayer()
|
||||
);
|
||||
//Debug.Log("当前房间存活数量: " + count);
|
||||
if (!flag)
|
||||
|
|
Loading…
Reference in New Issue
Block a user