迁移测试文件,建立主程序集
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "GeometryTD.Runtime",
|
||||
"rootNamespace": "GeometryTD",
|
||||
"references": [
|
||||
"UnityGameFramework.Runtime",
|
||||
"Unity.InputSystem",
|
||||
"Unity.TextMeshPro"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e67bd2d1b65d48ce8120141996e55b2b
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "GeometryTD.Editor",
|
||||
"rootNamespace": "GeometryTD.Editor",
|
||||
"references": [
|
||||
"GeometryTD.Runtime",
|
||||
"UnityGameFramework.Editor"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 739d2e9771244fc8af6c8d8636eade79
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -8,6 +8,44 @@ using UnityGameFramework.Runtime;
|
||||
|
||||
namespace GeometryTD.Procedure
|
||||
{
|
||||
public enum ProcedureMainFlowPhase
|
||||
{
|
||||
Hub = 0,
|
||||
NodeActive = 1,
|
||||
RunCompletedPendingFinish = 2
|
||||
}
|
||||
|
||||
public enum ProcedureMainRunAdvanceResult
|
||||
{
|
||||
NoChange = 0,
|
||||
NodeFailed = 1,
|
||||
AdvancedToNextNode = 2,
|
||||
RunCompleted = 3
|
||||
}
|
||||
|
||||
public static class ProcedureMainRunFlowService
|
||||
{
|
||||
public static ProcedureMainRunAdvanceResult TryAdvanceRun(
|
||||
RunState runState,
|
||||
bool succeeded,
|
||||
BackpackInventoryData snapshot)
|
||||
{
|
||||
if (!RunStateAdvanceService.TryCompleteCurrentNode(runState, succeeded, snapshot))
|
||||
{
|
||||
return ProcedureMainRunAdvanceResult.NoChange;
|
||||
}
|
||||
|
||||
if (runState != null && runState.IsCompleted)
|
||||
{
|
||||
return ProcedureMainRunAdvanceResult.RunCompleted;
|
||||
}
|
||||
|
||||
return succeeded
|
||||
? ProcedureMainRunAdvanceResult.AdvancedToNextNode
|
||||
: ProcedureMainRunAdvanceResult.NodeFailed;
|
||||
}
|
||||
}
|
||||
|
||||
public class ProcedureMain : ProcedureBase
|
||||
{
|
||||
public override bool UseNativeDialog => false;
|
||||
@@ -15,6 +53,7 @@ namespace GeometryTD.Procedure
|
||||
private RepoFormUseCase _repoFormUseCase;
|
||||
private NodeMapFormUseCase _nodeMapFormUseCase;
|
||||
private RunState _currentRunState;
|
||||
private ProcedureMainFlowPhase _flowPhase = ProcedureMainFlowPhase.Hub;
|
||||
|
||||
#region FSM
|
||||
|
||||
@@ -45,7 +84,7 @@ namespace GeometryTD.Procedure
|
||||
_nodeMapFormUseCase.SetRunState(_currentRunState);
|
||||
GameEntry.UIRouter.BindUIUseCase(UIFormType.NodeMapForm, _nodeMapFormUseCase);
|
||||
|
||||
OpenHubUI();
|
||||
EnterHubFlow();
|
||||
}
|
||||
|
||||
protected override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds,
|
||||
@@ -69,6 +108,7 @@ namespace GeometryTD.Procedure
|
||||
_repoFormUseCase = null;
|
||||
_nodeMapFormUseCase = null;
|
||||
_currentRunState = null;
|
||||
_flowPhase = ProcedureMainFlowPhase.Hub;
|
||||
|
||||
base.OnLeave(procedureOwner, isShutdown);
|
||||
}
|
||||
@@ -117,8 +157,7 @@ namespace GeometryTD.Procedure
|
||||
args.NodeType,
|
||||
args.SequenceIndex);
|
||||
|
||||
GameEntry.UIRouter.CloseUI(UIFormType.NodeMapForm);
|
||||
GameEntry.UIRouter.CloseUI(UIFormType.MainForm);
|
||||
EnterNodeFlow();
|
||||
}
|
||||
|
||||
private void OnNodeComplete(object sender, GameEventArgs e)
|
||||
@@ -145,8 +184,7 @@ namespace GeometryTD.Procedure
|
||||
snapshot = GameEntry.PlayerInventory.GetInventorySnapshot();
|
||||
}
|
||||
|
||||
AdvanceRunState(args.Succeeded, snapshot);
|
||||
OpenHubUI();
|
||||
HandleRunAdvanceResult(ProcedureMainRunFlowService.TryAdvanceRun(_currentRunState, args.Succeeded, snapshot));
|
||||
}
|
||||
|
||||
private void OnCombatFailureReturn(object sender, GameEventArgs e)
|
||||
@@ -159,8 +197,7 @@ namespace GeometryTD.Procedure
|
||||
BackpackInventoryData snapshot = GameEntry.PlayerInventory != null
|
||||
? GameEntry.PlayerInventory.GetInventorySnapshot()
|
||||
: null;
|
||||
AdvanceRunState(false, snapshot);
|
||||
OpenHubUI();
|
||||
HandleRunAdvanceResult(ProcedureMainRunFlowService.TryAdvanceRun(_currentRunState, false, snapshot));
|
||||
}
|
||||
|
||||
private void OnNodeMapNodeEnterRequested(object sender, GameEventArgs e)
|
||||
@@ -171,9 +208,15 @@ namespace GeometryTD.Procedure
|
||||
}
|
||||
|
||||
RunNodeState currentNode = _currentRunState?.CurrentNode;
|
||||
if (_currentRunState == null || !_currentRunState.CanEnterCurrentNode || currentNode == null)
|
||||
if (_currentRunState == null ||
|
||||
_flowPhase != ProcedureMainFlowPhase.Hub ||
|
||||
!_currentRunState.CanEnterCurrentNode ||
|
||||
currentNode == null)
|
||||
{
|
||||
Log.Warning("ProcedureMain.OnNodeMapNodeEnterRequested() ignored. Current run has no enterable node.");
|
||||
Log.Warning(
|
||||
"ProcedureMain.OnNodeMapNodeEnterRequested() ignored. FlowPhase={0}, HasEnterableNode={1}.",
|
||||
_flowPhase,
|
||||
_currentRunState != null && _currentRunState.CanEnterCurrentNode);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -226,33 +269,30 @@ namespace GeometryTD.Procedure
|
||||
}
|
||||
}
|
||||
|
||||
private void AdvanceRunState(bool succeeded, BackpackInventoryData snapshot)
|
||||
private void HandleRunAdvanceResult(ProcedureMainRunAdvanceResult result)
|
||||
{
|
||||
if (_currentRunState == null)
|
||||
switch (result)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RunStateAdvanceService.TryCompleteCurrentNode(_currentRunState, succeeded, snapshot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentRunState.IsCompleted)
|
||||
{
|
||||
Log.Info("ProcedureMain run completed. RunId={0}", _currentRunState.RunId);
|
||||
return;
|
||||
}
|
||||
|
||||
RunNodeState nextNode = _currentRunState.CurrentNode;
|
||||
if (nextNode != null)
|
||||
{
|
||||
Log.Info(
|
||||
"ProcedureMain advanced run. RunId={0}, NextNodeType={1}, SequenceIndex={2}, LevelId={3}.",
|
||||
_currentRunState.RunId,
|
||||
nextNode.NodeType,
|
||||
nextNode.SequenceIndex,
|
||||
nextNode.LinkedLevelId);
|
||||
case ProcedureMainRunAdvanceResult.NoChange:
|
||||
return;
|
||||
case ProcedureMainRunAdvanceResult.NodeFailed:
|
||||
Log.Info(
|
||||
"ProcedureMain current node failed. RunId={0}, NodeId={1}, NodeType={2}, SequenceIndex={3}.",
|
||||
_currentRunState?.RunId,
|
||||
_currentRunState?.CurrentNode?.NodeId ?? 0,
|
||||
_currentRunState?.CurrentNode?.NodeType ?? RunNodeType.None,
|
||||
_currentRunState?.CurrentNode?.SequenceIndex ?? -1);
|
||||
EnterHubFlow();
|
||||
return;
|
||||
case ProcedureMainRunAdvanceResult.AdvancedToNextNode:
|
||||
LogNextNode();
|
||||
EnterHubFlow();
|
||||
return;
|
||||
case ProcedureMainRunAdvanceResult.RunCompleted:
|
||||
EnterRunCompletedPendingFinish();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,11 +302,48 @@ namespace GeometryTD.Procedure
|
||||
GameEntry.PlayerInventory.GetParticipantTowerSnapshot().Count > 0;
|
||||
}
|
||||
|
||||
private void OpenHubUI()
|
||||
private void EnterHubFlow()
|
||||
{
|
||||
_flowPhase = ProcedureMainFlowPhase.Hub;
|
||||
_nodeMapFormUseCase?.SetRunState(_currentRunState);
|
||||
GameEntry.UIRouter.OpenUI(UIFormType.NodeMapForm);
|
||||
GameEntry.UIRouter.OpenUI(UIFormType.MainForm);
|
||||
}
|
||||
|
||||
private void EnterNodeFlow()
|
||||
{
|
||||
_flowPhase = ProcedureMainFlowPhase.NodeActive;
|
||||
CloseHubUI();
|
||||
}
|
||||
|
||||
private void EnterRunCompletedPendingFinish()
|
||||
{
|
||||
_flowPhase = ProcedureMainFlowPhase.RunCompletedPendingFinish;
|
||||
_nodeMapFormUseCase?.SetRunState(_currentRunState);
|
||||
CloseHubUI();
|
||||
Log.Info("ProcedureMain run completed. RunId={0}", _currentRunState?.RunId);
|
||||
}
|
||||
|
||||
private void CloseHubUI()
|
||||
{
|
||||
GameEntry.UIRouter.CloseUI(UIFormType.NodeMapForm);
|
||||
GameEntry.UIRouter.CloseUI(UIFormType.MainForm);
|
||||
}
|
||||
|
||||
private void LogNextNode()
|
||||
{
|
||||
RunNodeState nextNode = _currentRunState?.CurrentNode;
|
||||
if (nextNode == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Info(
|
||||
"ProcedureMain advanced run. RunId={0}, NextNodeType={1}, SequenceIndex={2}, LevelId={3}.",
|
||||
_currentRunState.RunId,
|
||||
nextNode.NodeType,
|
||||
nextNode.SequenceIndex,
|
||||
nextNode.LinkedLevelId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using GeometryTD.CustomEvent;
|
||||
using GeometryTD.Definition;
|
||||
using GeometryTD.Procedure;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GeometryTD.Tests.Editor
|
||||
{
|
||||
public sealed class RunStateTests
|
||||
{
|
||||
[Test]
|
||||
public void Factory_Creates_RunState_With_First_Node_Available()
|
||||
{
|
||||
BackpackInventoryData sourceInventory = new BackpackInventoryData
|
||||
{
|
||||
Gold = 120
|
||||
};
|
||||
sourceInventory.ParticipantTowerInstanceIds.Add(11);
|
||||
|
||||
RunState runState = RunStateFactory.Create(
|
||||
LevelThemeType.Plain,
|
||||
sourceInventory,
|
||||
new List<RunNodeSeed>
|
||||
{
|
||||
new RunNodeSeed { NodeType = RunNodeType.Combat, LinkedLevelId = 1 },
|
||||
new RunNodeSeed { NodeType = RunNodeType.Event },
|
||||
new RunNodeSeed { NodeType = RunNodeType.BossCombat, LinkedLevelId = 4 }
|
||||
},
|
||||
"run-test");
|
||||
|
||||
Assert.That(runState.RunId, Is.EqualTo("run-test"));
|
||||
Assert.That(runState.ThemeType, Is.EqualTo(LevelThemeType.Plain));
|
||||
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(0));
|
||||
Assert.That(runState.IsCompleted, Is.False);
|
||||
Assert.That(runState.Nodes.Count, Is.EqualTo(3));
|
||||
Assert.That(runState.Nodes[0].Status, Is.EqualTo(RunNodeStatus.Available));
|
||||
Assert.That(runState.Nodes[1].Status, Is.EqualTo(RunNodeStatus.Locked));
|
||||
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(120));
|
||||
|
||||
sourceInventory.Gold = 1;
|
||||
sourceInventory.ParticipantTowerInstanceIds[0] = 99;
|
||||
|
||||
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(120));
|
||||
Assert.That(runState.RunInventorySnapshot.ParticipantTowerInstanceIds[0], Is.EqualTo(11));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AdvanceService_Completes_Run_And_Unlocks_Next_Node()
|
||||
{
|
||||
RunState runState = RunStateFactory.Create(
|
||||
LevelThemeType.Plain,
|
||||
new BackpackInventoryData { Gold = 50 },
|
||||
new[]
|
||||
{
|
||||
new RunNodeSeed { NodeId = 101, NodeType = RunNodeType.Combat, LinkedLevelId = 1 },
|
||||
new RunNodeSeed { NodeId = 102, NodeType = RunNodeType.Shop },
|
||||
new RunNodeSeed { NodeId = 103, NodeType = RunNodeType.BossCombat, LinkedLevelId = 4 }
|
||||
});
|
||||
|
||||
bool firstCompleted = RunStateAdvanceService.TryCompleteCurrentNode(
|
||||
runState,
|
||||
true,
|
||||
new BackpackInventoryData { Gold = 80 });
|
||||
|
||||
Assert.That(firstCompleted, Is.True);
|
||||
Assert.That(runState.Nodes[0].Status, Is.EqualTo(RunNodeStatus.Completed));
|
||||
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(1));
|
||||
Assert.That(runState.Nodes[1].Status, Is.EqualTo(RunNodeStatus.Available));
|
||||
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(80));
|
||||
|
||||
RunStateAdvanceService.TryCompleteCurrentNode(runState, true, new BackpackInventoryData { Gold = 95 });
|
||||
RunStateAdvanceService.TryCompleteCurrentNode(runState, true, new BackpackInventoryData { Gold = 130 });
|
||||
|
||||
Assert.That(runState.IsCompleted, Is.True);
|
||||
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(3));
|
||||
Assert.That(runState.CompletedNodeCount, Is.EqualTo(3));
|
||||
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(130));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AdvanceService_Failure_Marks_Current_Node_Failed_Without_Completing_Run()
|
||||
{
|
||||
RunState runState = RunStateFactory.Create(
|
||||
LevelThemeType.Plain,
|
||||
new BackpackInventoryData { Gold = 20 },
|
||||
new[]
|
||||
{
|
||||
new RunNodeSeed { NodeType = RunNodeType.Combat }
|
||||
});
|
||||
|
||||
bool result = RunStateAdvanceService.TryCompleteCurrentNode(
|
||||
runState,
|
||||
false,
|
||||
new BackpackInventoryData { Gold = 5 });
|
||||
|
||||
Assert.That(result, Is.True);
|
||||
Assert.That(runState.IsCompleted, Is.False);
|
||||
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(0));
|
||||
Assert.That(runState.CurrentNode.Status, Is.EqualTo(RunNodeStatus.Failed));
|
||||
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(5));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NodeCompleteEventArgs_Clones_Inventory_And_Clears_State()
|
||||
{
|
||||
BackpackInventoryData inventory = new BackpackInventoryData { Gold = 66 };
|
||||
NodeCompleteEventArgs eventArgs = NodeCompleteEventArgs.Create(
|
||||
"run-1",
|
||||
7,
|
||||
RunNodeType.Shop,
|
||||
3,
|
||||
true,
|
||||
inventory);
|
||||
|
||||
inventory.Gold = 1;
|
||||
|
||||
Assert.That(eventArgs.RunId, Is.EqualTo("run-1"));
|
||||
Assert.That(eventArgs.NodeId, Is.EqualTo(7));
|
||||
Assert.That(eventArgs.NodeType, Is.EqualTo(RunNodeType.Shop));
|
||||
Assert.That(eventArgs.SequenceIndex, Is.EqualTo(3));
|
||||
Assert.That(eventArgs.Succeeded, Is.True);
|
||||
Assert.That(eventArgs.InventorySnapshotAfterNode.Gold, Is.EqualTo(66));
|
||||
|
||||
eventArgs.Clear();
|
||||
|
||||
Assert.That(eventArgs.RunId, Is.Null);
|
||||
Assert.That(eventArgs.NodeId, Is.EqualTo(0));
|
||||
Assert.That(eventArgs.NodeType, Is.EqualTo(RunNodeType.None));
|
||||
Assert.That(eventArgs.SequenceIndex, Is.EqualTo(-1));
|
||||
Assert.That(eventArgs.Succeeded, Is.False);
|
||||
Assert.That(eventArgs.InventorySnapshotAfterNode, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FixedRunNodeSequenceBuilder_Builds_Plain_Ten_Node_Sequence()
|
||||
{
|
||||
IReadOnlyList<RunNodeSeed> nodeSeeds = FixedRunNodeSequenceBuilder.Build(LevelThemeType.Plain);
|
||||
|
||||
Assert.That(nodeSeeds, Is.Not.Null);
|
||||
Assert.That(nodeSeeds.Count, Is.EqualTo(10));
|
||||
|
||||
Assert.That(nodeSeeds[0].NodeType, Is.EqualTo(RunNodeType.Combat));
|
||||
Assert.That(nodeSeeds[1].NodeType, Is.EqualTo(RunNodeType.Event));
|
||||
Assert.That(nodeSeeds[2].NodeType, Is.EqualTo(RunNodeType.Combat));
|
||||
Assert.That(nodeSeeds[3].NodeType, Is.EqualTo(RunNodeType.Shop));
|
||||
Assert.That(nodeSeeds[4].NodeType, Is.EqualTo(RunNodeType.Combat));
|
||||
Assert.That(nodeSeeds[5].NodeType, Is.EqualTo(RunNodeType.Event));
|
||||
Assert.That(nodeSeeds[6].NodeType, Is.EqualTo(RunNodeType.Combat));
|
||||
Assert.That(nodeSeeds[7].NodeType, Is.EqualTo(RunNodeType.Shop));
|
||||
Assert.That(nodeSeeds[8].NodeType, Is.EqualTo(RunNodeType.Event));
|
||||
Assert.That(nodeSeeds[9].NodeType, Is.EqualTo(RunNodeType.BossCombat));
|
||||
|
||||
Assert.That(nodeSeeds[0].LinkedLevelId, Is.EqualTo(1));
|
||||
Assert.That(nodeSeeds[2].LinkedLevelId, Is.EqualTo(2));
|
||||
Assert.That(nodeSeeds[4].LinkedLevelId, Is.EqualTo(3));
|
||||
Assert.That(nodeSeeds[6].LinkedLevelId, Is.EqualTo(1));
|
||||
Assert.That(nodeSeeds[9].LinkedLevelId, Is.EqualTo(4));
|
||||
Assert.That(nodeSeeds[1].LinkedLevelId, Is.EqualTo(0));
|
||||
Assert.That(nodeSeeds[3].LinkedLevelId, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FixedRunNodeSequenceBuilder_Returns_Empty_For_Unsupported_Theme()
|
||||
{
|
||||
IReadOnlyList<RunNodeSeed> nodeSeeds = FixedRunNodeSequenceBuilder.Build(LevelThemeType.Volcano);
|
||||
|
||||
Assert.That(nodeSeeds, Is.Not.Null);
|
||||
Assert.That(nodeSeeds.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateFixedRun_Creates_Ten_Node_Run_And_Completes_After_Ten_Advances()
|
||||
{
|
||||
RunState runState = RunStateFactory.CreateFixedRun(
|
||||
LevelThemeType.Plain,
|
||||
new BackpackInventoryData { Gold = 100 },
|
||||
"fixed-run");
|
||||
|
||||
Assert.That(runState.RunId, Is.EqualTo("fixed-run"));
|
||||
Assert.That(runState.NodeCount, Is.EqualTo(10));
|
||||
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(0));
|
||||
Assert.That(runState.CurrentNode.NodeType, Is.EqualTo(RunNodeType.Combat));
|
||||
Assert.That(runState.Nodes[0].Status, Is.EqualTo(RunNodeStatus.Available));
|
||||
Assert.That(runState.Nodes[9].Status, Is.EqualTo(RunNodeStatus.Locked));
|
||||
Assert.That(runState.GetNodeBySequenceIndex(9), Is.Not.Null);
|
||||
Assert.That(RunState.IsBossNode(runState.GetNodeBySequenceIndex(9)), Is.True);
|
||||
|
||||
for (int i = 0; i < runState.NodeCount; i++)
|
||||
{
|
||||
bool advanced = RunStateAdvanceService.TryCompleteCurrentNode(
|
||||
runState,
|
||||
true,
|
||||
new BackpackInventoryData { Gold = 100 + i });
|
||||
|
||||
Assert.That(advanced, Is.True);
|
||||
}
|
||||
|
||||
Assert.That(runState.IsCompleted, Is.True);
|
||||
Assert.That(runState.CompletedNodeCount, Is.EqualTo(10));
|
||||
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(10));
|
||||
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(109));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d3e6fd8ec274118b59f66c6efc41405
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user