diff --git "a/DungeonShooting_Document/\351\241\271\347\233\256\345\270\256\345\212\251\346\226\207\346\241\243.md" "b/DungeonShooting_Document/\351\241\271\347\233\256\345\270\256\345\212\251\346\226\207\346\241\243.md" index 133b51a..b6f7b65 100644 --- "a/DungeonShooting_Document/\351\241\271\347\233\256\345\270\256\345\212\251\346\226\207\346\241\243.md" +++ "b/DungeonShooting_Document/\351\241\271\347\233\256\345\270\256\345\212\251\346\226\207\346\241\243.md" @@ -140,4 +140,123 @@ ### 3.2.5.`ActivityObject`常用功能 +#### 自定义组件 +这个功能类似于`Unity`的`MonoBehaviour`, 组件必须继承`Component`类, 组件的作用是拆分功能代码, 开发者可以将相同功能的代码放入同一个组件中, 与`Godot`的`Node`不同的是, 挂载到`ActivityObject`上的组件并不会生成一个`Node`节点, 它相比于`Node`更加轻量 +自定义组件代码: +```csharp +public class MyComponent : Component +{ + +} +``` +调用`ActivityObject.AddComponent()`添加组件: +```csharp +var component = activityInstance.AddComponent(); +``` +注意: 一个`ActivityObject`上不允许挂载多个相同的组件 + +#### 运动控制 +`ActivityObject`的移动由自身的`MoveController`组件控制, 非特殊情况下不要直接修改`ActivityObject`的位置, 而是使用`MoveController.AddConstantForce()`函数来添加外力 +```csharp +//添加一个向右的外力, 速度为100 +var force = activityInstance.MoveController.AddConstantForce("ForceName"); //外力必须起名称, 而且在运动控制器中必须唯一 +force.Velocity = new Vector2(0, 100); +//以下为精简写法 +var force = activityInstance.MoveController.AddConstantForce(new Vector2(0, 100), 0); //创建匿名外力, 但是与上面不同的是当速率变为 0 时自动销毁 +``` +物体的运动方向就是所有外力总和的方向, 通过`MoveController.Velocity`可以获取当前运动速度 + +#### 垂直方向运动 +当游戏中需要制作飞行物体或者模拟投抛运动时, 就需要控制物体纵轴所处高度, `ActivityObject`中提供了一系列控制纵轴方向运动的属性和函数, 以下列举几个关键属性和函数: +```csharp +/// +/// 当前物体的海拔高度, 如果大于0, 则会做自由落体运动, 也就是执行投抛代码 +/// +public float Altitude { get; set; } = 0; + +/// +/// 物体纵轴移动速度, 如果设置大于0, 就可以营造向上投抛物体的效果, 该值会随着重力加速度衰减 +/// +public float VerticalSpeed { get; set; } = 0; + +/// +/// 物体下坠回弹的强度 +/// +public float BounceStrength { get; set; } = 0.5f; + +/// +/// 物体下坠回弹后的运动速度衰减量 +/// +public float BounceSpeed { get; set; } = 0.75f; + +/// +/// 是否启用垂直方向上的运动模拟, 默认开启, 如果禁用, 那么下落和投抛效果, 同样 Throw() 函数也将失效 +/// +public bool EnableVerticalMotion { get; set; } = true; +``` +垂直运动也提供了一些可供重新的虚函数: +```csharp +/// +/// 开始投抛该物体时调用 +/// +protected virtual void OnThrowStart() +{ +} + +/// +/// 投抛该物体达到最高点时调用 +/// +protected virtual void OnThrowMaxHeight(float height) +{ +} + +/// +/// 投抛状态下第一次接触地面时调用, 之后的回弹落地将不会调用该函数 +/// +protected virtual void OnFirstFallToGround() +{ +} + +/// +/// 投抛状态下每次接触地面时调用 +/// +protected virtual void OnFallToGround() +{ +} + +/// +/// 投抛结束时调用 +/// +protected virtual void OnThrowOver() +{ +} +``` +如果需要模拟飞行效果则需要设置`Altitude`值大于0, 并且将`EnableVerticalMotion`设置为`false` +如果需要自由落体, 则直接设置`Altitude`值大于0 +如果需要上抛运动, 则直接设置`VerticalSpeed`值大于0 +如果值`BounceStrength`和`BounceSpeed`设置成1, 则投抛的物体在地上会一直朝一个方向弹跳 +如果需要投抛物体不需要每个关键值都设置一遍信息, 只需要调用`ActivityObject.Throw()`函数即可: +```csharp +/// +/// 将该节点投抛出去 +/// +/// 初始高度 +/// 旋转速度 +/// 移动速率 +/// 纵轴速度 +public void Throw(float altitude, float verticalSpeed, Vector2 velocity, float rotate); +``` +调用示例, 模拟弹壳投抛落在地上弹跳的过程 +```csharp +var startPos = activityInstance.Master.GlobalPosition; +var startHeight = 6; +var direction = GlobalRotationDegrees + Utils.RandomRangeInt(-30, 30) + 180; +var verticalSpeed = Utils.RandomRangeInt(60, 120); +var velocity = new Vector2(Utils.RandomRangeInt(20, 60), 0).Rotated(direction * Mathf.Pi / 180); +var rotate = Utils.RandomRangeInt(-720, 720); +var shell = ActivityObject.Create(ActivityIdPrefix.Shell + "0001"); +shell.Throw(startPos, startHeight, verticalSpeed, velocity, rotate); +``` + +#### 协程 diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index 7b63117..6434c9d 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -41,12 +41,7 @@ /// 是否调用过 Destroy() 函数 /// public bool IsDestroyed { get; private set; } - - /// - /// 是否正在投抛过程中 - /// - public bool IsThrowing => _fallData != null && !_isFallOver; - + /// /// 阴影偏移 /// @@ -83,6 +78,11 @@ } /// + /// 是否正在投抛过程中 + /// + public bool IsThrowing => _fallData != null && !_isFallOver; + + /// /// 当前物体的海拔高度, 如果大于0, 则会做自由落体运动, 也就是执行投抛代码 /// public float Altitude diff --git a/DungeonShooting_Godot/src/framework/activity/ExternalForce.cs b/DungeonShooting_Godot/src/framework/activity/ExternalForce.cs index e6b1d2f..53fe1c9 100644 --- a/DungeonShooting_Godot/src/framework/activity/ExternalForce.cs +++ b/DungeonShooting_Godot/src/framework/activity/ExternalForce.cs @@ -19,7 +19,7 @@ /// /// 阻力大小, 也就是速度每秒衰减的量 /// - public float Resistance { get; set; } = 5; + public float Resistance { get; set; } = 0; /// /// 当速度到达 0 后是否自动销毁, 默认 true