聊天记录展示

This commit is contained in:
2025-10-15 18:55:01 +08:00
parent d984cb1457
commit 5714ae08bb
8 changed files with 285 additions and 137 deletions
+26 -14
View File
@@ -138,11 +138,11 @@ export class ChatController {
if (roleId && roleId > 0) { if (roleId && roleId > 0) {
ChatAIService.Instance.setCurrentRole(roleId); ChatAIService.Instance.setCurrentRole(roleId);
// 从ChatHistoryManager加载对话记录到ChatModel中 // 从ChatHistoryManager加载最近10条对话记录到ChatModel中
this.loadDialogsFromHistory(roleId); this.loadDialogsFromHistory(roleId, 10);
// 同步到DialogManager // 同步对话数据到DialogManager和UI
//this.syncDialogData(); this.syncDialogData();
logger.log(`ChatController initialized with role ${roleId}`); logger.log(`ChatController initialized with role ${roleId}`);
} else { } else {
@@ -165,15 +165,15 @@ export class ChatController {
return false; return false;
} }
// 更新AI服务的当前角色 // 更新AI服务的当前角色
ChatAIService.Instance.setCurrentRole(roleId); ChatAIService.Instance.setCurrentRole(roleId);
// 从ChatHistoryManager加载对话记录到ChatModel中 // 从ChatHistoryManager加载最近10条对话记录到ChatModel中
this.loadDialogsFromHistory(roleId); this.loadDialogsFromHistory(roleId, 10);
// 同步对话数据到DialogManager // 同步对话数据到DialogManager和UI
//this.syncDialogData(); this.syncDialogData();
logger.log(`ChatController switched to role ${roleId}`); logger.log(`ChatController switched to role ${roleId}`);
return true; return true;
@@ -371,8 +371,9 @@ export class ChatController {
/** /**
* 从ChatHistoryManager加载对话记录到ChatModel中 * 从ChatHistoryManager加载对话记录到ChatModel中
* @param roleId 角色ID,不传则使用当前角色 * @param roleId 角色ID,不传则使用当前角色
* @param limit 加载消息数量限制,默认10条(0表示加载全部)
*/ */
public loadDialogsFromHistory(roleId?: number): void { public loadDialogsFromHistory(roleId?: number, limit: number = 10): void {
const targetRoleId = roleId || this.chatModel.getCurrentRoleId(); const targetRoleId = roleId || this.chatModel.getCurrentRoleId();
if (!targetRoleId) { if (!targetRoleId) {
logger.warn("Cannot load dialogs: no active role"); logger.warn("Cannot load dialogs: no active role");
@@ -380,7 +381,15 @@ export class ChatController {
} }
// 从ChatHistoryManager加载聊天记录 // 从ChatHistoryManager加载聊天记录
const chatHistory = ChatHistoryManager.Instance.loadHistory(targetRoleId); let chatHistory = ChatHistoryManager.Instance.loadHistory(targetRoleId);
// 如果设置了限制,只取最近的N条消息
if (limit > 0 && chatHistory.length > limit) {
chatHistory = chatHistory.slice(-limit);
logger.log(
`Limited chat history to recent ${limit} messages for role ${targetRoleId}`
);
}
// 清空ChatModel中的对话记录 // 清空ChatModel中的对话记录
this.chatModel.clearDialogs(targetRoleId); this.chatModel.clearDialogs(targetRoleId);
@@ -398,8 +407,8 @@ export class ChatController {
} }
/** /**
* 同步ChatModel的对话数据到DialogManager * 同步ChatModel的对话数据到DialogManager和UI
* 用于确保DialogManager和ChatModel的数据一致性 * 用于确保DialogManager和ChatModel的数据一致性,并更新UI显示
*/ */
public syncDialogData(): void { public syncDialogData(): void {
if (!this.dialogManager || !this.chatModel.validate()) { if (!this.dialogManager || !this.chatModel.validate()) {
@@ -410,7 +419,10 @@ export class ChatController {
} }
const dialogs = this.chatModel.getDialogs(); const dialogs = this.chatModel.getDialogs();
this.dialogManager.syncFromChatModel(dialogs);
// 使用loadHistoryDialogs方法加载历史对话到DialogManager
this.dialogManager.loadHistoryDialogs(dialogs);
logger.log( logger.log(
`Synced ${dialogs.length} dialogs from ChatModel to DialogManager` `Synced ${dialogs.length} dialogs from ChatModel to DialogManager`
); );
+37 -13
View File
@@ -4,12 +4,11 @@ export interface Dialog {
} }
export class DiaLogData { export class DiaLogData {
public playerDialog: Dialog = null; // 统一的对话数组,保存所有历史对话
public aiDialogs: Dialog[] = []; private dialogs: Dialog[] = [];
public cleanDialog() { public cleanDialog() {
this.playerDialog = null; this.dialogs = [];
this.aiDialogs = [];
} }
public pushDialog( public pushDialog(
@@ -17,17 +16,42 @@ export class DiaLogData {
str: string, str: string,
isLoading: boolean = false isLoading: boolean = false
) { ) {
if (isPlayer) { // 追加新对话到数组末尾
this.playerDialog = { isPlayer: true, content: str }; this.dialogs.push({ isPlayer, content: str });
} else {
this.aiDialogs.push({ isPlayer: false, content: str });
}
} }
public GetPlayerDialog() { /**
return this.playerDialog; * 获取最后一条玩家对话(兼容旧接口)
*/
public GetPlayerDialog(): Dialog | null {
// 从后往前查找最后一条玩家消息
for (let i = this.dialogs.length - 1; i >= 0; i--) {
if (this.dialogs[i].isPlayer) {
return this.dialogs[i];
}
}
return null;
} }
public GetAIDialog() {
return this.aiDialogs; /**
* 获取所有AI对话(兼容旧接口)
*/
public GetAIDialog(): Dialog[] {
// 返回所有AI消息
return this.dialogs.filter(dialog => !dialog.isPlayer);
}
/**
* 获取所有对话记录
*/
public getAllDialogs(): Dialog[] {
return [...this.dialogs];
}
/**
* 批量设置对话记录(用于加载历史)
*/
public setDialogs(dialogs: Dialog[]): void {
this.dialogs = [...dialogs];
} }
} }
@@ -44,16 +44,14 @@ export class DialogManager {
* *
* @param {boolean} isPlayer - 是否为玩家消息 * @param {boolean} isPlayer - 是否为玩家消息
* @param {string} str - 消息内容 * @param {string} str - 消息内容
* @param {boolean} fromPlayer - 是否来自玩家输入(用于清理对话 * @param {boolean} fromPlayer - 是否来自玩家输入(已废弃,保留参数兼容性
*/ */
public updateDialog( public updateDialog(
isPlayer: boolean, isPlayer: boolean,
str: string, str: string,
fromPlayer: boolean = false fromPlayer: boolean = false
): void { ): void {
if (fromPlayer) { // 移除清空逻辑,改为追加模式以支持历史记录显示
this.dialogData.cleanDialog();
}
this.dialogData.pushDialog(isPlayer, str); this.dialogData.pushDialog(isPlayer, str);
} }
@@ -62,16 +60,14 @@ export class DialogManager {
* *
* @param {boolean} isPlayer - 是否为玩家消息 * @param {boolean} isPlayer - 是否为玩家消息
* @param {string} str - 消息内容 * @param {string} str - 消息内容
* @param {boolean} fromPlayer - 是否来自玩家输入(用于清理对话 * @param {boolean} fromPlayer - 是否来自玩家输入(已废弃,保留参数兼容性
*/ */
public updateDialogWithSegments( public updateDialogWithSegments(
isPlayer: boolean, isPlayer: boolean,
str: string, str: string,
fromPlayer: boolean = false fromPlayer: boolean = false
): void { ): void {
if (fromPlayer) { // 移除清空逻辑,改为追加模式以支持历史记录显示
this.dialogData.cleanDialog();
}
// 如果是玩家消息,直接添加单个气泡 // 如果是玩家消息,直接添加单个气泡
if (isPlayer) { if (isPlayer) {
@@ -182,4 +178,43 @@ export class DialogManager {
logger.log("DialogManager: Synced dialogs from ChatModel"); logger.log("DialogManager: Synced dialogs from ChatModel");
} }
/**
* 加载历史对话记录(用于初始化显示)
* @param dialogs 历史对话数组
*/
public loadHistoryDialogs(dialogs: Dialog[]): void {
// 清空当前对话
this.dialogData.cleanDialog();
// 遍历历史对话,对AI消息进行分段处理
let totalSegments = 0;
dialogs.forEach((dialog) => {
if (dialog.isPlayer) {
// 玩家消息直接添加
this.dialogData.pushDialog(dialog.isPlayer, dialog.content);
totalSegments++;
} else {
// AI消息进行分段处理
const segments = this.splitMessageIntoSegments(dialog.content);
if (segments.length <= 1) {
// 单段消息直接添加
this.dialogData.pushDialog(dialog.isPlayer, dialog.content);
totalSegments++;
} else {
// 多段消息,每段作为独立气泡
segments.forEach((segment) => {
this.dialogData.pushDialog(dialog.isPlayer, segment);
totalSegments++;
});
}
}
});
logger.log(
`DialogManager: Loaded ${dialogs.length} history dialogs (expanded to ${totalSegments} segments)`
);
// 通知UI更新
Utils.sendInnerMsg(InnerMsgCode.Chat_DialogRefresh);
}
} }
@@ -43,13 +43,16 @@ export class ChatContentsLayout extends Component {
private isPressing: boolean = false; private isPressing: boolean = false;
// 长按计时器 // 长按计时器
private longPressTimer: number = null; private longPressTimer: number = null;
// 已显示的AI对话数量(用于避免重复显示)
private displayedAIDialogCount: number = 0;
fixMaxWidth: number; fixMaxWidth: number;
protected start(): void { protected start(): void {
this.lBubble.node.active = false; this.lBubble.node.active = false;
this.rBubble.node.active = false; this.rBubble.node.active = false;
this.fixMaxWidth = 534.4; // 设置气泡最大宽度为屏幕宽度的70%
this.fixMaxWidth = view.getVisibleSize().width * 0.7;
// 获取或添加UIOpacity组件到content节点 // 获取或添加UIOpacity组件到content节点
this.contentOpacity = this.contentOpacity =
@@ -77,37 +80,44 @@ export class ChatContentsLayout extends Component {
} }
/** /**
* 更新玩家输入的对话 * 更新玩家输入的对话(追加模式,不清空历史)
* @param dialog 玩家输入的对话数据 * @param dialog 玩家输入的对话数据
*/ */
updatePlayerDialog(dialog: Dialog): void { updatePlayerDialog(dialog: Dialog): void {
// 清理所有现有气泡到缓存池 if (!dialog) return;
this.clearAllBubbles();
// 清理所有延时任务 // 不再清空气泡,改为追加模式以支持历史记录
this.clearDelayedTasks();
// 创建玩家气泡(插入到首位,Layout会让它显示在最下面) // 创建玩家气泡
const playerBubble = this.createOrGetBubble(true); const playerBubble = this.createOrGetBubble(true);
playerBubble.node.active = true; playerBubble.node.active = true;
playerBubble.updateBubbleContent(dialog.content, true); playerBubble.updateBubbleContent(dialog.content, true);
this.bubbles.push(playerBubble); this.bubbles.push(playerBubble);
// 滚动到底部
this.scheduleOnce(() => {
this.scrollView.scrollToBottom();
}, 0);
} }
/** /**
* 更新AI回复的对话 * 更新AI回复的对话(智能追加,避免重复显示)
* @param dialogs AI回复的对话数据数组 * @param dialogs AI回复的对话数据数组
*/ */
updateAIDialogs(dialogs: Dialog[]): void { updateAIDialogs(dialogs: Dialog[]): void {
// 清除等待回复气泡 if (!dialogs || dialogs.length === 0) return;
// if (this.waitingBubble) {
// this.removeWaitingBubble();
// }
// 清理之前的延时任务 // 清理之前的延时任务
this.clearDelayedTasks(); this.clearDelayedTasks();
// 逐个添加AI对话,带延时 // 只添加新的AI对话(避免重复显示历史记录)
this.addAIDialogsWithDelay(dialogs, 0); const newDialogs = dialogs.slice(this.displayedAIDialogCount);
if (newDialogs.length > 0) {
// 更新已显示数量
this.displayedAIDialogCount = dialogs.length;
// 逐个添加新的AI对话,带延时
this.addAIDialogsWithDelay(newDialogs, 0);
}
this.node.position = Vec3.ZERO; this.node.position = Vec3.ZERO;
// 滚动到底部(等待下一帧Layout更新完成) // 滚动到底部(等待下一帧Layout更新完成)
@@ -117,9 +127,9 @@ export class ChatContentsLayout extends Component {
} }
/** /**
* 清理所有气泡到缓存池 * 清理所有气泡到缓存池(改为public,供外部调用)
*/ */
private clearAllBubbles(): void { public clearAllBubbles(): void {
for (const bubble of this.bubbles) { for (const bubble of this.bubbles) {
if (bubble && bubble.node) { if (bubble && bubble.node) {
bubble.node.active = false; bubble.node.active = false;
@@ -129,10 +139,48 @@ export class ChatContentsLayout extends Component {
this.bubbles = []; this.bubbles = [];
//this.waitingBubble = null; //this.waitingBubble = null;
// 重置AI对话计数器
this.displayedAIDialogCount = 0;
// 清理多余的缓存气泡 // 清理多余的缓存气泡
this.cleanupExcessCachedBubbles(); this.cleanupExcessCachedBubbles();
} }
/**
* 加载所有历史对话(用于初始化)
* @param dialogs 所有对话记录
*/
public loadAllDialogs(dialogs: Dialog[]): void {
if (!dialogs || dialogs.length === 0) return;
// 清空现有气泡
this.clearAllBubbles();
this.clearDelayedTasks();
// 倒序遍历对话,从最后一个开始插入(保持正确的显示顺序)
for (let i = dialogs.length - 1; i >= 0; i--) {
const dialog = dialogs[i];
const bubble = this.createOrGetBubble(dialog.isPlayer);
bubble.node.active = true;
bubble.updateBubbleContent(dialog.content, dialog.isPlayer);
// 每个气泡插入到首位,确保旧消息在上面,新消息在下面
bubble.node.setSiblingIndex(0);
this.bubbles.push(bubble);
// 统计AI对话数量
if (!dialog.isPlayer) {
this.displayedAIDialogCount++;
}
}
// 滚动到底部
this.scheduleOnce(() => {
this.scrollView.scrollToBottom();
}, 0.1);
console.log(`ChatContentsLayout: Loaded ${dialogs.length} history dialogs`);
}
/** /**
* 从缓存池获取或创建新的气泡 * 从缓存池获取或创建新的气泡
* @param isPlayer 是否为玩家气泡 * @param isPlayer 是否为玩家气泡
@@ -198,12 +246,12 @@ export class ChatContentsLayout extends Component {
const aiBubble = this.createOrGetBubble(false); const aiBubble = this.createOrGetBubble(false);
aiBubble.node.active = true; aiBubble.node.active = true;
aiBubble.updateBubbleContent(dialog.content, false); aiBubble.updateBubbleContent(dialog.content, false);
// AI消息插入到首位,显示在最上面 // AI消息自然追加到末尾,显示在最下面(与玩家消息保持一致)
aiBubble.node.setSiblingIndex(0); this.bubbles.push(aiBubble);
this.scheduleOnce(() => { this.scheduleOnce(() => {
this.scrollView.scrollToBottom(); this.scrollView.scrollToBottom();
}, 0); }, 0);
this.bubbles.push(aiBubble);
// 递归处理下一条对话 // 递归处理下一条对话
this.addAIDialogsWithDelay(dialogs, index + 1); this.addAIDialogsWithDelay(dialogs, index + 1);
@@ -129,6 +129,12 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
this, this,
this.onChatCountChange this.onChatCountChange
); );
Utils.addInnerEL(
InnerMsgCode.Chat_DialogRefresh,
this,
this.onDialogRefresh
);
} }
onDestroy(): void { onDestroy(): void {
@@ -147,6 +153,11 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
this, this,
this.onEmotionInitialized this.onEmotionInitialized
); );
Utils.removeInnerEL(
InnerMsgCode.Chat_DialogRefresh,
this,
this.onDialogRefresh
);
// 停止视频播放,释放资源 // 停止视频播放,释放资源
if (this.videoLayer) { if (this.videoLayer) {
@@ -402,6 +413,22 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
} }
} }
} }
/**
* 对话刷新事件处理(用于加载历史记录)
*/
private onDialogRefresh = (): void => {
if (!this.layout) return;
// 获取所有对话记录
const dialogManager = DialogManager.getInstance();
const allDialogs = dialogManager["dialogData"].getAllDialogs();
logger.log(`ChatPanel: Loading ${allDialogs.length} history dialogs to UI`);
// 加载所有对话到UI
this.layout.loadAllDialogs(allDialogs);
};
protected onEnable(): void { protected onEnable(): void {
if (!this.manager) this.manager = DialogManager.getInstance(); if (!this.manager) this.manager = DialogManager.getInstance();
@@ -98,7 +98,7 @@ export class ShowPanel extends li_BaseView {
// 阻止事件冒泡 // 阻止事件冒泡
event.propagationStopped = true; event.propagationStopped = true;
// 阻止浏览器默认行为(如拖动、滚动) // 阻止浏览器默认行为(如拖动、滚动)
event.preventDefault(); //event.preventDefault();
} }
protected onClose() { protected onClose() {
+17 -15
View File
@@ -1336,8 +1336,8 @@
}, },
"_lpos": { "_lpos": {
"__type__": "cc.Vec3", "__type__": "cc.Vec3",
"x": 13.099999999999966, "x": 0,
"y": -158.57699999999997, "y": -158.577,
"z": 0 "z": 0
}, },
"_lrot": { "_lrot": {
@@ -1386,7 +1386,7 @@
}, },
"_lpos": { "_lpos": {
"__type__": "cc.Vec3", "__type__": "cc.Vec3",
"x": -28.972000000000037, "x": -42.072,
"y": -303.6575, "y": -303.6575,
"z": 0 "z": 0
}, },
@@ -1620,7 +1620,7 @@
}, },
"_contentSize": { "_contentSize": {
"__type__": "cc.Size", "__type__": "cc.Size",
"width": 1080, "width": 697.6,
"height": 45 "height": 45
}, },
"_anchorPoint": { "_anchorPoint": {
@@ -1660,7 +1660,7 @@
"_paddingBottom": 30, "_paddingBottom": 30,
"_spacingX": 0, "_spacingX": 0,
"_spacingY": 15, "_spacingY": 15,
"_verticalDirection": 0, "_verticalDirection": 1,
"_horizontalDirection": 0, "_horizontalDirection": 0,
"_constraint": 0, "_constraint": 0,
"_constraintNum": 2, "_constraintNum": 2,
@@ -1759,8 +1759,8 @@
}, },
"_lpos": { "_lpos": {
"__type__": "cc.Vec3", "__type__": "cc.Vec3",
"x": -81.42899999999997, "x": -257.913,
"y": -303.626, "y": -345.697,
"z": 0 "z": 0
}, },
"_lrot": { "_lrot": {
@@ -2548,8 +2548,8 @@
}, },
"_alignFlags": 40, "_alignFlags": 40,
"_target": null, "_target": null,
"_left": 293.571, "_left": 117.08700000000002,
"_right": 259.16599999999994, "_right": 435.65,
"_top": 0, "_top": 0,
"_bottom": 0, "_bottom": 0,
"_horizontalCenter": 0, "_horizontalCenter": 0,
@@ -2649,8 +2649,8 @@
}, },
"_lpos": { "_lpos": {
"__type__": "cc.Vec3", "__type__": "cc.Vec3",
"x": 69.286, "x": 248.123,
"y": -33.625999999999976, "y": -470.697,
"z": 0 "z": 0
}, },
"_lrot": { "_lrot": {
@@ -3617,7 +3617,7 @@
"_alignFlags": 32, "_alignFlags": 32,
"_target": null, "_target": null,
"_left": 0, "_left": 0,
"_right": 305.714, "_right": 126.87700000000001,
"_top": 0, "_top": 0,
"_bottom": 0, "_bottom": 0,
"_horizontalCenter": 0, "_horizontalCenter": 0,
@@ -3732,7 +3732,7 @@
}, },
"_contentSize": { "_contentSize": {
"__type__": "cc.Size", "__type__": "cc.Size",
"width": 723.8, "width": 697.6,
"height": 684.24 "height": 684.24
}, },
"_anchorPoint": { "_anchorPoint": {
@@ -3877,7 +3877,7 @@
}, },
"_contentSize": { "_contentSize": {
"__type__": "cc.Size", "__type__": "cc.Size",
"width": 723.8, "width": 697.6,
"height": 684.24 "height": 684.24
}, },
"_anchorPoint": { "_anchorPoint": {
@@ -3948,7 +3948,7 @@
"_alignFlags": 45, "_alignFlags": 45,
"_target": null, "_target": null,
"_left": 26.2, "_left": 26.2,
"_right": 0, "_right": 26.2,
"_top": 0.38528562499999996, "_top": 0.38528562499999996,
"_bottom": 299.303, "_bottom": 299.303,
"_horizontalCenter": 0, "_horizontalCenter": 0,
@@ -3978,6 +3978,8 @@
"__id__": 0 "__id__": 0
}, },
"fileId": "41O8NIf/BNzbi1iBa0OJzt", "fileId": "41O8NIf/BNzbi1iBa0OJzt",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null "nestedPrefabInstanceRoots": null
}, },
{ {
+67 -67
View File
@@ -2522,7 +2522,7 @@
}, },
{ {
"__type__": "cc.Node", "__type__": "cc.Node",
"_name": "chatBtn", "_name": "detailBtn",
"_objFlags": 0, "_objFlags": 0,
"__editorExtras__": {}, "__editorExtras__": {},
"_parent": { "_parent": {
@@ -2546,8 +2546,8 @@
}, },
"_lpos": { "_lpos": {
"__type__": "cc.Vec3", "__type__": "cc.Vec3",
"x": 240.08799999999997, "x": 0,
"y": -2.285999999999831, "y": 0,
"z": 0 "z": 0
}, },
"_lrot": { "_lrot": {
@@ -2587,8 +2587,8 @@
}, },
"_contentSize": { "_contentSize": {
"__type__": "cc.Size", "__type__": "cc.Size",
"width": 100, "width": 690,
"height": 100 "height": 180
}, },
"_anchorPoint": { "_anchorPoint": {
"__type__": "cc.Vec2", "__type__": "cc.Vec2",
@@ -2599,10 +2599,10 @@
}, },
{ {
"__type__": "cc.CompPrefabInfo", "__type__": "cc.CompPrefabInfo",
"fileId": "4cMlYtnbBO064yZXRA1GwL" "fileId": "85MUsweIVK5L3FFtT0TEZ1"
}, },
{ {
"__type__": "cc.Sprite", "__type__": "cc.Widget",
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"__editorExtras__": {}, "__editorExtras__": {},
@@ -2613,38 +2613,29 @@
"__prefab": { "__prefab": {
"__id__": 105 "__id__": 105
}, },
"_customMaterial": null, "_alignFlags": 45,
"_srcBlendFactor": 2, "_target": null,
"_dstBlendFactor": 4, "_left": 0,
"_color": { "_right": 0,
"__type__": "cc.Color", "_top": 0,
"r": 255, "_bottom": 0,
"g": 255, "_horizontalCenter": 0,
"b": 255, "_verticalCenter": 0,
"a": 255 "_isAbsLeft": true,
}, "_isAbsRight": true,
"_spriteFrame": { "_isAbsTop": true,
"__uuid__": "1b0f18ce-5d14-4a6d-861e-d640f173e9fb@f9941", "_isAbsBottom": true,
"__expectedType__": "cc.SpriteFrame" "_isAbsHorizontalCenter": true,
}, "_isAbsVerticalCenter": true,
"_type": 0, "_originalWidth": 100,
"_fillType": 0, "_originalHeight": 100,
"_sizeMode": 1, "_alignMode": 2,
"_fillCenter": { "_lockFlags": 0,
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_useGrayscale": false,
"_atlas": null,
"_id": "" "_id": ""
}, },
{ {
"__type__": "cc.CompPrefabInfo", "__type__": "cc.CompPrefabInfo",
"fileId": "15bvwd0d5HmalSCKDMfaNx" "fileId": "535aLc925HuqW9jtjkssz2"
}, },
{ {
"__type__": "cc.Button", "__type__": "cc.Button",
@@ -2700,7 +2691,7 @@
}, },
{ {
"__type__": "cc.CompPrefabInfo", "__type__": "cc.CompPrefabInfo",
"fileId": "06nslvNYNH65cg9n7c0mLT" "fileId": "f0kGWHBNdKv4Bh/VqTRN1V"
}, },
{ {
"__type__": "cc.PrefabInfo", "__type__": "cc.PrefabInfo",
@@ -2710,14 +2701,14 @@
"asset": { "asset": {
"__id__": 0 "__id__": 0
}, },
"fileId": "39vAqfB6tIHqiwsIvtkXGg", "fileId": "c3K4m/IMJG94t8ShUriO9C",
"instance": null, "instance": null,
"targetOverrides": null, "targetOverrides": null,
"nestedPrefabInstanceRoots": null "nestedPrefabInstanceRoots": null
}, },
{ {
"__type__": "cc.Node", "__type__": "cc.Node",
"_name": "detailBtn", "_name": "chatBtn",
"_objFlags": 0, "_objFlags": 0,
"__editorExtras__": {}, "__editorExtras__": {},
"_parent": { "_parent": {
@@ -2741,8 +2732,8 @@
}, },
"_lpos": { "_lpos": {
"__type__": "cc.Vec3", "__type__": "cc.Vec3",
"x": 0, "x": 240.08799999999997,
"y": 0, "y": -2.285999999999831,
"z": 0 "z": 0
}, },
"_lrot": { "_lrot": {
@@ -2782,8 +2773,8 @@
}, },
"_contentSize": { "_contentSize": {
"__type__": "cc.Size", "__type__": "cc.Size",
"width": 690, "width": 100,
"height": 180 "height": 100
}, },
"_anchorPoint": { "_anchorPoint": {
"__type__": "cc.Vec2", "__type__": "cc.Vec2",
@@ -2794,10 +2785,10 @@
}, },
{ {
"__type__": "cc.CompPrefabInfo", "__type__": "cc.CompPrefabInfo",
"fileId": "85MUsweIVK5L3FFtT0TEZ1" "fileId": "4cMlYtnbBO064yZXRA1GwL"
}, },
{ {
"__type__": "cc.Widget", "__type__": "cc.Sprite",
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"__editorExtras__": {}, "__editorExtras__": {},
@@ -2808,29 +2799,38 @@
"__prefab": { "__prefab": {
"__id__": 113 "__id__": 113
}, },
"_alignFlags": 45, "_customMaterial": null,
"_target": null, "_srcBlendFactor": 2,
"_left": 0, "_dstBlendFactor": 4,
"_right": 0, "_color": {
"_top": 0, "__type__": "cc.Color",
"_bottom": 0, "r": 255,
"_horizontalCenter": 0, "g": 255,
"_verticalCenter": 0, "b": 255,
"_isAbsLeft": true, "a": 255
"_isAbsRight": true, },
"_isAbsTop": true, "_spriteFrame": {
"_isAbsBottom": true, "__uuid__": "1b0f18ce-5d14-4a6d-861e-d640f173e9fb@f9941",
"_isAbsHorizontalCenter": true, "__expectedType__": "cc.SpriteFrame"
"_isAbsVerticalCenter": true, },
"_originalWidth": 100, "_type": 0,
"_originalHeight": 100, "_fillType": 0,
"_alignMode": 2, "_sizeMode": 1,
"_lockFlags": 0, "_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_useGrayscale": false,
"_atlas": null,
"_id": "" "_id": ""
}, },
{ {
"__type__": "cc.CompPrefabInfo", "__type__": "cc.CompPrefabInfo",
"fileId": "535aLc925HuqW9jtjkssz2" "fileId": "15bvwd0d5HmalSCKDMfaNx"
}, },
{ {
"__type__": "cc.Button", "__type__": "cc.Button",
@@ -2886,7 +2886,7 @@
}, },
{ {
"__type__": "cc.CompPrefabInfo", "__type__": "cc.CompPrefabInfo",
"fileId": "f0kGWHBNdKv4Bh/VqTRN1V" "fileId": "06nslvNYNH65cg9n7c0mLT"
}, },
{ {
"__type__": "cc.PrefabInfo", "__type__": "cc.PrefabInfo",
@@ -2896,7 +2896,7 @@
"asset": { "asset": {
"__id__": 0 "__id__": 0
}, },
"fileId": "c3K4m/IMJG94t8ShUriO9C", "fileId": "39vAqfB6tIHqiwsIvtkXGg",
"instance": null, "instance": null,
"targetOverrides": null, "targetOverrides": null,
"nestedPrefabInstanceRoots": null "nestedPrefabInstanceRoots": null
@@ -3157,10 +3157,10 @@
"__id__": 65 "__id__": 65
}, },
"chatBtn": { "chatBtn": {
"__id__": 101 "__id__": 109
}, },
"detailBtn": { "detailBtn": {
"__id__": 109 "__id__": 101
}, },
"_id": "" "_id": ""
}, },