diff --git a/DungeonShooting_Godot/prefab/role/Role0001.tscn b/DungeonShooting_Godot/prefab/role/Role0001.tscn
index 196f400..b8e436d 100644
--- a/DungeonShooting_Godot/prefab/role/Role0001.tscn
+++ b/DungeonShooting_Godot/prefab/role/Role0001.tscn
@@ -44,6 +44,3 @@
[node name="AnimatedSprite" parent="." index="2"]
material = SubResource("ShaderMaterial_8hgu2")
sprite_frames = ExtResource("4_galcc")
-
-[node name="MountPoint" parent="." index="6"]
-position = Vector2(2, -8)
diff --git a/DungeonShooting_Godot/prefab/role/RoleTemplate.tscn b/DungeonShooting_Godot/prefab/role/RoleTemplate.tscn
index d55de02..2217fee 100644
--- a/DungeonShooting_Godot/prefab/role/RoleTemplate.tscn
+++ b/DungeonShooting_Godot/prefab/role/RoleTemplate.tscn
@@ -69,5 +69,5 @@
shape = SubResource("RectangleShape2D_n68nu")
[node name="MountPoint" type="Marker2D" parent="."]
-position = Vector2(1, -6)
+position = Vector2(2, -8)
script = ExtResource("2_5ddpw")
diff --git a/DungeonShooting_Godot/src/game/activity/role/Role.cs b/DungeonShooting_Godot/src/game/activity/role/Role.cs
index 034de62..c2ce92b 100644
--- a/DungeonShooting_Godot/src/game/activity/role/Role.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/Role.cs
@@ -81,6 +81,11 @@
///
[Export, ExportFillNode]
public CollisionShape2D InteractiveCollision { get; set; }
+
+ ///
+ /// 武器挂载点是否始终指向目标
+ ///
+ public bool MountLookTarget { get; set; } = true;
///
/// 脸的朝向
@@ -226,6 +231,11 @@
/// 是否可以翻滚
///
public bool CanRoll => _rollCoolingTimer <= 0;
+
+ ///
+ /// 是否处于近战攻击中
+ ///
+ public bool IsMeleeAttack { get; private set; }
//翻滚冷却计时器
private float _rollCoolingTimer = 0;
@@ -409,8 +419,12 @@
{
Face = FaceDirection.Left;
}
- //枪口跟随目标
- MountPoint.SetLookAt(pos);
+
+ if (MountLookTarget)
+ {
+ //枪口跟随目标
+ MountPoint.SetLookAt(pos);
+ }
}
//检查可互动的物体
@@ -582,7 +596,6 @@
/// 使角色看向指定的坐标,
/// 注意, 调用该函数会清空 LookTarget, 因为拥有 LookTarget 时也会每帧更新玩家视野位置
///
- ///
public void LookTargetPosition(Vector2 pos)
{
LookTarget = null;
@@ -596,8 +609,12 @@
{
Face = FaceDirection.Left;
}
- //枪口跟随目标
- MountPoint.SetLookAt(pos);
+
+ if (MountLookTarget)
+ {
+ //枪口跟随目标
+ MountPoint.SetLookAt(pos);
+ }
}
///
@@ -866,13 +883,35 @@
///
public virtual void Attack()
{
- if (WeaponPack.ActiveItem != null)
+ if (!IsMeleeAttack && WeaponPack.ActiveItem != null)
{
WeaponPack.ActiveItem.Trigger(this);
}
}
///
+ /// 触发近战攻击
+ ///
+ public virtual void MeleeAttack()
+ {
+ if (IsMeleeAttack)
+ {
+ return;
+ }
+
+ if (WeaponPack.ActiveItem != null)
+ {
+ IsMeleeAttack = true;
+ WeaponPack.ActiveItem.TriggerMeleeAttack(this);
+ //播放近战动画
+ PlayAnimation_MeleeAttack(() =>
+ {
+ IsMeleeAttack = false;
+ });
+ }
+ }
+
+ ///
/// 触发使用道具
///
public virtual void UseActiveProp()
diff --git a/DungeonShooting_Godot/src/game/activity/role/Role_Animation.cs b/DungeonShooting_Godot/src/game/activity/role/Role_Animation.cs
new file mode 100644
index 0000000..fc3e853
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/Role_Animation.cs
@@ -0,0 +1,53 @@
+
+using System;
+using Godot;
+using Vector2 = Godot.Vector2;
+
+public partial class Role
+{
+ ///
+ /// 播放近战攻击动画
+ ///
+ public virtual void PlayAnimation_MeleeAttack(Action finish)
+ {
+ MountLookTarget = false;
+ var r = MountPoint.RotationDegrees;
+ var p1 = MountPoint.Position;
+ var p2 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r - 60));
+ var p3 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r + 60));
+
+ var tween = CreateTween();
+ tween.SetParallel();
+
+ tween.TweenProperty(MountPoint, "rotation_degrees", r - 60, 0.15);
+ tween.TweenProperty(MountPoint, "position", p2, 0.15);
+ tween.Chain();
+
+ tween.TweenCallback(Callable.From(() =>
+ {
+ MountPoint.RotationDegrees = r + 60;
+ MountPoint.Position = p3;
+ //创建屏幕抖动
+ if (Face == FaceDirection.Right)
+ {
+ GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 90)) * 5);
+ }
+ else
+ {
+ GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(270 - r)) * 5);
+ }
+ }));
+ tween.Chain();
+
+ tween.TweenProperty(MountPoint, "rotation_degrees", r, 0.3);
+ tween.TweenProperty(MountPoint, "position", p1, 0.3);
+ tween.Chain();
+
+ tween.TweenCallback(Callable.From(() =>
+ {
+ MountLookTarget = true;
+ finish();
+ }));
+ tween.Play();
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs
index 89e806c..0227a42 100644
--- a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs
@@ -84,8 +84,12 @@
{
Face = FaceDirection.Left;
}
- //枪口跟随鼠标
- MountPoint.SetLookAt(mousePos);
+
+ if (MountLookTarget)
+ {
+ //枪口跟随鼠标
+ MountPoint.SetLookAt(mousePos);
+ }
}
if (InputManager.ExchangeWeapon) //切换武器
@@ -121,7 +125,14 @@
Reload();
}
- if (InputManager.Fire) //开火
+ if (InputManager.MeleeAttack) //近战攻击
+ {
+ if (StateController.CurrState != PlayerStateEnum.Roll) //不能是翻滚状态
+ {
+ MeleeAttack();
+ }
+ }
+ else if (InputManager.Fire) //正常开火
{
if (StateController.CurrState != PlayerStateEnum.Roll) //不能是翻滚状态
{
diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
index f8d877d..5ec5fd3 100644
--- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
+++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
@@ -981,6 +981,14 @@
}
///
+ /// 触发武器的近战攻击
+ ///
+ public void TriggerMeleeAttack(Role trigger)
+ {
+
+ }
+
+ ///
/// 获取武器攻击的目标层级
///
///