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