Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / activity / ActivityObject.cs
@小李xl 小李xl on 15 Feb 2024 53 KB 地牢编辑器2格墙壁支持
  1.  
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using Config;
  6. using Godot;
  7.  
  8. /// <summary>
  9. /// 房间内活动物体基类, 所有物体都必须继承该类,<br/>
  10. /// 该类提供基础物体运动模拟, 互动接口, 自定义组件, 协程等功能<br/>
  11. /// ActivityObject 子类实例化请不要直接使用 new, 而用该在类上标上 [Tool], 并在 ActivityObject.xlsx 配置文件中注册物体, 导出配置表后使用 ActivityObject.Create(id) 来创建实例.<br/>
  12. /// </summary>
  13. [Tool]
  14. public partial class ActivityObject : CharacterBody2D, IDestroy, ICoroutine
  15. {
  16. /// <summary>
  17. /// 是否是调试模式
  18. /// </summary>
  19. public static bool IsDebug { get; set; }
  20.  
  21. /// <summary>
  22. /// 实例唯一 Id
  23. /// </summary>
  24. public long Id { get; set; }
  25. /// <summary>
  26. /// 当前物体对应的配置数据, 如果不是通过 ActivityObject.Create() 函数创建出来的对象那么 ItemConfig 为 null
  27. /// </summary>
  28. public ExcelConfig.ActivityBase ActivityBase { get; private set; }
  29.  
  30. /// <summary>
  31. /// 是否是静态物体, 如果为true, 则会禁用移动处理
  32. /// </summary>
  33. public bool IsStatic
  34. {
  35. get => MoveController != null ? !MoveController.Enable : true;
  36. set
  37. {
  38. if (MoveController != null)
  39. {
  40. MoveController.Enable = !value;
  41. }
  42. }
  43. }
  44.  
  45. /// <summary>
  46. /// 是否显示阴影
  47. /// </summary>
  48. public bool IsShowShadow { get; private set; }
  49. /// <summary>
  50. /// 当前物体显示的阴影图像, 节点名称必须叫 "ShadowSprite", 类型为 Sprite2D
  51. /// </summary>
  52. [Export, ExportFillNode]
  53. public Sprite2D ShadowSprite { get; set; }
  54. /// <summary>
  55. /// 当前物体显示的精灵图像, 节点名称必须叫 "AnimatedSprite2D", 类型为 AnimatedSprite2D
  56. /// </summary>
  57. [Export, ExportFillNode]
  58. public AnimatedSprite2D AnimatedSprite { get; set; }
  59.  
  60. /// <summary>
  61. /// 当前物体碰撞器节点, 节点名称必须叫 "Collision", 类型为 CollisionShape2D
  62. /// </summary>
  63. [Export, ExportFillNode]
  64. public CollisionShape2D Collision { get; set; }
  65.  
  66. /// <summary>
  67. /// 是否调用过 Destroy() 函数
  68. /// </summary>
  69. public bool IsDestroyed { get; private set; }
  70. /// <summary>
  71. /// 阴影偏移
  72. /// </summary>
  73. [Export]
  74. public Vector2 ShadowOffset { get; set; } = new Vector2(0, 2);
  75. /// <summary>
  76. /// 移动控制器
  77. /// </summary>
  78. public MoveController MoveController { get; private set; }
  79.  
  80. /// <summary>
  81. /// 物体移动基础速率
  82. /// </summary>
  83. public Vector2 BasisVelocity
  84. {
  85. get
  86. {
  87. if (MoveController != null)
  88. {
  89. return MoveController.BasisVelocity;
  90. }
  91.  
  92. return Vector2.Zero;
  93. }
  94. set
  95. {
  96. if (MoveController != null)
  97. {
  98. MoveController.BasisVelocity = value;
  99. }
  100. }
  101. }
  102.  
  103. /// <summary>
  104. /// 当前物体归属的区域, 如果为 null 代表不属于任何一个区域
  105. /// </summary>
  106. public AffiliationArea AffiliationArea
  107. {
  108. get => _affiliationArea;
  109. set
  110. {
  111. if (value != _affiliationArea)
  112. {
  113. var prev = _affiliationArea;
  114. _affiliationArea = value;
  115. if (!IsDestroyed)
  116. {
  117. OnAffiliationChange(prev);
  118. }
  119. }
  120. }
  121. }
  122.  
  123. /// <summary>
  124. /// 是否正在投抛过程中
  125. /// </summary>
  126. public bool IsThrowing => VerticalSpeed != 0 && !_isFallOver;
  127.  
  128. /// <summary>
  129. /// 当前物体的海拔高度, 如果大于0, 则会做自由落体运动, 也就是执行投抛逻辑
  130. /// </summary>
  131. public float Altitude
  132. {
  133. get => _altitude;
  134. set
  135. {
  136. _altitude = value;
  137. _hasResilienceVerticalSpeed = false;
  138. }
  139. }
  140.  
  141. private float _altitude = 0;
  142.  
  143. /// <summary>
  144. /// 物体纵轴移动速度, 如果设置大于0, 就可以营造向上投抛物体的效果, 该值会随着重力加速度衰减
  145. /// </summary>
  146. public float VerticalSpeed
  147. {
  148. get => _verticalSpeed;
  149. set
  150. {
  151. _verticalSpeed = value;
  152. _hasResilienceVerticalSpeed = false;
  153. }
  154. }
  155.  
  156. private float _verticalSpeed;
  157.  
  158. /// <summary>
  159. /// 是否启用垂直方向上的运动模拟, 默认开启, 如果禁用, 那么下落和投抛效果, 同样 Throw() 函数也将失效
  160. /// </summary>
  161. public bool EnableVerticalMotion { get; set; } = true;
  162. /// <summary>
  163. /// 是否启用物体更新行为, 默认 true, 如果禁用, 则会停止当前物体的 Process(), PhysicsProcess() 调用, 并且禁用 Collision 节点, 禁用后所有组件也同样被禁用行为
  164. /// </summary>
  165. public bool EnableBehavior
  166. {
  167. get => _enableBehavior;
  168. set
  169. {
  170. if (value != _enableBehavior)
  171. {
  172. _enableBehavior = value;
  173. SetProcess(value);
  174. SetPhysicsProcess(value);
  175. if (value)
  176. {
  177. Collision.Disabled = _enableBehaviorCollisionDisabledFlag;
  178. }
  179. else
  180. {
  181. _enableBehaviorCollisionDisabledFlag = Collision.Disabled;
  182. Collision.Disabled = true;
  183. }
  184. }
  185. }
  186. }
  187.  
  188. /// <summary>
  189. /// 是否启用自定义行为, 默认 true, 如果禁用, 则会停止调用子类重写的 Process(), PhysicsProcess() 函数, 并且当前物体除 MoveController 以外的组件 Process(), PhysicsProcess() 也会停止调用
  190. /// </summary>
  191. public bool EnableCustomBehavior { get; set; } = true;
  192. /// <summary>
  193. /// 物体材质数据
  194. /// </summary>
  195. public ExcelConfig.ActivityMaterial ActivityMaterial { get; private set; }
  196. /// <summary>
  197. /// 所在的 World 对象
  198. /// </summary>
  199. public World World { get; private set; }
  200.  
  201. /// <summary>
  202. /// 是否开启描边
  203. /// </summary>
  204. public bool ShowOutline
  205. {
  206. get => _blendShaderMaterial == null ? false : _blendShaderMaterial.GetShaderParameter(ShaderParamNames.ShowOutline).AsBool();
  207. set
  208. {
  209. _blendShaderMaterial?.SetShaderParameter(ShaderParamNames.ShowOutline, value);
  210. _shadowBlendShaderMaterial?.SetShaderParameter(ShaderParamNames.ShowOutline, value);
  211. }
  212. }
  213.  
  214. /// <summary>
  215. /// 描边颜色
  216. /// </summary>
  217. public Color OutlineColor
  218. {
  219. get => _blendShaderMaterial == null ? Colors.Black : _blendShaderMaterial.GetShaderParameter(ShaderParamNames.OutlineColor).AsColor();
  220. set => _blendShaderMaterial?.SetShaderParameter(ShaderParamNames.OutlineColor, value);
  221. }
  222.  
  223. /// <summary>
  224. /// 灰度
  225. /// </summary>
  226. public float Grey
  227. {
  228. get => _blendShaderMaterial == null ? 0 : _blendShaderMaterial.GetShaderParameter(ShaderParamNames.Grey).AsSingle();
  229. set => _blendShaderMaterial?.SetShaderParameter(ShaderParamNames.Grey, value);
  230. }
  231. /// <summary>
  232. /// 是否是自定义阴影纹理
  233. /// </summary>
  234. public bool IsCustomShadowSprite { get; private set; }
  235.  
  236. /// <summary>
  237. /// 记录绘制液体的笔刷上一次绘制的位置<br/>
  238. /// 每次调用 DrawLiquid() 后都会记录这一次绘制的位置, 记录这个位置用作执行补间操作, 但是一旦停止绘制了, 需要手动清理记录的位置, 也就是将 BrushPrevPosition 置为 null
  239. /// </summary>
  240. public Vector2I? BrushPrevPosition { get; set; }
  241. /// <summary>
  242. /// 默认所在层级
  243. /// </summary>
  244. public RoomLayerEnum DefaultLayer { get; set; }
  245.  
  246. /// <summary>
  247. /// 投抛状态下的碰撞器层级
  248. /// </summary>
  249. public uint ThrowCollisionMask { get; set; } = PhysicsLayer.Wall;
  250. // --------------------------------------------------------------------------------
  251.  
  252. //是否正在调用组件 Update 函数
  253. private bool _updatingComp = false;
  254. //组件集合
  255. private readonly List<KeyValuePair<Type, Component>> _components = new List<KeyValuePair<Type, Component>>();
  256. //修改的组件集合, value 为 true 表示添加组件, false 表示移除组件
  257. private readonly List<KeyValuePair<Component, bool>> _changeComponents = new List<KeyValuePair<Component, bool>>();
  258. //上一帧动画名称
  259. private StringName _prevAnimation;
  260. //上一帧动画
  261. private int _prevAnimationFrame;
  262.  
  263. //播放 Hit 动画
  264. private bool _playHit;
  265. private float _playHitSchedule;
  266.  
  267. //混色shader材质
  268. private ShaderMaterial _blendShaderMaterial;
  269. private ShaderMaterial _shadowBlendShaderMaterial;
  270. //存储投抛该物体时所产生的数据
  271. private readonly ActivityFallData _fallData = new ActivityFallData();
  272. //标记字典
  273. private Dictionary<string, object> _signMap;
  274. //开启的协程
  275. private List<CoroutineData> _coroutineList;
  276.  
  277. //物体所在区域
  278. private AffiliationArea _affiliationArea;
  279.  
  280. //是否是第一次下坠
  281. private bool _firstFall = true;
  282. //下坠是否已经结束
  283. private bool _isFallOver = true;
  284.  
  285. //投抛移动速率
  286. private ExternalForce _throwForce;
  287. //落到地上回弹的速度
  288. private float _resilienceVerticalSpeed = 0;
  289. private bool _hasResilienceVerticalSpeed = false;
  290.  
  291. //是否启用物体行为
  292. private bool _enableBehavior = true;
  293. private bool _enableBehaviorCollisionDisabledFlag;
  294.  
  295. private bool _processingBecomesStaticImage = false;
  296.  
  297. //击退外力
  298. private ExternalForce _repelForce;
  299.  
  300. //绑定销毁物体集合
  301. private HashSet<IDestroy> _destroySet;
  302.  
  303. //挂载的物体集合
  304. private HashSet<IMountItem> _mountObjects;
  305.  
  306. // --------------------------------------------------------------------------------
  307. //实例索引
  308. private static long _instanceIndex = 0;
  309. //冻结显示的Sprite
  310. private FreezeSprite _freezeSprite;
  311.  
  312. //初始化节点
  313. private void _InitNode(ExcelConfig.ActivityBase config, World world)
  314. {
  315. #if TOOLS
  316. if (!Engine.IsEditorHint())
  317. {
  318. if (GetType().GetCustomAttributes(typeof(ToolAttribute), false).Length == 0)
  319. {
  320. throw new Exception($"ActivityObject子类'{GetType().FullName}'没有加[Tool]标记!");
  321. }
  322. }
  323. #endif
  324. if (config.Material == null)
  325. {
  326. ActivityMaterial = ExcelConfig.ActivityMaterial_List[0];
  327. }
  328. else
  329. {
  330. ActivityMaterial = config.Material;
  331. }
  332.  
  333. //GravityScale 为 0 时关闭重力
  334. if (ActivityMaterial.GravityScale == 0)
  335. {
  336. EnableVerticalMotion = false;
  337. }
  338. World = world;
  339. ActivityBase = config;
  340. #if TOOLS
  341. Name = GetType().Name + (_instanceIndex++);
  342. #endif
  343. Id = _instanceIndex;
  344. _blendShaderMaterial = AnimatedSprite.Material as ShaderMaterial;
  345. IsCustomShadowSprite = ShadowSprite.Texture != null;
  346. if (!IsCustomShadowSprite) //没有自定义阴影纹理
  347. {
  348. _shadowBlendShaderMaterial = ShadowSprite.Material as ShaderMaterial;
  349. if (_shadowBlendShaderMaterial != null && _blendShaderMaterial != null)
  350. {
  351. var value = _blendShaderMaterial.GetShaderParameter(ShaderParamNames.ShowOutline);
  352. _shadowBlendShaderMaterial.SetShaderParameter(ShaderParamNames.ShowOutline, value);
  353. }
  354. ShadowSprite.Visible = false;
  355. }
  356.  
  357. MotionMode = MotionModeEnum.Floating;
  358. MoveController = AddComponent<MoveController>();
  359. IsStatic = config.IsStatic;
  360. OnInit();
  361. }
  362.  
  363. /// <summary>
  364. /// 子类重写的 _Ready() 可能会比 _InitNode() 函数调用晚, 所以禁止子类重写, 如需要 _Ready() 类似的功能需重写 OnInit()
  365. /// </summary>
  366. public sealed override void _Ready()
  367. {
  368.  
  369. }
  370. /// <summary>
  371. /// 子类需要重写 _EnterTree() 函数, 请重写 EnterTree()
  372. /// </summary>
  373. public sealed override void _EnterTree()
  374. {
  375. #if TOOLS
  376. // 在工具模式下创建的 template 节点自动创建对应的必要子节点
  377. if (Engine.IsEditorHint())
  378. {
  379. _InitNodeInEditor();
  380. return;
  381. }
  382. #endif
  383. EnterTree();
  384. }
  385. /// <summary>
  386. /// 子类需要重写 _ExitTree() 函数, 请重写 ExitTree()
  387. /// </summary>
  388. public sealed override void _ExitTree()
  389. {
  390. #if TOOLS
  391. // 在工具模式下创建的 template 节点自动创建对应的必要子节点
  392. if (Engine.IsEditorHint())
  393. {
  394. return;
  395. }
  396. #endif
  397. ExitTree();
  398. }
  399.  
  400. /// <summary>
  401. /// 显示并更新阴影
  402. /// </summary>
  403. public void ShowShadowSprite()
  404. {
  405. if (!IsCustomShadowSprite)
  406. {
  407. var anim = AnimatedSprite.Animation;
  408. var frame = AnimatedSprite.Frame;
  409. if (_prevAnimation != anim || _prevAnimationFrame != frame)
  410. {
  411. var frames = AnimatedSprite.SpriteFrames;
  412. if (frames != null && frames.HasAnimation(anim))
  413. {
  414. //切换阴影动画
  415. ShadowSprite.Texture = frames.GetFrameTexture(anim, frame);
  416. }
  417. }
  418.  
  419. _prevAnimation = anim;
  420. _prevAnimationFrame = frame;
  421. }
  422.  
  423. IsShowShadow = true;
  424. CalcShadowTransform();
  425. ShadowSprite.Visible = true;
  426. }
  427.  
  428. /// <summary>
  429. /// 隐藏阴影
  430. /// </summary>
  431. public void HideShadowSprite()
  432. {
  433. ShadowSprite.Visible = false;
  434. IsShowShadow = false;
  435. }
  436.  
  437. /// <summary>
  438. /// 设置默认序列帧动画的第一帧
  439. /// </summary>
  440. public void SetDefaultTexture(Texture2D texture)
  441. {
  442. if (AnimatedSprite.SpriteFrames == null)
  443. {
  444. SpriteFrames spriteFrames = new SpriteFrames();
  445. AnimatedSprite.SpriteFrames = spriteFrames;
  446. spriteFrames.AddFrame("default", texture);
  447. }
  448. else
  449. {
  450. SpriteFrames spriteFrames = AnimatedSprite.SpriteFrames;
  451. spriteFrames.SetFrame("default", 0, texture);
  452. }
  453. AnimatedSprite.Play("default");
  454. }
  455.  
  456. /// <summary>
  457. /// 获取默认序列帧动画的第一帧
  458. /// </summary>
  459. public Texture2D GetDefaultTexture()
  460. {
  461. return AnimatedSprite.SpriteFrames.GetFrameTexture("default", 0);
  462. }
  463. /// <summary>
  464. /// 获取当前序列帧动画的 Texture2D
  465. /// </summary>
  466. public Texture2D GetCurrentTexture()
  467. {
  468. var spriteFrames = AnimatedSprite.SpriteFrames;
  469. if (spriteFrames == null)
  470. {
  471. return null;
  472. }
  473. return spriteFrames.GetFrameTexture(AnimatedSprite.Animation, AnimatedSprite.Frame);
  474. }
  475.  
  476. /// <summary>
  477. /// 物体初始化时调用
  478. /// </summary>
  479. public virtual void OnInit()
  480. {
  481. }
  482. /// <summary>
  483. /// 进入场景树时调用
  484. /// </summary>
  485. public virtual void EnterTree()
  486. {
  487. }
  488.  
  489. /// <summary>
  490. /// 离开场景树时调用
  491. /// </summary>
  492. public virtual void ExitTree()
  493. {
  494. }
  495. /// <summary>
  496. /// 返回是否能与其他ActivityObject互动
  497. /// </summary>
  498. /// <param name="master">触发者</param>
  499. public virtual CheckInteractiveResult CheckInteractive(ActivityObject master)
  500. {
  501. return new CheckInteractiveResult(this);
  502. }
  503.  
  504. /// <summary>
  505. /// 与其它ActivityObject互动时调用, 如果要检测是否能互动请 CheckInteractive() 函数, 如果直接调用该函数那么属于强制互动行为, 例如子弹碰到物体
  506. /// </summary>
  507. /// <param name="master">触发者</param>
  508. public virtual void Interactive(ActivityObject master)
  509. {
  510. }
  511.  
  512. /// <summary>
  513. /// 开始投抛该物体时调用
  514. /// </summary>
  515. protected virtual void OnThrowStart()
  516. {
  517. }
  518. /// <summary>
  519. /// 投抛该物体达到最高点时调用
  520. /// </summary>
  521. protected virtual void OnThrowMaxHeight(float height)
  522. {
  523. }
  524.  
  525. /// <summary>
  526. /// 投抛状态下第一次接触地面时调用, 之后的回弹落地将不会调用该函数
  527. /// </summary>
  528. protected virtual void OnFirstFallToGround()
  529. {
  530. }
  531.  
  532. /// <summary>
  533. /// 投抛状态下每次接触地面时调用
  534. /// </summary>
  535. protected virtual void OnFallToGround()
  536. {
  537. }
  538.  
  539. /// <summary>
  540. /// 投抛结束时调用
  541. /// </summary>
  542. protected virtual void OnThrowOver()
  543. {
  544. }
  545.  
  546. /// <summary>
  547. /// 当前物体销毁时调用, 销毁物体请调用 Destroy() 函数
  548. /// </summary>
  549. protected virtual void OnDestroy()
  550. {
  551. }
  552.  
  553. /// <summary>
  554. /// 每帧调用一次, 物体的 Process() 会在组件的 Process() 之前调用
  555. /// </summary>
  556. protected virtual void Process(float delta)
  557. {
  558. }
  559. /// <summary>
  560. /// 每物理帧调用一次, 物体的 PhysicsProcess() 会在组件的 PhysicsProcess() 之前调用
  561. /// </summary>
  562. protected virtual void PhysicsProcess(float delta)
  563. {
  564. }
  565. /// <summary>
  566. /// 如果开启 debug, 则每帧调用该函数, 可用于绘制文字线段等
  567. /// </summary>
  568. protected virtual void DebugDraw()
  569. {
  570. }
  571.  
  572. /// <summary>
  573. /// 归属区域发生改变
  574. /// </summary>
  575. /// <param name="prevArea">上一个区域, 注意可能为空</param>
  576. protected virtual void OnAffiliationChange(AffiliationArea prevArea)
  577. {
  578. }
  579.  
  580. /// <summary>
  581. /// 移动并碰撞到物体时调用该函数, 参数为碰撞数据, 该函数由 MoveController 调用
  582. /// </summary>
  583. public virtual void OnMoveCollision(KinematicCollision2D collision)
  584. {
  585. }
  586.  
  587. /// <summary>
  588. /// 撞到墙壁反弹时调用该函数, 参数为反弹的角度, 弧度制, 该函数由 MoveController 调用
  589. /// </summary>
  590. public virtual void OnBounce(float rotation)
  591. {
  592. }
  593.  
  594. /// <summary>
  595. /// 返回当物体 CollisionLayer 是否能与 mask 层碰撞
  596. /// </summary>
  597. public bool CollisionWithMask(uint mask)
  598. {
  599. return (CollisionLayer & mask) != 0;
  600. }
  601. /// <summary>
  602. /// 拾起一个 node 节点, 也就是将其从场景树中移除
  603. /// </summary>
  604. public void Pickup()
  605. {
  606. var parent = GetParent();
  607. if (parent != null)
  608. {
  609. if (IsThrowing)
  610. {
  611. StopThrow();
  612. }
  613.  
  614. parent.RemoveChild(this);
  615. }
  616. }
  617.  
  618. /// <summary>
  619. /// 将一个节点扔到地上
  620. /// <param name="layer">放入的层</param>
  621. /// <param name="showShadow">是否显示阴影</param>
  622. /// </summary>
  623. public virtual void PutDown(RoomLayerEnum layer, bool showShadow = true)
  624. {
  625. DefaultLayer = layer;
  626. var parent = GetParent();
  627. var root = GameApplication.Instance.World.GetRoomLayer(layer);
  628. if (parent != root)
  629. {
  630. if (parent != null)
  631. {
  632. Reparent(root);
  633. }
  634. else
  635. {
  636. root.AddChild(this);
  637. }
  638. }
  639.  
  640. if (showShadow)
  641. {
  642. if (IsInsideTree())
  643. {
  644. ShowShadowSprite();
  645. }
  646. else
  647. {
  648. //注意需要延时调用
  649. CallDeferred(nameof(ShowShadowSprite));
  650. CalcShadowTransform();
  651. }
  652. }
  653. else
  654. {
  655. ShadowSprite.Visible = false;
  656. }
  657. }
  658.  
  659. /// <summary>
  660. /// 将一个节点扔到地上
  661. /// </summary>
  662. /// <param name="position">放置的位置</param>
  663. /// <param name="layer">放入的层</param>
  664. /// <param name="showShadow">是否显示阴影</param>
  665. public void PutDown(Vector2 position, RoomLayerEnum layer, bool showShadow = true)
  666. {
  667. PutDown(layer);
  668. Position = position;
  669. }
  670.  
  671. /// <summary>
  672. /// 将该节点投抛出去
  673. /// </summary>
  674. /// <param name="altitude">初始高度</param>
  675. /// <param name="verticalSpeed">纵轴速度</param>
  676. /// <param name="velocity">移动速率</param>
  677. /// <param name="rotateSpeed">旋转速度</param>
  678. public void Throw(float altitude, float verticalSpeed, Vector2 velocity, float rotateSpeed)
  679. {
  680. Altitude = altitude;
  681. //Position = Position + new Vector2(0, altitude);
  682. VerticalSpeed = verticalSpeed;
  683. //ThrowRotationDegreesSpeed = rotateSpeed;
  684. if (_throwForce != null)
  685. {
  686. MoveController.RemoveForce(_throwForce);
  687. }
  688.  
  689. _throwForce = new ExternalForce(ForceNames.Throw);
  690. _throwForce.Velocity = velocity;
  691. _throwForce.RotationSpeed = Mathf.DegToRad(rotateSpeed);
  692. MoveController.AddForce(_throwForce);
  693.  
  694. InitThrowData();
  695. }
  696.  
  697. /// <summary>
  698. /// 将该节点投抛出去
  699. /// </summary>
  700. /// <param name="position">初始位置</param>
  701. /// <param name="altitude">初始高度</param>
  702. /// <param name="verticalSpeed">纵轴速度</param>
  703. /// <param name="velocity">移动速率</param>
  704. /// <param name="rotateSpeed">旋转速度</param>
  705. public void Throw(Vector2 position, float altitude, float verticalSpeed, Vector2 velocity, float rotateSpeed)
  706. {
  707. GlobalPosition = position;
  708. Throw(altitude, verticalSpeed, velocity, rotateSpeed);
  709. }
  710.  
  711.  
  712. /// <summary>
  713. /// 强制停止投抛运动
  714. /// </summary>
  715. public void StopThrow()
  716. {
  717. _isFallOver = true;
  718. RestoreCollision();
  719. }
  720.  
  721. /// <summary>
  722. /// 往当前物体上挂载一个组件
  723. /// </summary>
  724. public T AddComponent<T>() where T : Component, new()
  725. {
  726. var component = new T();
  727. if (_updatingComp)
  728. {
  729. _changeComponents.Add(new KeyValuePair<Component, bool>(component, true));
  730. }
  731. else
  732. {
  733. _components.Add(new KeyValuePair<Type, Component>(typeof(T), component));
  734. }
  735.  
  736. component.Master = this;
  737. component.Ready();
  738. component.OnEnable();
  739. return component;
  740. }
  741.  
  742. /// <summary>
  743. /// 往当前物体上挂载一个组件
  744. /// </summary>
  745. public Component AddComponent(Type type)
  746. {
  747. var component = (Component)Activator.CreateInstance(type);
  748. if (_updatingComp)
  749. {
  750. _changeComponents.Add(new KeyValuePair<Component, bool>(component, true));
  751. }
  752. else
  753. {
  754. _components.Add(new KeyValuePair<Type, Component>(type, component));
  755. }
  756. component.Master = this;
  757. component.Ready();
  758. component.OnEnable();
  759. return component;
  760. }
  761.  
  762. /// <summary>
  763. /// 移除一个组件, 并且销毁
  764. /// </summary>
  765. /// <param name="component">组件对象</param>
  766. public void RemoveComponent(Component component)
  767. {
  768. if (component.IsDestroyed)
  769. {
  770. return;
  771. }
  772.  
  773. if (_updatingComp)
  774. {
  775. _changeComponents.Add(new KeyValuePair<Component, bool>(component, false));
  776. component.Destroy();
  777. }
  778. else
  779. {
  780. for (var i = 0; i < _components.Count; i++)
  781. {
  782. if (_components[i].Value == component)
  783. {
  784. _components.RemoveAt(i);
  785. component.Destroy();
  786. return;
  787. }
  788. }
  789. }
  790. }
  791.  
  792. /// <summary>
  793. /// 根据类型获取一个组件
  794. /// </summary>
  795. public Component GetComponent(Type type)
  796. {
  797. for (int i = 0; i < _components.Count; i++)
  798. {
  799. var temp = _components[i];
  800. if (temp.Key.IsAssignableTo(type))
  801. {
  802. return temp.Value;
  803. }
  804. }
  805.  
  806. if (_updatingComp)
  807. {
  808. for (var i = 0; i < _changeComponents.Count; i++)
  809. {
  810. var temp = _components[i];
  811. if (temp.Value.GetType().IsAssignableTo(type))
  812. {
  813. return temp.Value;
  814. }
  815. }
  816. }
  817.  
  818. return null;
  819. }
  820.  
  821. /// <summary>
  822. /// 根据类型获取一个组件
  823. /// </summary>
  824. public T GetComponent<T>() where T : Component
  825. {
  826. for (int i = 0; i < _components.Count; i++)
  827. {
  828. var temp = _components[i];
  829. if (temp.Value is T component)
  830. {
  831. return component;
  832. }
  833. }
  834.  
  835. if (_updatingComp)
  836. {
  837. for (var i = 0; i < _changeComponents.Count; i++)
  838. {
  839. var temp = _components[i];
  840. if (temp.Value is T component)
  841. {
  842. return component;
  843. }
  844. }
  845. }
  846.  
  847. return null;
  848. }
  849.  
  850. /// <summary>
  851. /// 根据类型获取所有相同类型的组件
  852. /// </summary>
  853. public Component[] GetComponents(Type type)
  854. {
  855. var list = new List<Component>();
  856. for (int i = 0; i < _components.Count; i++)
  857. {
  858. var temp = _components[i];
  859. if (temp.Key.IsAssignableTo(type))
  860. {
  861. list.Add(temp.Value);
  862. }
  863. }
  864.  
  865. if (_updatingComp)
  866. {
  867. for (var i = 0; i < _changeComponents.Count; i++)
  868. {
  869. var temp = _components[i];
  870. if (temp.Value.GetType().IsAssignableTo(type))
  871. {
  872. list.Add(temp.Value);
  873. }
  874. }
  875. }
  876.  
  877. return list.ToArray();
  878. }
  879. /// <summary>
  880. /// 根据类型获取所有相同类型的组件
  881. /// </summary>
  882. public T[] GetComponents<T>() where T : Component
  883. {
  884. var list = new List<T>();
  885. for (int i = 0; i < _components.Count; i++)
  886. {
  887. var temp = _components[i];
  888. if (temp.Value is T component)
  889. {
  890. list.Add(component);
  891. }
  892. }
  893.  
  894. if (_updatingComp)
  895. {
  896. for (var i = 0; i < _changeComponents.Count; i++)
  897. {
  898. var temp = _components[i];
  899. if (temp.Value is T component)
  900. {
  901. list.Add(component);
  902. }
  903. }
  904. }
  905.  
  906. return list.ToArray();
  907. }
  908. /// <summary>
  909. /// 设置混色材质的颜色
  910. /// </summary>
  911. public void SetBlendColor(Color color)
  912. {
  913. _blendShaderMaterial?.SetShaderParameter("blend", color);
  914. }
  915.  
  916. /// <summary>
  917. /// 获取混色材质的颜色
  918. /// </summary>
  919. public Color GetBlendColor()
  920. {
  921. if (_blendShaderMaterial == null)
  922. {
  923. return Colors.White;
  924. }
  925. return _blendShaderMaterial.GetShaderParameter("blend").AsColor();
  926. }
  927. /// <summary>
  928. /// 设置混色材质的强度
  929. /// </summary>
  930. public void SetBlendSchedule(float value)
  931. {
  932. _blendShaderMaterial?.SetShaderParameter("schedule", value);
  933. }
  934.  
  935. /// <summary>
  936. /// 获取混色材质的强度
  937. /// </summary>
  938. public float GetBlendSchedule()
  939. {
  940. if (_blendShaderMaterial == null)
  941. {
  942. return default;
  943. }
  944. return _blendShaderMaterial.GetShaderParameter("schedule").AsSingle();
  945. }
  946.  
  947. /// <summary>
  948. /// 设置混色颜色
  949. /// </summary>
  950. public void SetBlendModulate(Color color)
  951. {
  952. _blendShaderMaterial?.SetShaderParameter("modulate", color);
  953. _shadowBlendShaderMaterial?.SetShaderParameter("modulate", color);
  954. }
  955. /// <summary>
  956. /// 获取混色颜色
  957. /// </summary>
  958. public Color SetBlendModulate()
  959. {
  960. if (_blendShaderMaterial == null)
  961. {
  962. return Colors.White;
  963. }
  964. return _blendShaderMaterial.GetShaderParameter("modulate").AsColor();
  965. }
  966. /// <summary>
  967. /// 每帧调用一次, 为了防止子类覆盖 _Process(), 给 _Process() 加上了 sealed, 子类需要帧循环函数请重写 Process() 函数
  968. /// </summary>
  969. public sealed override void _Process(double delta)
  970. {
  971. #if TOOLS
  972. if (Engine.IsEditorHint())
  973. {
  974. return;
  975. }
  976. #endif
  977. var newDelta = (float)delta;
  978. if (EnableCustomBehavior)
  979. {
  980. Process(newDelta);
  981. }
  982. //更新组件
  983. if (_components.Count > 0)
  984. {
  985. _updatingComp = true;
  986. if (EnableCustomBehavior) //启用所有组件
  987. {
  988. for (int i = 0; i < _components.Count; i++)
  989. {
  990. if (IsDestroyed) return;
  991. var temp = _components[i].Value;
  992. if (temp != null && temp.Enable)
  993. {
  994. temp.Process(newDelta);
  995. }
  996. }
  997. }
  998. else //只更新 MoveController 组件
  999. {
  1000. if (MoveController.Enable)
  1001. {
  1002. MoveController.Process(newDelta);
  1003. }
  1004. }
  1005. _updatingComp = false;
  1006. if (_changeComponents.Count > 0)
  1007. {
  1008. RefreshComponent();
  1009. }
  1010. }
  1011.  
  1012. // 更新下坠处理逻辑
  1013. UpdateFall(newDelta);
  1014.  
  1015. //阴影
  1016. UpdateShadowSprite(newDelta);
  1017. // Hit 动画
  1018. if (_playHit)
  1019. {
  1020. if (_playHitSchedule < 0.05f)
  1021. {
  1022. _blendShaderMaterial?.SetShaderParameter("schedule", 1);
  1023. }
  1024. else if (_playHitSchedule < 0.15f)
  1025. {
  1026. _blendShaderMaterial?.SetShaderParameter("schedule", Mathf.Lerp(1, 0, (_playHitSchedule - 0.05f) / 0.1f));
  1027. }
  1028. if (_playHitSchedule >= 0.15f)
  1029. {
  1030. _blendShaderMaterial?.SetShaderParameter("schedule", 0);
  1031. _playHitSchedule = 0;
  1032. _playHit = false;
  1033. }
  1034. else
  1035. {
  1036. _playHitSchedule += newDelta;
  1037. }
  1038. }
  1039. //协程更新
  1040. ProxyCoroutineHandler.ProxyUpdateCoroutine(ref _coroutineList, newDelta);
  1041. //调试绘制
  1042. if (IsDebug)
  1043. {
  1044. QueueRedraw();
  1045. }
  1046. }
  1047.  
  1048. /// <summary>
  1049. /// 更新下坠处理逻辑
  1050. /// </summary>
  1051. public void UpdateFall(float delta)
  1052. {
  1053. // 下坠判定
  1054. if (Altitude > 0 || VerticalSpeed != 0)
  1055. {
  1056. if (_isFallOver) // 没有处于下坠状态, 则进入下坠状态
  1057. {
  1058. InitThrowData();
  1059. }
  1060. else
  1061. {
  1062. if (EnableVerticalMotion) //如果启用了纵向运动, 则更新运动
  1063. {
  1064. //GlobalRotationDegrees = GlobalRotationDegrees + ThrowRotationDegreesSpeed * newDelta;
  1065.  
  1066. var ysp = VerticalSpeed;
  1067.  
  1068. _altitude += VerticalSpeed * delta;
  1069. _verticalSpeed -= GameConfig.G * ActivityMaterial.GravityScale * delta;
  1070.  
  1071. //当高度大于16时, 显示在所有物体上, 并且关闭碰撞
  1072. if (Altitude >= 16)
  1073. {
  1074. AnimatedSprite.ZIndex = 20;
  1075. }
  1076. else
  1077. {
  1078. AnimatedSprite.ZIndex = 0;
  1079. }
  1080. //动态开关碰撞器
  1081. if (ActivityMaterial.DynamicCollision)
  1082. {
  1083. Collision.Disabled = Altitude >= 16;
  1084. }
  1085. //达到最高点
  1086. if (ysp > 0 && ysp * VerticalSpeed < 0)
  1087. {
  1088. OnThrowMaxHeight(Altitude);
  1089. }
  1090.  
  1091. //落地判断
  1092. if (Altitude <= 0)
  1093. {
  1094. _altitude = 0;
  1095.  
  1096. //第一次接触地面
  1097. if (_firstFall)
  1098. {
  1099. _firstFall = false;
  1100. OnFirstFallToGround();
  1101. }
  1102.  
  1103. if (_throwForce != null)
  1104. {
  1105. //缩放移动速度
  1106. //MoveController.ScaleAllForce(BounceSpeed);
  1107. _throwForce.Velocity *= ActivityMaterial.FallBounceSpeed;
  1108. //缩放旋转速度
  1109. //MoveController.ScaleAllRotationSpeed(BounceStrength);
  1110. _throwForce.RotationSpeed *= ActivityMaterial.FallBounceRotation;
  1111. }
  1112. //如果落地高度不够低, 再抛一次
  1113. if (ActivityMaterial.Bounce && (!_hasResilienceVerticalSpeed || _resilienceVerticalSpeed > 5))
  1114. {
  1115. if (!_hasResilienceVerticalSpeed)
  1116. {
  1117. _hasResilienceVerticalSpeed = true;
  1118. _resilienceVerticalSpeed = -VerticalSpeed * ActivityMaterial.FallBounceStrength;
  1119. }
  1120. else
  1121. {
  1122. if (_resilienceVerticalSpeed < 25)
  1123. {
  1124. _resilienceVerticalSpeed = _resilienceVerticalSpeed * ActivityMaterial.FallBounceStrength * 0.4f;
  1125. }
  1126. else
  1127. {
  1128. _resilienceVerticalSpeed = _resilienceVerticalSpeed * ActivityMaterial.FallBounceStrength;
  1129. }
  1130. }
  1131. _verticalSpeed = _resilienceVerticalSpeed;
  1132. _isFallOver = false;
  1133.  
  1134. OnFallToGround();
  1135. }
  1136. else //结束
  1137. {
  1138. _verticalSpeed = 0;
  1139.  
  1140. if (_throwForce != null)
  1141. {
  1142. MoveController.RemoveForce(_throwForce);
  1143. _throwForce = null;
  1144. }
  1145. _isFallOver = true;
  1146. OnFallToGround();
  1147. ThrowOver();
  1148. }
  1149. }
  1150. }
  1151.  
  1152. //计算精灵位置
  1153. CalcThrowAnimatedPosition();
  1154. }
  1155. }
  1156.  
  1157. }
  1158.  
  1159. /// <summary>
  1160. /// 更新阴影逻辑
  1161. /// </summary>
  1162. public void UpdateShadowSprite(float delta)
  1163. {
  1164. // 阴影
  1165. if (ShadowSprite.Visible)
  1166. {
  1167. if (!IsCustomShadowSprite)
  1168. {
  1169. //更新阴影贴图, 使其和动画一致
  1170. var anim = AnimatedSprite.Animation;
  1171. var frame = AnimatedSprite.Frame;
  1172. if (_prevAnimation != anim || _prevAnimationFrame != frame)
  1173. {
  1174. //切换阴影动画
  1175. ShadowSprite.Texture = AnimatedSprite.SpriteFrames.GetFrameTexture(anim, AnimatedSprite.Frame);
  1176. }
  1177.  
  1178. _prevAnimation = anim;
  1179. _prevAnimationFrame = frame;
  1180. }
  1181.  
  1182. if (_freezeSprite == null || !_freezeSprite.IsFrozen)
  1183. {
  1184. //计算阴影
  1185. CalcShadowTransform();
  1186. }
  1187. }
  1188.  
  1189. }
  1190. /// <summary>
  1191. /// 每物理帧调用一次, 为了防止子类覆盖 _PhysicsProcess(), 给 _PhysicsProcess() 加上了 sealed, 子类需要帧循环函数请重写 PhysicsProcess() 函数
  1192. /// </summary>
  1193. public sealed override void _PhysicsProcess(double delta)
  1194. {
  1195. #if TOOLS
  1196. if (Engine.IsEditorHint())
  1197. {
  1198. return;
  1199. }
  1200. #endif
  1201. var newDelta = (float)delta;
  1202. if (EnableCustomBehavior)
  1203. {
  1204. PhysicsProcess(newDelta);
  1205. }
  1206. //更新组件
  1207. if (_components.Count > 0)
  1208. {
  1209. _updatingComp = true;
  1210. if (EnableCustomBehavior) //启用所有组件
  1211. {
  1212. for (int i = 0; i < _components.Count; i++)
  1213. {
  1214. if (IsDestroyed) return;
  1215. var temp = _components[i].Value;
  1216. if (temp != null && temp.Enable)
  1217. {
  1218. temp.PhysicsProcess(newDelta);
  1219. }
  1220. }
  1221. }
  1222. else //只更新 MoveController 组件
  1223. {
  1224. if (MoveController.Enable)
  1225. {
  1226. MoveController.PhysicsProcess(newDelta);
  1227. }
  1228. }
  1229. _updatingComp = false;
  1230.  
  1231. if (_changeComponents.Count > 0)
  1232. {
  1233. RefreshComponent();
  1234. }
  1235. }
  1236. }
  1237.  
  1238. //更新新增/移除的组件
  1239. private void RefreshComponent()
  1240. {
  1241. for (var i = 0; i < _changeComponents.Count; i++)
  1242. {
  1243. var item = _changeComponents[i];
  1244. if (item.Value) //添加组件
  1245. {
  1246. _components.Add(new KeyValuePair<Type, Component>(item.Key.GetType(), item.Key));
  1247. }
  1248. else //移除组件
  1249. {
  1250. for (var j = 0; j < _components.Count; j++)
  1251. {
  1252. if (_components[i].Value == item.Key)
  1253. {
  1254. _components.RemoveAt(i);
  1255. break;
  1256. }
  1257. }
  1258. }
  1259. }
  1260. }
  1261.  
  1262. /// <summary>
  1263. /// 绘制函数, 子类不允许重写, 需要绘制函数请重写 DebugDraw()
  1264. /// </summary>
  1265. public sealed override void _Draw()
  1266. {
  1267. #if TOOLS
  1268. if (Engine.IsEditorHint())
  1269. {
  1270. return;
  1271. }
  1272. #endif
  1273. if (IsDebug)
  1274. {
  1275. DebugDraw();
  1276. if (_components.Count > 0)
  1277. {
  1278. var arr = _components.ToArray();
  1279. for (int i = 0; i < arr.Length; i++)
  1280. {
  1281. if (IsDestroyed) return;
  1282. var temp = arr[i].Value;
  1283. if (temp != null && temp.Master == this && temp.Enable)
  1284. {
  1285. temp.DebugDraw();
  1286. }
  1287. }
  1288. }
  1289. }
  1290. }
  1291.  
  1292. /// <summary>
  1293. /// 重新计算物体阴影的位置和旋转信息, 无论是否显示阴影
  1294. /// </summary>
  1295. public void CalcShadowTransform()
  1296. {
  1297. //偏移
  1298. if (!IsCustomShadowSprite)
  1299. {
  1300. ShadowSprite.Offset = AnimatedSprite.Offset;
  1301. }
  1302.  
  1303. //缩放
  1304. ShadowSprite.Scale = AnimatedSprite.Scale;
  1305. //阴影角度
  1306. ShadowSprite.Rotation = 0;
  1307. //阴影位置计算
  1308. var pos = AnimatedSprite.GlobalPosition;
  1309. ShadowSprite.GlobalPosition = new Vector2(pos.X + ShadowOffset.X, pos.Y + ShadowOffset.Y + Altitude);
  1310. }
  1311.  
  1312. //计算位置
  1313. private void CalcThrowAnimatedPosition()
  1314. {
  1315. if (Scale.Y < 0)
  1316. {
  1317. var pos = new Vector2(_fallData.OriginSpritePosition.X, -_fallData.OriginSpritePosition.Y);
  1318. AnimatedSprite.GlobalPosition = GlobalPosition + new Vector2(0, -Altitude) - pos.Rotated(Rotation + Mathf.Pi);
  1319. }
  1320. else
  1321. {
  1322. AnimatedSprite.GlobalPosition = GlobalPosition + new Vector2(0, -Altitude) + _fallData.OriginSpritePosition.Rotated(Rotation);
  1323. }
  1324. }
  1325.  
  1326.  
  1327. /// <summary>
  1328. /// 销毁物体
  1329. /// </summary>
  1330. public void Destroy()
  1331. {
  1332. if (IsDestroyed)
  1333. {
  1334. return;
  1335. }
  1336. if (_mountObjects != null)
  1337. {
  1338. foreach (var item in _mountObjects)
  1339. {
  1340. item.OnUnmount(this);
  1341. }
  1342.  
  1343. _mountObjects = null;
  1344. }
  1345.  
  1346. IsDestroyed = true;
  1347. if (AffiliationArea != null)
  1348. {
  1349. AffiliationArea.RemoveItem(this);
  1350. }
  1351. QueueFree();
  1352. OnDestroy();
  1353.  
  1354. if (_freezeSprite != null)
  1355. {
  1356. _freezeSprite.Destroy();
  1357. }
  1358. var arr = _components.ToArray();
  1359. for (var i = 0; i < arr.Length; i++)
  1360. {
  1361. arr[i].Value?.Destroy();
  1362. }
  1363.  
  1364. _components.Clear();
  1365. if (_destroySet != null)
  1366. {
  1367. foreach (var destroy in _destroySet)
  1368. {
  1369. destroy.Destroy();
  1370. }
  1371.  
  1372. _destroySet = null;
  1373. }
  1374. }
  1375.  
  1376. /// <summary>
  1377. /// 延时销毁
  1378. /// </summary>
  1379. public void DelayDestroy()
  1380. {
  1381. CallDeferred(nameof(Destroy));
  1382. }
  1383.  
  1384. /// <summary>
  1385. /// 继承指定物体的运动速率
  1386. /// </summary>
  1387. /// <param name="other">目标对象</param>
  1388. /// <param name="scale">继承的速率缩放</param>
  1389. public void InheritVelocity(ActivityObject other, float scale = 0.5f)
  1390. {
  1391. MoveController.AddVelocity(other.Velocity * scale);
  1392. }
  1393.  
  1394. /// <summary>
  1395. /// 触发投抛动作
  1396. /// </summary>
  1397. private void Throw()
  1398. {
  1399. var parent = GetParent();
  1400. //投抛时必须要加入 YSortLayer 节点下
  1401. if (parent == null)
  1402. {
  1403. this.AddToActivityRoot(RoomLayerEnum.YSortLayer);
  1404. }
  1405. else if (parent != GameApplication.Instance.World.YSortLayer)
  1406. {
  1407. Reparent(GameApplication.Instance.World.YSortLayer);
  1408. }
  1409.  
  1410. CalcThrowAnimatedPosition();
  1411. //显示阴影
  1412. ShowShadowSprite();
  1413.  
  1414. if (EnableVerticalMotion)
  1415. {
  1416. OnThrowStart();
  1417. }
  1418. }
  1419.  
  1420. /// <summary>
  1421. /// 设置下坠状态下的碰撞器
  1422. /// </summary>
  1423. private void SetFallCollision()
  1424. {
  1425. if (_fallData != null && _fallData.UseOrigin)
  1426. {
  1427. _fallData.OriginShape = Collision.Shape;
  1428. _fallData.OriginPosition = Collision.Position;
  1429. _fallData.OriginRotation = Collision.Rotation;
  1430. _fallData.OriginScale = Collision.Scale;
  1431. _fallData.OriginZIndex = ZIndex;
  1432. _fallData.OriginSpritePosition = AnimatedSprite.Position;
  1433. _fallData.OriginCollisionEnable = Collision.Disabled;
  1434. _fallData.OriginCollisionPosition = Collision.Position;
  1435. _fallData.OriginCollisionRotation = Collision.Rotation;
  1436. _fallData.OriginCollisionScale = Collision.Scale;
  1437. _fallData.OriginCollisionMask = CollisionMask;
  1438. _fallData.OriginCollisionLayer = CollisionLayer;
  1439.  
  1440. Collision.Position = Vector2.Zero;
  1441. Collision.Rotation = 0;
  1442. Collision.Scale = Vector2.One;
  1443. ZIndex = 0;
  1444. Collision.Disabled = false;
  1445. Collision.Position = Vector2.Zero;
  1446. Collision.Rotation = 0;
  1447. Collision.Scale = Vector2.One;
  1448. CollisionMask = ThrowCollisionMask;
  1449. CollisionLayer = _fallData.OriginCollisionLayer | PhysicsLayer.Throwing;
  1450. _fallData.UseOrigin = false;
  1451. }
  1452. }
  1453.  
  1454. /// <summary>
  1455. /// 重置碰撞器
  1456. /// </summary>
  1457. private void RestoreCollision()
  1458. {
  1459. if (_fallData != null && !_fallData.UseOrigin)
  1460. {
  1461. Collision.Shape = _fallData.OriginShape;
  1462. Collision.Position = _fallData.OriginPosition;
  1463. Collision.Rotation = _fallData.OriginRotation;
  1464. Collision.Scale = _fallData.OriginScale;
  1465. ZIndex = _fallData.OriginZIndex;
  1466. AnimatedSprite.Position = _fallData.OriginSpritePosition;
  1467. Collision.Disabled = _fallData.OriginCollisionEnable;
  1468. Collision.Position = _fallData.OriginCollisionPosition;
  1469. Collision.Rotation = _fallData.OriginCollisionRotation;
  1470. Collision.Scale = _fallData.OriginCollisionScale;
  1471. CollisionMask = _fallData.OriginCollisionMask;
  1472. CollisionLayer = _fallData.OriginCollisionLayer;
  1473.  
  1474. _fallData.UseOrigin = true;
  1475. }
  1476. }
  1477.  
  1478. /// <summary>
  1479. /// 投抛结束
  1480. /// </summary>
  1481. private void ThrowOver()
  1482. {
  1483. var parent = GetParent();
  1484. var roomLayer = GameApplication.Instance.World.GetRoomLayer(DefaultLayer);
  1485. if (parent != roomLayer)
  1486. {
  1487. parent.RemoveChild(this);
  1488. roomLayer.AddChild(this);
  1489. }
  1490. RestoreCollision();
  1491.  
  1492. OnThrowOver();
  1493. }
  1494.  
  1495. //初始化投抛状态数据
  1496. private void InitThrowData()
  1497. {
  1498. SetFallCollision();
  1499.  
  1500. _isFallOver = false;
  1501. _firstFall = true;
  1502. _hasResilienceVerticalSpeed = false;
  1503. _resilienceVerticalSpeed = 0;
  1504.  
  1505. Throw();
  1506. }
  1507.  
  1508. /// <summary>
  1509. /// 设置标记, 用于在物体上记录自定义数据
  1510. /// </summary>
  1511. /// <param name="name">标记名称</param>
  1512. /// <param name="v">存入值</param>
  1513. public void SetSign(string name, object v)
  1514. {
  1515. if (_signMap == null)
  1516. {
  1517. _signMap = new Dictionary<string, object>();
  1518. }
  1519.  
  1520. _signMap[name] = v;
  1521. }
  1522.  
  1523. /// <summary>
  1524. /// 返回是否存在指定名称的标记数据
  1525. /// </summary>
  1526. public bool HasSign(string name)
  1527. {
  1528. return _signMap == null ? false : _signMap.ContainsKey(name);
  1529. }
  1530.  
  1531. /// <summary>
  1532. /// 根据名称获取标记值
  1533. /// </summary>
  1534. public object GetSign(string name)
  1535. {
  1536. if (_signMap == null)
  1537. {
  1538. return null;
  1539. }
  1540.  
  1541. _signMap.TryGetValue(name, out var value);
  1542. return value;
  1543. }
  1544.  
  1545. /// <summary>
  1546. /// 根据名称获取标记值
  1547. /// </summary>
  1548. public T GetSign<T>(string name)
  1549. {
  1550. if (_signMap == null)
  1551. {
  1552. return default;
  1553. }
  1554.  
  1555. _signMap.TryGetValue(name, out var value);
  1556. if (value is T v)
  1557. {
  1558. return v;
  1559. }
  1560. return default;
  1561. }
  1562.  
  1563. /// <summary>
  1564. /// 根据名称删除标记
  1565. /// </summary>
  1566. public void RemoveSign(string name)
  1567. {
  1568. if (_signMap != null)
  1569. {
  1570. _signMap.Remove(name);
  1571. }
  1572. }
  1573.  
  1574. /// <summary>
  1575. /// 播放受伤动画, 该动画不与 Animation 节点的动画冲突
  1576. /// </summary>
  1577. public void PlayHitAnimation()
  1578. {
  1579. _playHit = true;
  1580. _playHitSchedule = 0;
  1581. }
  1582.  
  1583. /// <summary>
  1584. /// 获取当前摩擦力
  1585. /// </summary>
  1586. public float GetCurrentFriction()
  1587. {
  1588. return ActivityMaterial.Friction;
  1589. }
  1590. /// <summary>
  1591. /// 获取当前旋转摩擦力
  1592. /// </summary>
  1593. public float GetCurrentRotationFriction()
  1594. {
  1595. return ActivityMaterial.RotationFriction;
  1596. }
  1597. public long StartCoroutine(IEnumerator able)
  1598. {
  1599. return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
  1600. }
  1601. public void StopCoroutine(long coroutineId)
  1602. {
  1603. ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
  1604. }
  1605.  
  1606. public bool IsCoroutineOver(long coroutineId)
  1607. {
  1608. return ProxyCoroutineHandler.ProxyIsCoroutineOver(ref _coroutineList, coroutineId);
  1609. }
  1610.  
  1611. public void StopAllCoroutine()
  1612. {
  1613. ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
  1614. }
  1615. /// <summary>
  1616. /// 播放 AnimatedSprite 上的动画, 如果没有这个动画, 则什么也不会发生
  1617. /// </summary>
  1618. /// <param name="name">动画名称</param>
  1619. public void PlaySpriteAnimation(string name)
  1620. {
  1621. var spriteFrames = AnimatedSprite.SpriteFrames;
  1622. if (spriteFrames != null && spriteFrames.HasAnimation(name))
  1623. {
  1624. AnimatedSprite.Play(name);
  1625. }
  1626. }
  1627.  
  1628. /// <summary>
  1629. /// 将当前 ActivityObject 变成静态图像绘制到地面上, 用于优化渲染大量物体<br/>
  1630. /// 调用该函数后会排队进入渲染队列, 并且禁用所有行为, 当渲染完成后会销毁当前对象, 也就是调用 Destroy() 函数<br/>
  1631. /// </summary>
  1632. public void BecomesStaticImage()
  1633. {
  1634. if (_processingBecomesStaticImage)
  1635. {
  1636. return;
  1637. }
  1638. if (AffiliationArea == null)
  1639. {
  1640. Debug.LogError($"调用函数: BecomesStaticImage() 失败, 物体{Name}没有归属区域, 无法确定绘制到哪个ImageCanvas上, 直接执行销毁");
  1641. Destroy();
  1642. return;
  1643. }
  1644.  
  1645. _processingBecomesStaticImage = true;
  1646. EnableBehavior = false;
  1647. var roomInfo = AffiliationArea.RoomInfo;
  1648. var position = roomInfo.ToCanvasPosition(GlobalPosition);
  1649. roomInfo.StaticImageCanvas.DrawActivityObjectInCanvas(this, position.X, position.Y, () =>
  1650. {
  1651. Destroy();
  1652. });
  1653. }
  1654.  
  1655. /// <summary>
  1656. /// 是否正在处理成为静态图片
  1657. /// </summary>
  1658. public bool IsProcessingBecomesStaticImage()
  1659. {
  1660. return _processingBecomesStaticImage;
  1661. }
  1662. /// <summary>
  1663. /// 冻结物体,多余的节点就会被移出场景树,逻辑也会被暂停,用于优化性能
  1664. /// </summary>
  1665. public void Freeze()
  1666. {
  1667. if (_freezeSprite == null)
  1668. {
  1669. _freezeSprite = new FreezeSprite(this);
  1670. }
  1671. _freezeSprite.Freeze();
  1672. }
  1673.  
  1674. /// <summary>
  1675. /// 解冻物体, 恢复正常逻辑
  1676. /// </summary>
  1677. public void Unfreeze()
  1678. {
  1679. if (_freezeSprite == null)
  1680. {
  1681. return;
  1682. }
  1683. _freezeSprite.Unfreeze();
  1684. }
  1685.  
  1686. /// <summary>
  1687. /// 获取中心点坐标
  1688. /// </summary>
  1689. public Vector2 GetCenterPosition()
  1690. {
  1691. return AnimatedSprite.Position + Position;
  1692. }
  1693.  
  1694. /// <summary>
  1695. /// 设置物体朝向
  1696. /// </summary>
  1697. public void SetForwardDirection(FaceDirection face)
  1698. {
  1699. if ((face == FaceDirection.Left && Scale.X > 0) || (face == FaceDirection.Right && Scale.X < 0))
  1700. {
  1701. Scale *= new Vector2(-1, 1);
  1702. }
  1703. }
  1704. /// <summary>
  1705. /// 添加一个击退力
  1706. /// </summary>
  1707. public void AddRepelForce(Vector2 velocity)
  1708. {
  1709. if (_repelForce == null)
  1710. {
  1711. _repelForce = new ExternalForce(ForceNames.Repel);
  1712. }
  1713.  
  1714. //不在 MoveController 中
  1715. if (_repelForce.MoveController == null)
  1716. {
  1717. _repelForce.Velocity = velocity;
  1718. MoveController.AddForce(_repelForce);
  1719. }
  1720. else
  1721. {
  1722. _repelForce.Velocity += velocity;
  1723. }
  1724. }
  1725.  
  1726. /// <summary>
  1727. /// 获取击退力
  1728. /// </summary>
  1729. public Vector2 GetRepelForce()
  1730. {
  1731. if (_repelForce == null || _repelForce.MoveController == null)
  1732. {
  1733. return Vector2.Zero;
  1734. }
  1735.  
  1736. return _repelForce.Velocity;
  1737. }
  1738.  
  1739. /// <summary>
  1740. /// 根据笔刷 id 在该物体位置绘制液体, 该 id 为 LiquidMaterial 表的 id<br/>
  1741. /// 需要清除记录的点就请将 BrushPrevPosition 置为 null
  1742. /// </summary>
  1743. public void DrawLiquid(string brushId)
  1744. {
  1745. if (AffiliationArea != null)
  1746. {
  1747. DrawLiquid(LiquidBrushManager.GetBrush(brushId));
  1748. }
  1749. }
  1750. /// <summary>
  1751. /// 根据笔刷数据在该物体位置绘制液体<br/>
  1752. /// 需要清除记录的点就请将 BrushPrevPosition 置为 null
  1753. /// </summary>
  1754. public void DrawLiquid(BrushImageData brush)
  1755. {
  1756. if (AffiliationArea != null)
  1757. {
  1758. var pos = AffiliationArea.RoomInfo.LiquidCanvas.ToLiquidCanvasPosition(Position);
  1759. AffiliationArea.RoomInfo.LiquidCanvas.DrawBrush(brush, BrushPrevPosition, pos, 0);
  1760. BrushPrevPosition = pos;
  1761. }
  1762. }
  1763. /// <summary>
  1764. /// 根据笔刷 id 在该物体位置绘制液体, 该 id 为 LiquidMaterial 表的 id<br/>
  1765. /// 需要清除记录的点就请将 BrushPrevPosition 置为 null
  1766. /// </summary>
  1767. public void DrawLiquid(string brushId, Vector2I offset)
  1768. {
  1769. if (AffiliationArea != null)
  1770. {
  1771. DrawLiquid(LiquidBrushManager.GetBrush(brushId), offset);
  1772. }
  1773. }
  1774. /// <summary>
  1775. /// 根据笔刷数据在该物体位置绘制液体<br/>
  1776. /// 需要清除记录的点就请将 BrushPrevPosition 置为 null
  1777. /// </summary>
  1778. public void DrawLiquid(BrushImageData brush, Vector2I offset)
  1779. {
  1780. if (AffiliationArea != null)
  1781. {
  1782. var pos = AffiliationArea.RoomInfo.LiquidCanvas.ToLiquidCanvasPosition(Position) + offset;
  1783. AffiliationArea.RoomInfo.LiquidCanvas.DrawBrush(brush, BrushPrevPosition, pos, 0);
  1784. BrushPrevPosition = pos;
  1785. }
  1786. }
  1787.  
  1788. /// <summary>
  1789. /// 绑定可销毁对象, 绑定的物体会在当前物体销毁时触发销毁
  1790. /// </summary>
  1791. public void AddDestroyObject(IDestroy destroy)
  1792. {
  1793. if (_destroySet == null)
  1794. {
  1795. _destroySet = new HashSet<IDestroy>();
  1796. }
  1797.  
  1798. _destroySet.Add(destroy);
  1799. }
  1800.  
  1801. /// <summary>
  1802. /// 移除绑定可销毁对象
  1803. /// </summary>
  1804. public void RemoveDestroyObject(IDestroy destroy)
  1805. {
  1806. if (_destroySet == null)
  1807. {
  1808. return;
  1809. }
  1810. _destroySet.Remove(destroy);
  1811. }
  1812.  
  1813. /// <summary>
  1814. /// 绑定挂载对象, 绑定的物体会在当前物体销毁时触发扔出
  1815. /// </summary>
  1816. public void AddMountObject(IMountItem target)
  1817. {
  1818. if (_mountObjects == null)
  1819. {
  1820. _mountObjects = new HashSet<IMountItem>();
  1821. }
  1822.  
  1823. if (_mountObjects.Add(target))
  1824. {
  1825. target.OnMount(this);
  1826. }
  1827. }
  1828. /// <summary>
  1829. /// 移除绑定挂载对象
  1830. /// </summary>
  1831. public void RemoveMountObject(IMountItem target)
  1832. {
  1833. if (_mountObjects == null)
  1834. {
  1835. return;
  1836. }
  1837.  
  1838. if (_mountObjects.Remove(target))
  1839. {
  1840. target.OnUnmount(this);
  1841. }
  1842. }
  1843. }