-
- using System;
- using System.IO;
- using Godot;
-
- /// <summary>
- /// 用于在预制场景中创建 ActivityObject
- /// </summary>
- [Tool]
- public partial class ActivityInstance : Node2D
- {
- private const string GroupName = "Editor";
-
- /// <summary>
- /// 物体Id
- /// </summary>
- [Export]
- public string Id
- {
- get => _id;
- set
- {
- _id = value;
- _dirty = true;
- }
- }
-
- /// <summary>
- /// 默认所在层级
- /// </summary>
- [Export]
- public RoomLayerEnum DefaultLayer { get; set; } = RoomLayerEnum.NormalLayer;
-
- /// <summary>
- /// 是否显示阴影
- /// </summary>
- [Export]
- public bool ShowShadow
- {
- get => _showShadow;
- set
- {
- _showShadow = value;
- if (_activityObject != null)
- {
- if (value)
- {
- _activityObject.ShowShadowSprite();
- }
- else
- {
- _activityObject.HideShadowSprite();
- }
- }
- }
- }
-
- /// <summary>
- /// 阴影偏移
- /// </summary>
- [Export]
- public Vector2 ShowOffset
- {
- get => _showOffset;
- set
- {
- _showOffset = value;
- if (_activityObject != null)
- {
- _activityObject.ShadowOffset = value;
- }
- }
- }
-
- /// <summary>
- /// 初始海拔高度
- /// </summary>
- [Export]
- public float Altitude
- {
- get => _altitude;
- set
- {
- _altitude = value;
- if (_activityObject != null)
- {
- _activityObject.Altitude = value;
- _activityObject.Collision.Position = _collPos;
- _activityObject.UpdateShadowSprite((float)GetProcessDeltaTime());
- _activityObject.CalcThrowAnimatedPosition();
- }
- }
- }
-
- /// <summary>
- /// 动画精灵的z轴索引
- /// </summary>
- [Export]
- public int SpriteZIndex
- {
- get => _spriteZIndex;
- set
- {
- _spriteZIndex = value;
- if (_activityObject != null)
- {
- _activityObject.AnimatedSprite.ZIndex = value;
- }
- }
- }
-
- /// <summary>
- /// 阴影z轴索引
- /// </summary>
- [Export]
- public int ShadowZIndex
- {
- get => _shadowZIndex;
- set
- {
- _shadowZIndex = value;
- if (_activityObject != null)
- {
- _activityObject.ShadowSprite.ZIndex = value;
- }
- }
- }
-
- /// <summary>
- /// 是否启用垂直运动模拟
- /// </summary>
- [Export]
- public bool VerticalMotion { get; private set; } = true;
-
- /// <summary>
- /// 是否启用碰撞器
- /// </summary>
- [Export]
- public bool CollisionEnabled
- {
- get => _collisionEnabled;
- set
- {
- _collisionEnabled = value;
- if (_activityObject != null)
- {
- _activityObject.Collision.Disabled = !value;
- }
- }
- }
-
- /// <summary>
- /// 编辑器属性, 物体子碰撞器在编辑器中是否可见
- /// </summary>
- [Export]
- public bool CollisionVisible
- {
- get => _collisionVisible;
- set
- {
- _collisionVisible = value;
- OnChangeCollisionVisible();
- }
- }
-
- private bool _dirty = false;
- private bool _collisionVisible = true;
- private string _prevId;
- private string _id;
- private ActivityObject _activityObject;
- private Sprite2D _errorSprite;
- private bool _showShadow = true;
- private Vector2 _showOffset = new Vector2(0, 2);
- private float _altitude;
- private int _spriteZIndex = 0;
- private int _shadowZIndex = -1;
- private bool _collisionEnabled = true;
-
- private Vector2 _collPos;
- private bool _createFlag = false;
-
- //嵌套Instance相关
- private bool _isNested = false;
- private ActivityObject _activityInstance;
-
- private static string _jsonText;
-
- /// <summary>
- /// 清空缓存的json
- /// </summary>
- public static void ClearCacheJson()
- {
- _jsonText = null;
- }
-
- public override void _Ready()
- {
- #if TOOLS
- if (!Engine.IsEditorHint())
- {
- #endif
- var world = World.Current;
- if (world != null && world.YSortLayer != null && world.NormalLayer != null)
- {
- DoCreateObject();
- }
- #if TOOLS
- }
- #endif
- }
-
- public override void _Process(double delta)
- {
- #if TOOLS
- if (Engine.IsEditorHint())
- {
- if (_dirty || (_activityObject != null && _activityObject.GetParent() != this))
- {
- _dirty = false;
-
- if (_prevId != _id)
- {
- OnChangeActivityId(_id);
- }
- else if (string.IsNullOrEmpty(_id))
- {
- ShowErrorSprite();
- }
-
- OnChangeCollisionVisible();
- }
-
- if (_activityObject != null)
- {
- _activityObject.Collision.Position = _collPos;
- _activityObject.UpdateShadowSprite((float)delta);
- _activityObject.CalcThrowAnimatedPosition();
- }
- }
- else
- {
- #endif
- var world = World.Current;
- if (world != null && world.YSortLayer != null && world.NormalLayer != null)
- {
- DoCreateObject();
- }
- #if TOOLS
- }
- #endif
- }
-
- public override void _EnterTree()
- {
- #if TOOLS
- if (Engine.IsEditorHint())
- {
- _dirty = true;
-
- var children = GetChildren();
- foreach (var child in children)
- {
- if (child is ActivityObject)
- {
- child.QueueFree();
- }
- }
- if (_activityObject != null)
- {
- _activityObject.QueueFree();
- }
- _activityObject = null;
- _prevId = null;
- }
- #endif
- }
-
- public override void _ExitTree()
- {
- #if TOOLS
- if (Engine.IsEditorHint() && _activityObject != null)
- {
- _activityObject.QueueFree();
- _activityObject = null;
- }
- #endif
- }
-
- private ActivityObject DoCreateObject()
- {
- if (_createFlag)
- {
- return _activityInstance;
- }
-
- _createFlag = true;
- var activityObject = ActivityObject.Create(Id);
- if (_isNested)
- {
- activityObject.Position = Position - new Vector2(0, 1);
- activityObject.Scale = Scale;
- activityObject.Rotation = Rotation;
- }
- else
- {
- activityObject.Position = GlobalPosition + new Vector2(0, 1);
- activityObject.Scale = GlobalScale;
- activityObject.Rotation = GlobalRotation;
- }
-
- activityObject.Visible = Visible;
- activityObject.ShadowOffset = _showOffset;
- activityObject.Altitude = _altitude;
- activityObject.AnimatedSprite.ZIndex = _spriteZIndex;
- activityObject.ShadowSprite.ZIndex = _shadowZIndex;
- activityObject.EnableVerticalMotion = VerticalMotion;
- activityObject.Collision.Disabled = !_collisionEnabled;
- if (!_isNested)
- {
- activityObject.PutDown(DefaultLayer, _showShadow);
- }
- else
- {
- activityObject.DefaultLayer = DefaultLayer;
- activityObject.ShowShadowSprite();
- }
-
- var children = GetChildren();
- foreach (var child in children)
- {
- if (!child.IsInGroup(GroupName))
- {
- if (child is ActivityInstance o)
- {
- o._isNested = true;
- var instance = o.DoCreateObject();
- activityObject.AddChild(instance);
- if (instance is IMountItem mountItem)
- {
- activityObject.AddMountObject(mountItem);
- }
- else if (instance is IDestroy destroy)
- {
- activityObject.AddDestroyObject(destroy);
- }
- }
- else
- {
- child.Reparent(activityObject);
- if (child is Node2D node2D && activityObject.GetCurrentTexture().GetHeight() % 2 == 0)
- {
- node2D.Position += new Vector2(0, 1);
- }
- }
- }
- }
-
- QueueFree();
- _activityInstance = activityObject;
- return activityObject;
- }
-
- private void OnChangeActivityId(string id)
- {
- _prevId = id;
-
- if (_activityObject != null)
- {
- _activityObject.QueueFree();
- _activityObject = null;
- }
-
- if (string.IsNullOrEmpty(id))
- {
- ShowErrorSprite();
- return;
- }
-
- if (_jsonText == null)
- {
- _jsonText = File.ReadAllText("resource/config/ActivityBase.json");
- }
- var str = $"\"Id\": \"{id}\",";
- var index = _jsonText.IndexOf(str, StringComparison.Ordinal);
- if (index > -1)
- {
- const string s = "\"Prefab\": \"";
- var startIndex = _jsonText.IndexOf(s, index, StringComparison.Ordinal);
- if (startIndex > -1)
- {
- var endIndex = _jsonText.IndexOf('"', startIndex + s.Length + 1);
- if (endIndex > -1)
- {
- var prefab = _jsonText.Substring(startIndex + s.Length, endIndex - (startIndex + s.Length));
- var instance = ResourceManager.LoadAndInstantiate<ActivityObject>(prefab);
- _activityObject = instance;
- _collPos = instance.Collision.Position - instance.AnimatedSprite.Position - instance.AnimatedSprite.Offset;
- instance.IsCustomShadowSprite = instance.ShadowSprite.Texture != null;
- instance.Altitude = _altitude;
- instance.ShadowOffset = _showOffset;
- _activityObject.Position = _activityObject.AnimatedSprite.Position;
- if (_showShadow)
- {
- instance.ShowShadowSprite();
- var shadowSpriteMaterial = instance.ShadowSprite.Material as ShaderMaterial;
- if (shadowSpriteMaterial != null)
- {
- shadowSpriteMaterial.SetShaderParameter(
- ShaderParamNames.ShowOutline,
- ((ShaderMaterial)instance.AnimatedSprite.Material).GetShaderParameter(ShaderParamNames
- .ShowOutline)
- );
- }
- }
- AddChild(instance);
- MoveChild(instance, 0);
- HideErrorSprite();
- return;
- }
- }
- }
- GD.PrintErr($"未找到Id为'{id}'的物体!");
- ShowErrorSprite();
- }
-
- private void OnChangeCollisionVisible()
- {
- if (_activityObject != null)
- {
- Utils.EachNode(_activityObject, node =>
- {
- if (node is CollisionShape2D collisionShape2D)
- {
- collisionShape2D.Visible = _collisionVisible;
- }
- else if (node is CollisionPolygon2D collisionPolygon2D)
- {
- collisionPolygon2D.Visible = _collisionVisible;
- }
- });
- }
- }
-
- private void ShowErrorSprite()
- {
- if (_errorSprite == null)
- {
- _errorSprite = new Sprite2D();
- _errorSprite.AddToGroup(GroupName);
- _errorSprite.Texture = ResourceManager.LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_Error_mini_png);
- AddChild(_errorSprite);
- MoveChild(_errorSprite, GetChildCount() - 1);
- }
- }
-
- private void HideErrorSprite()
- {
- if (_errorSprite != null)
- {
- _errorSprite.QueueFree();
- _errorSprite = null;
- }
- }
- }