初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器 HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块 Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚 AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RedCircuit.AIAssistant
|
||||
{
|
||||
/// <summary>
|
||||
/// 操作执行器,将 AI 操作指令转换为游戏内动作。
|
||||
/// 所有操作必须经用户确认后才执行,支持撤销。
|
||||
/// </summary>
|
||||
public class AIActionExecutor : MonoBehaviour
|
||||
{
|
||||
/// <summary>待确认的操作队列</summary>
|
||||
private readonly Queue<AIAction> _pendingQueue = new();
|
||||
|
||||
/// <summary>已执行的操作批次 (用于撤销)</summary>
|
||||
private readonly Stack<ActionBatch> _executedBatches = new();
|
||||
|
||||
/// <summary>单次操作元件上限</summary>
|
||||
private const int MaxActionsPerBatch = 20;
|
||||
|
||||
/// <summary>将 AI 操作加入待确认队列</summary>
|
||||
public void QueueActions(List<AIAction> actions)
|
||||
{
|
||||
if (actions.Count > MaxActionsPerBatch)
|
||||
{
|
||||
Debug.LogWarning($"[AIAction] 操作数 {actions.Count} 超过单批上限 {MaxActionsPerBatch},将截断");
|
||||
actions = actions.GetRange(0, MaxActionsPerBatch);
|
||||
}
|
||||
|
||||
foreach (var action in actions)
|
||||
{
|
||||
_pendingQueue.Enqueue(action);
|
||||
}
|
||||
|
||||
// TODO: 在画布上预览待执行操作 (半透明高亮)
|
||||
PreviewActions(actions);
|
||||
}
|
||||
|
||||
/// <summary>执行队列中所有待确认的操作</summary>
|
||||
public void ExecuteQueuedActions()
|
||||
{
|
||||
if (_pendingQueue.Count == 0) return;
|
||||
|
||||
// 记录操作前快照 (用于撤销)
|
||||
var batch = new ActionBatch();
|
||||
batch.SnapshotBefore = CaptureCanvasSnapshot();
|
||||
|
||||
while (_pendingQueue.TryDequeue(out var action))
|
||||
{
|
||||
ExecuteAction(action);
|
||||
batch.Actions.Add(action);
|
||||
}
|
||||
|
||||
batch.SnapshotAfter = CaptureCanvasSnapshot();
|
||||
_executedBatches.Push(batch);
|
||||
|
||||
Debug.Log($"[AIAction] 已执行 {batch.Actions.Count} 个操作");
|
||||
ClearPreviews();
|
||||
}
|
||||
|
||||
/// <summary>取消所有待确认的操作</summary>
|
||||
public void CancelQueuedActions()
|
||||
{
|
||||
var count = _pendingQueue.Count;
|
||||
_pendingQueue.Clear();
|
||||
ClearPreviews();
|
||||
Debug.Log($"[AIAction] 已取消 {count} 个待确认操作");
|
||||
}
|
||||
|
||||
/// <summary>撤销上一次 AI 操作批次</summary>
|
||||
public void UndoLastBatch()
|
||||
{
|
||||
if (!_executedBatches.TryPop(out var batch))
|
||||
{
|
||||
Debug.LogWarning("[AIAction] 没有可撤销的 AI 操作");
|
||||
return;
|
||||
}
|
||||
|
||||
// 恢复操作前快照
|
||||
RestoreCanvasSnapshot(batch.SnapshotBefore);
|
||||
Debug.Log($"[AIAction] 已撤销 {batch.Actions.Count} 个操作");
|
||||
}
|
||||
|
||||
private void ExecuteAction(AIAction action)
|
||||
{
|
||||
switch (action.Type)
|
||||
{
|
||||
case ActionType.Place:
|
||||
Debug.Log($"[AIAction] 放置 {action.Component} 于 ({action.X},{action.Y}) 旋转={action.Rotation}");
|
||||
// TODO: 调用 PlacementController.PlaceComponent()
|
||||
break;
|
||||
|
||||
case ActionType.Delete:
|
||||
Debug.Log($"[AIAction] 删除 ({action.X},{action.Y})");
|
||||
// TODO: 调用 PlacementController.DeleteComponent()
|
||||
break;
|
||||
|
||||
case ActionType.Move:
|
||||
Debug.Log($"[AIAction] 移动 ({action.FromX},{action.FromY}) -> ({action.X},{action.Y})");
|
||||
// TODO: 调用 PlacementController.MoveComponent()
|
||||
break;
|
||||
|
||||
case ActionType.Rotate:
|
||||
Debug.Log($"[AIAction] 旋转 ({action.X},{action.Y}) -> {action.Rotation}");
|
||||
// TODO: 调用 PlacementController.RotateComponent()
|
||||
break;
|
||||
|
||||
case ActionType.Wire:
|
||||
Debug.Log($"[AIAction] 连线 ({action.FromX},{action.FromY}) -> ({action.X},{action.Y})");
|
||||
// TODO: 调用 PlacementController.PlaceWire()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void PreviewActions(List<AIAction> actions)
|
||||
{
|
||||
// TODO: 在画布上以半透明预览所有待执行操作
|
||||
foreach (var action in actions)
|
||||
{
|
||||
// 创建预览 Ghost 对象
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearPreviews()
|
||||
{
|
||||
// TODO: 清除所有预览 Ghost 对象
|
||||
}
|
||||
|
||||
private string CaptureCanvasSnapshot()
|
||||
{
|
||||
// TODO: 序列化当前画布状态为 JSON
|
||||
return "{}";
|
||||
}
|
||||
|
||||
private void RestoreCanvasSnapshot(string snapshot)
|
||||
{
|
||||
// TODO: 从 JSON 快照恢复画布状态
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RedCircuit.AIAssistant
|
||||
{
|
||||
/// <summary>
|
||||
/// AI 助搭核心协调器,管理 AI 会话生命周期,协调各子系统。
|
||||
/// </summary>
|
||||
public class AIAssistantManager : MonoBehaviour
|
||||
{
|
||||
public static AIAssistantManager Instance { get; private set; }
|
||||
|
||||
/// <summary>当前会话 ID</summary>
|
||||
public string SessionId { get; private set; } = Guid.NewGuid().ToString("N")[..16];
|
||||
|
||||
/// <summary>AI 是否就绪</summary>
|
||||
public bool IsReady { get; private set; }
|
||||
|
||||
/// <summary>聊天历史记录</summary>
|
||||
public List<ChatMessage> History { get; } = new();
|
||||
|
||||
private AIChatController _chatController;
|
||||
private AICircuitAdvisor _advisor;
|
||||
private AIActionExecutor _executor;
|
||||
private AIContextProvider _contextProvider;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null) { Destroy(gameObject); return; }
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_chatController = GetComponent<AIChatController>() ?? gameObject.AddComponent<AIChatController>();
|
||||
_advisor = GetComponent<AICircuitAdvisor>() ?? gameObject.AddComponent<AICircuitAdvisor>();
|
||||
_executor = GetComponent<AIActionExecutor>() ?? gameObject.AddComponent<AIActionExecutor>();
|
||||
_contextProvider = GetComponent<AIContextProvider>() ?? gameObject.AddComponent<AIContextProvider>();
|
||||
|
||||
IsReady = true;
|
||||
Debug.Log("[AIAssistant] Manager initialized");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理用户输入的消息。
|
||||
/// </summary>
|
||||
public async void HandleUserMessage(string message)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
_chatController.AppendSystemMessage("AI 助手尚未就绪,请稍候...");
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录用户消息
|
||||
History.Add(new ChatMessage { Role = MessageRole.User, Content = message, Timestamp = DateTime.Now });
|
||||
_chatController.AppendUserMessage(message);
|
||||
|
||||
// 采集上下文
|
||||
var context = _contextProvider.CollectContext();
|
||||
|
||||
// 发送到服务端 (TODO: 实现网络请求)
|
||||
var response = await RequestAIChat(message, context);
|
||||
|
||||
// 处理响应
|
||||
ProcessAIResponse(response);
|
||||
}
|
||||
|
||||
private async Task<AIResponse> RequestAIChat(string message, GameContext context)
|
||||
{
|
||||
// TODO: 调用 ai-service POST /api/ai/chat
|
||||
// 使用 SSE 流式接收响应
|
||||
await Task.Delay(100); // 模拟网络延迟
|
||||
return new AIResponse
|
||||
{
|
||||
Type = ResponseType.Text,
|
||||
Content = "AI 助搭功能正在开发中,敬请期待!",
|
||||
Actions = new List<AIAction>(),
|
||||
RequiresConfirmation = false
|
||||
};
|
||||
}
|
||||
|
||||
private void ProcessAIResponse(AIResponse response)
|
||||
{
|
||||
// 记录 AI 消息
|
||||
History.Add(new ChatMessage { Role = MessageRole.Assistant, Content = response.Content, Timestamp = DateTime.Now });
|
||||
|
||||
switch (response.Type)
|
||||
{
|
||||
case ResponseType.Text:
|
||||
_chatController.AppendAIMessage(response.Content);
|
||||
break;
|
||||
|
||||
case ResponseType.Analysis:
|
||||
_chatController.AppendAIMessage(response.Content);
|
||||
_advisor.ShowReport(response.Analysis);
|
||||
break;
|
||||
|
||||
case ResponseType.Action:
|
||||
_chatController.AppendAIMessage(response.Content);
|
||||
if (response.RequiresConfirmation && response.Actions.Count > 0)
|
||||
{
|
||||
_executor.QueueActions(response.Actions);
|
||||
_chatController.ShowConfirmationPrompt(response.Actions.Count);
|
||||
}
|
||||
break;
|
||||
|
||||
case ResponseType.Error:
|
||||
_chatController.AppendErrorMessage(response.Content);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>用户确认执行 AI 操作</summary>
|
||||
public void ConfirmActions()
|
||||
{
|
||||
_executor.ExecuteQueuedActions();
|
||||
}
|
||||
|
||||
/// <summary>用户拒绝执行 AI 操作</summary>
|
||||
public void RejectActions()
|
||||
{
|
||||
_executor.CancelQueuedActions();
|
||||
}
|
||||
|
||||
/// <summary>撤销上一次 AI 操作</summary>
|
||||
public void UndoLastAIAction()
|
||||
{
|
||||
_executor.UndoLastBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RedCircuit.AIAssistant
|
||||
{
|
||||
/// <summary>
|
||||
/// 聊天 UI 控制器,处理消息收发与流式显示。
|
||||
/// </summary>
|
||||
public class AIChatController : MonoBehaviour
|
||||
{
|
||||
/// <summary>聊天面板是否可见</summary>
|
||||
public bool IsVisible { get; private set; }
|
||||
|
||||
/// <summary>消息列表 (用于 UI 渲染)</summary>
|
||||
public List<ChatMessage> Messages { get; } = new();
|
||||
|
||||
/// <summary>显示聊天面板</summary>
|
||||
public void Show()
|
||||
{
|
||||
IsVisible = true;
|
||||
// TODO: 播放面板展开动画
|
||||
}
|
||||
|
||||
/// <summary>隐藏聊天面板</summary>
|
||||
public void Hide()
|
||||
{
|
||||
IsVisible = false;
|
||||
// TODO: 播放面板收起动画
|
||||
}
|
||||
|
||||
/// <summary>追加用户消息到 UI</summary>
|
||||
public void AppendUserMessage(string content)
|
||||
{
|
||||
var msg = new ChatMessage
|
||||
{
|
||||
Role = MessageRole.User,
|
||||
Content = content,
|
||||
Timestamp = DateTime.Now
|
||||
};
|
||||
Messages.Add(msg);
|
||||
// TODO: 实例化用户消息气泡 UI
|
||||
}
|
||||
|
||||
/// <summary>追加 AI 消息到 UI (支持流式追加)</summary>
|
||||
public void AppendAIMessage(string content)
|
||||
{
|
||||
var msg = new ChatMessage
|
||||
{
|
||||
Role = MessageRole.Assistant,
|
||||
Content = content,
|
||||
Timestamp = DateTime.Now
|
||||
};
|
||||
Messages.Add(msg);
|
||||
// TODO: 实例化 AI 消息气泡 UI,支持打字机效果
|
||||
}
|
||||
|
||||
/// <summary>追加系统消息</summary>
|
||||
public void AppendSystemMessage(string content)
|
||||
{
|
||||
var msg = new ChatMessage
|
||||
{
|
||||
Role = MessageRole.System,
|
||||
Content = content,
|
||||
Timestamp = DateTime.Now
|
||||
};
|
||||
Messages.Add(msg);
|
||||
// TODO: 实例化系统消息 (居中灰色样式)
|
||||
}
|
||||
|
||||
/// <summary>追加错误消息</summary>
|
||||
public void AppendErrorMessage(string content)
|
||||
{
|
||||
AppendSystemMessage($"[错误] {content}");
|
||||
}
|
||||
|
||||
/// <summary>显示操作确认提示</summary>
|
||||
public void ShowConfirmationPrompt(int actionCount)
|
||||
{
|
||||
// TODO: 显示 "AI 建议执行 N 个操作,是否确认?" 确认栏
|
||||
Debug.Log($"[AIChat] 等待用户确认 {actionCount} 个操作");
|
||||
}
|
||||
|
||||
/// <summary>清空聊天记录</summary>
|
||||
public void ClearHistory()
|
||||
{
|
||||
Messages.Clear();
|
||||
// TODO: 清空 UI 消息列表
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RedCircuit.AIAssistant
|
||||
{
|
||||
/// <summary>
|
||||
/// 电路分析与建议,解析 AI 返回的电路方案并展示诊断报告。
|
||||
/// </summary>
|
||||
public class AICircuitAdvisor : MonoBehaviour
|
||||
{
|
||||
/// <summary>显示电路分析报告</summary>
|
||||
public void ShowReport(CircuitAnalysisReport report)
|
||||
{
|
||||
if (report == null) return;
|
||||
|
||||
Debug.Log($"[AIAdvisor] 电路分析: {report.Summary}");
|
||||
Debug.Log($"[AIAdvisor] 元件数: {report.Metrics.ComponentCount}, 成本: {report.Metrics.TotalCost}, 最大延迟: {report.Metrics.MaxDelay} tick");
|
||||
|
||||
foreach (var issue in report.Issues)
|
||||
{
|
||||
var icon = issue.Severity == IssueSeverity.Error ? "[ERROR]" : "[WARN]";
|
||||
Debug.Log($"[AIAdvisor] {icon} ({issue.Location.X},{issue.Location.Y}) {issue.Description}");
|
||||
if (!string.IsNullOrEmpty(issue.Suggestion))
|
||||
Debug.Log($"[AIAdvisor] -> 建议: {issue.Suggestion}");
|
||||
}
|
||||
|
||||
foreach (var opt in report.Optimizations)
|
||||
{
|
||||
Debug.Log($"[AIAdvisor] [OPT] {opt.Description} ({opt.EstimatedImprovement})");
|
||||
}
|
||||
|
||||
// TODO: 在 UI 上展示分析报告面板
|
||||
}
|
||||
|
||||
/// <summary>显示电路搭建方案供用户选择</summary>
|
||||
public void ShowCircuitPlan(List<CircuitPlan> plans)
|
||||
{
|
||||
foreach (var plan in plans)
|
||||
{
|
||||
Debug.Log($"[AIAdvisor] 方案: {plan.Name} | 成本: {plan.Cost} | 延迟: {plan.Delay} tick | 元件: {plan.ComponentCount}");
|
||||
Debug.Log($"[AIAdvisor] {plan.Description}");
|
||||
}
|
||||
// TODO: 在 UI 上展示方案对比卡片
|
||||
}
|
||||
|
||||
/// <summary>高亮显示问题位置</summary>
|
||||
public void HighlightIssue(GridPosition location, IssueSeverity severity)
|
||||
{
|
||||
// TODO: 在画布上高亮显示问题格子
|
||||
// Error -> 红色边框, Warning -> 黄色边框
|
||||
}
|
||||
|
||||
/// <summary>清除所有高亮</summary>
|
||||
public void ClearHighlights()
|
||||
{
|
||||
// TODO: 移除画布上的所有问题高亮
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RedCircuit.AIAssistant
|
||||
{
|
||||
/// <summary>
|
||||
/// 上下文采集器,收集当前游戏状态供 AI 参考。
|
||||
/// </summary>
|
||||
public class AIContextProvider : MonoBehaviour
|
||||
{
|
||||
/// <summary>采集当前游戏上下文</summary>
|
||||
public GameContext CollectContext()
|
||||
{
|
||||
var context = new GameContext
|
||||
{
|
||||
Mode = GetCurrentMode(),
|
||||
CanvasWidth = GetCanvasWidth(),
|
||||
CanvasHeight = GetCanvasHeight(),
|
||||
ComponentCount = GetComponentCount(),
|
||||
SelectedComponentId = GetSelectedComponentId(),
|
||||
SelectedComponentType = GetSelectedComponentType(),
|
||||
LevelId = GetCurrentLevelId(),
|
||||
LevelTitle = GetCurrentLevelTitle(),
|
||||
RedstoneCoins = GetRedstoneCoins()
|
||||
};
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
private string GetCurrentMode()
|
||||
{
|
||||
// TODO: 从 GameManager 获取当前游戏模式
|
||||
return "creative"; // creative / puzzle / automation / multiplayer
|
||||
}
|
||||
|
||||
private int GetCanvasWidth()
|
||||
{
|
||||
// TODO: 从 GridCanvas 获取画布宽度
|
||||
return 128;
|
||||
}
|
||||
|
||||
private int GetCanvasHeight()
|
||||
{
|
||||
// TODO: 从 GridCanvas 获取画布高度
|
||||
return 128;
|
||||
}
|
||||
|
||||
private int GetComponentCount()
|
||||
{
|
||||
// TODO: 从 CircuitGraph 获取当前元件数
|
||||
return 0;
|
||||
}
|
||||
|
||||
private string GetSelectedComponentId()
|
||||
{
|
||||
// TODO: 从 PlacementController 获取选中元件 ID
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetSelectedComponentType()
|
||||
{
|
||||
// TODO: 从 PlacementController 获取选中元件类型
|
||||
return null;
|
||||
}
|
||||
|
||||
private int? GetCurrentLevelId()
|
||||
{
|
||||
// TODO: 解谜模式下获取当前关卡 ID
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetCurrentLevelTitle()
|
||||
{
|
||||
// TODO: 解谜模式下获取当前关卡标题
|
||||
return null;
|
||||
}
|
||||
|
||||
private long GetRedstoneCoins()
|
||||
{
|
||||
// TODO: 从 EconomyManager 获取红石币余额
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RedCircuit.AIAssistant
|
||||
{
|
||||
// ==================== 消息模型 ====================
|
||||
|
||||
public enum MessageRole { User, Assistant, System }
|
||||
|
||||
[Serializable]
|
||||
public class ChatMessage
|
||||
{
|
||||
public MessageRole Role;
|
||||
public string Content;
|
||||
public DateTime Timestamp;
|
||||
}
|
||||
|
||||
// ==================== 响应模型 ====================
|
||||
|
||||
public enum ResponseType { Text, Analysis, Action, Error }
|
||||
|
||||
[Serializable]
|
||||
public class AIResponse
|
||||
{
|
||||
public ResponseType Type;
|
||||
public string Content;
|
||||
public List<AIAction> Actions = new();
|
||||
public bool RequiresConfirmation;
|
||||
public CircuitAnalysisReport Analysis;
|
||||
}
|
||||
|
||||
// ==================== 操作指令模型 ====================
|
||||
|
||||
public enum ActionType { Place, Delete, Move, Rotate, Wire }
|
||||
|
||||
[Serializable]
|
||||
public class AIAction
|
||||
{
|
||||
public ActionType Type;
|
||||
public string Component; // 元件类型 (Place 时使用)
|
||||
public int X; // 目标 X 坐标
|
||||
public int Y; // 目标 Y 坐标
|
||||
public int FromX; // 源 X 坐标 (Move/Wire 时使用)
|
||||
public int FromY; // 源 Y 坐标 (Move/Wire 时使用)
|
||||
public int Rotation; // 旋转角度 (0/90/180/270)
|
||||
public string Description; // 操作描述 (供用户确认时显示)
|
||||
}
|
||||
|
||||
// ==================== 上下文模型 ====================
|
||||
|
||||
[Serializable]
|
||||
public class GameContext
|
||||
{
|
||||
public string Mode; // creative / puzzle / automation / multiplayer
|
||||
public int CanvasWidth;
|
||||
public int CanvasHeight;
|
||||
public int ComponentCount;
|
||||
public string SelectedComponentId;
|
||||
public string SelectedComponentType;
|
||||
public int? LevelId;
|
||||
public string LevelTitle;
|
||||
public long RedstoneCoins;
|
||||
}
|
||||
|
||||
// ==================== 电路分析模型 ====================
|
||||
|
||||
[Serializable]
|
||||
public class CircuitAnalysisReport
|
||||
{
|
||||
public string Summary;
|
||||
public CircuitMetrics Metrics;
|
||||
public List<CircuitIssue> Issues = new();
|
||||
public List<CircuitOptimization> Optimizations = new();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CircuitMetrics
|
||||
{
|
||||
public int ComponentCount;
|
||||
public int TotalCost;
|
||||
public int MaxDelay;
|
||||
public int SignalPaths;
|
||||
}
|
||||
|
||||
public enum IssueSeverity { Error, Warning, Info }
|
||||
|
||||
[Serializable]
|
||||
public class CircuitIssue
|
||||
{
|
||||
public IssueSeverity Severity;
|
||||
public string Type; // signal_loss / short_circuit / redundant / etc.
|
||||
public GridPosition Location;
|
||||
public string Description;
|
||||
public string Suggestion;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CircuitOptimization
|
||||
{
|
||||
public string Type; // delay_reduction / cost_reduction / etc.
|
||||
public string Description;
|
||||
public string EstimatedImprovement;
|
||||
}
|
||||
|
||||
// ==================== 电路方案模型 ====================
|
||||
|
||||
[Serializable]
|
||||
public class CircuitPlan
|
||||
{
|
||||
public string Name;
|
||||
public string Description;
|
||||
public int Cost;
|
||||
public int Delay;
|
||||
public int ComponentCount;
|
||||
public List<AIAction> Steps = new();
|
||||
}
|
||||
|
||||
// ==================== 辅助类型 ====================
|
||||
|
||||
[Serializable]
|
||||
public struct GridPosition
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
|
||||
public GridPosition(int x, int y) { X = x; Y = y; }
|
||||
}
|
||||
|
||||
/// <summary>操作批次 (用于撤销)</summary>
|
||||
public class ActionBatch
|
||||
{
|
||||
public List<AIAction> Actions = new();
|
||||
public string SnapshotBefore;
|
||||
public string SnapshotAfter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "RedCircuit.AIAssistant",
|
||||
"rootNamespace": "RedCircuit.AIAssistant",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": []
|
||||
}
|
||||
Reference in New Issue
Block a user