fix: 更新提交

This commit is contained in:
han_han9
2025-11-26 22:57:07 +08:00
parent 8a6620cf8f
commit 4c16bec13f
640 changed files with 70914 additions and 13327 deletions

View File

@@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "a53e21a6-1d72-42c3-a8ea-ce4cd0dc318f",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,63 @@
[
{
"__type__": "cc.Prefab",
"_name": "DressGlareNode",
"_objFlags": 0,
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"asyncLoadAssets": false,
"persistent": false
},
{
"__type__": "cc.Node",
"_name": "DressGlareNode",
"_objFlags": 0,
"_parent": null,
"_children": [],
"_active": true,
"_components": [],
"_prefab": {
"__id__": 2
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "c46/YsCPVOJYA4mWEpNYRx"
}
]

View File

@@ -0,0 +1,13 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "e8086588-8a5d-4210-bc27-389b6adcaf11",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "DressGlareNode"
}
}

View File

@@ -0,0 +1,340 @@
[
{
"__type__": "cc.Prefab",
"_name": "DressSocketNode",
"_objFlags": 0,
"__editorExtras__": {},
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"persistent": false
},
{
"__type__": "cc.Node",
"_name": "DressSocketNode",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
"_children": [
{
"__id__": 2
},
{
"__id__": 8
}
],
"_active": true,
"_components": [],
"_prefab": {
"__id__": 14
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "Texture",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 3
},
{
"__id__": 5
}
],
"_prefab": {
"__id__": 7
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 4
},
"_contentSize": {
"__type__": "cc.Size",
"width": 100,
"height": 100
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "c2tK6S82tEJq55LVlT4F3N"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 6
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_spriteFrame": null,
"_type": 0,
"_fillType": 0,
"_sizeMode": 2,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": false,
"_useGrayscale": false,
"_atlas": null,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "a5XjaX0ABPP5RSoo98iHXa"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "46WgrGcBpCU4AVxZHeUKo0",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.Node",
"_name": "Spine",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 9
},
{
"__id__": 11
}
],
"_prefab": {
"__id__": 13
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 8
},
"_enabled": true,
"__prefab": {
"__id__": 10
},
"_contentSize": {
"__type__": "cc.Size",
"width": 100,
"height": 100
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.60222
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "e8PHvFTQdCub2YlQVztJGK"
},
{
"__type__": "sp.Skeleton",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 8
},
"_enabled": true,
"__prefab": {
"__id__": 12
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_skeletonData": null,
"defaultSkin": "",
"defaultAnimation": "",
"_premultipliedAlpha": false,
"_timeScale": 1,
"_preCacheMode": -1,
"_cacheMode": 0,
"_sockets": [],
"_useTint": false,
"_debugMesh": false,
"_debugBones": false,
"_debugSlots": false,
"_enableBatch": false,
"loop": true,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "0bLrMfCo1HH4sNbP27AV7B"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "28LtEJQG9CerixgYrYjMCo",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "c46/YsCPVOJYA4mWEpNYRx",
"instance": null,
"targetOverrides": null
}
]

View File

@@ -0,0 +1,13 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "2366e791-ed40-4713-8037-8702c964ea37",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "DressSocketNode"
}
}

View File

@@ -0,0 +1,67 @@
[
{
"__type__": "cc.Prefab",
"_name": "GameUI",
"_objFlags": 0,
"__editorExtras__": {},
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"persistent": false
},
{
"__type__": "cc.Node",
"_name": "GameUI",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
"_children": [],
"_active": true,
"_components": [],
"_prefab": {
"__id__": 2
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "c46/YsCPVOJYA4mWEpNYRx",
"instance": null,
"targetOverrides": null
}
]

View File

@@ -0,0 +1,13 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "1369e7f1-056a-4e3d-8484-39be5dface1e",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "GameUI"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "682cc812-4182-4fe0-8b91-43c4d9b6add6",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "MainUI-001"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "d098e1e4-9d54-4ad0-88f0-f13bf7c77e51",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,232 @@
import { instantiate, Node, sp, Sprite, SpriteFrame, Texture2D } from "cc";
import { DRESS_PART, DRESS_SOURCE_TYPE, IDressInfo, SPINE_SLOT, SPINE_SOCKET } from "./Types";
import ResManager from "@max-studio/core/res/ResManager";
import { loadDressSocketNode } from "./PetUtils";
import { StringUtils } from "@max-studio/core/utils/StringUtils";
export class BasePart {
protected skeleton: sp.Skeleton = null;
protected info: IDressInfo = null;
protected socketName: string = null;
protected part: DRESS_PART = null;
protected faceSkeleton: sp.Skeleton = null;
protected socketMountNode: Node = null;
protected socketCache: Map<string, sp.SpineSocket> = new Map();
protected socketNode: Node = null;
constructor(ske: sp.Skeleton, part: DRESS_PART) {
this.skeleton = ske;
this.part = part;
this.socketName = SPINE_SOCKET[part];
this.faceSkeleton = ske.node.getChildByName("face")?.getComponent(sp.Skeleton);
}
public async putOn(info: IDressInfo) {
this.takeOff();
this.info = info;
if (info.sourceLocationType == DRESS_SOURCE_TYPE.SLOT) {
await this.putOnBySlot(info);
} else {
await this.putOnBySocket(info);
}
}
public takeOff() {
if (this.info == null) {
return;
}
const partSkeleton = this.getPartSkeleton();
if (this.info.sourceLocationType == DRESS_SOURCE_TYPE.SLOT) {
const slotName = SPINE_SLOT[this.part];
if (StringUtils.isEmpty(slotName) || partSkeleton == null) {
console.error("宠物_槽位_空", slotName);
return;
}
const slot = partSkeleton.findSlot(slotName);
if (!slot) {
console.error("宠物_槽位_不存在", slotName);
return;
}
if (slot.texture) {
ResManager.getInstance().releaseAsset(slot.texture);
slot.texture = null;
}
partSkeleton.setSlotTexture(slotName, null, true);
} else {
if (!this.socketNode) {
return;
}
const socketSprite = this.socketNode.getOrAddComponent(Sprite, "Texture");
if (socketSprite && socketSprite.spriteFrame) {
ResManager.getInstance().releaseAsset(socketSprite.spriteFrame);
socketSprite.spriteFrame = null;
}
const spine = this.socketNode.getOrAddComponent(sp.Skeleton, "Spine");
if (spine && spine.skeletonData) {
ResManager.getInstance().releaseAsset(spine.skeletonData);
spine.skeletonData = undefined;
spine.animation = undefined;
}
}
this.info = null;
}
private getPartSkeleton() {
if (
this.part == DRESS_PART.GLASSES ||
this.part == DRESS_PART.ACCESS ||
this.info.sourceLocationType == DRESS_SOURCE_TYPE.SOCKET_TEX_FACE ||
this.info.sourceLocationType == DRESS_SOURCE_TYPE.SOCKET_SPINE_FACE
) {
return this.faceSkeleton;
}
return this.skeleton;
}
private getPartBonePath(skeleton: sp.Skeleton, name: string) {
let path = "";
console.log("获取宠物_骨骼_路径:", name);
let bone = skeleton.findBone(name);
if (bone) {
path = bone.data.name;
while (bone.parent) {
bone = bone.parent;
path = `${bone.data.name}/${path}`;
if ("root" == bone.data.name) {
break;
}
}
}
return path;
}
private getSocketNode(ske: sp.Skeleton, path: string): sp.SpineSocket {
let socket = this.socketCache.get(path);
if (socket == null) {
const sockets = ske.sockets as sp.SpineSocket[];
socket = sockets.find((s) => s.path == path);
if (!socket) {
console.error("宠物_挂点_不存在 创建挂点:", path);
socket = new sp.SpineSocket(path);
sockets.push(socket);
ske.sockets = sockets;
}
this.socketCache.set(path, socket);
}
return socket;
}
private async putOnBySlot(info: IDressInfo) {
const partSkeleton = this.getPartSkeleton();
const slotName = SPINE_SLOT[this.part];
if (StringUtils.isEmpty(slotName) || partSkeleton == null) {
console.error("宠物_槽位_空", slotName);
return;
}
const slot = partSkeleton.findSlot(slotName);
if (!slot) {
console.error("宠物_槽位_不存在", slotName);
return;
}
if (!info) {
if (slot.texture) {
ResManager.getInstance().releaseAsset(slot.texture);
slot.texture = null;
}
partSkeleton.setSlotTexture(slotName, null, true);
return;
}
const { err, asset } = await ResManager.getInstance().loadAsset({
bundle: "dress-spine",
path: `DressTexture/${info.sourceName}`,
type: Texture2D,
});
if (err) {
console.error("加载宠物_槽位_失败", err);
return;
}
if (this.info != info) {
ResManager.getInstance().releaseAsset(asset);
return;
}
if (slot.texture != null) {
ResManager.getInstance().releaseAsset(slot.texture);
slot.texture = null;
}
slot.texture = asset;
partSkeleton.setSlotTexture(slotName, asset, true);
}
private async putOnBySocket(info: IDressInfo) {
const partSkeleton = this.getPartSkeleton();
const bonePath = this.getPartBonePath(partSkeleton, this.socketName);
if (this.socketNode == null) {
const socketPrefab = await loadDressSocketNode();
if (socketPrefab == null) {
return;
}
this.socketNode = instantiate(socketPrefab);
}
if (
info.sourceLocationType == DRESS_SOURCE_TYPE.SOCKET_TEX_FACE ||
info.sourceLocationType == DRESS_SOURCE_TYPE.SOCKET_TEX
) {
const loadInfo = await ResManager.getInstance().loadAsset({
bundle: "dress-spine",
path: `DressTexture/${info.sourceName}`,
type: SpriteFrame,
});
if (loadInfo.err) {
console.error("加载宠物_socket_tex失败", loadInfo.err);
} else {
if (this.info == info) {
const socketSprite = this.socketNode.getOrAddComponent(Sprite, "Texture");
socketSprite.spriteFrame = loadInfo.asset as SpriteFrame;
} else {
console.warn("加载宠物_socket_tex失败但是不是当前宠物");
ResManager.getInstance().releaseAsset(loadInfo.asset);
}
}
} else if (
info.sourceLocationType == DRESS_SOURCE_TYPE.SOCKET_SPINE ||
info.sourceLocationType == DRESS_SOURCE_TYPE.SOCKET_SPINE_FACE
) {
const loadInfo = await ResManager.getInstance().loadAsset({
bundle: "dress-spine",
path: `DressSpine/${info.sourceName}/${info.sourceName}`,
type: sp.SkeletonData,
});
if (loadInfo.err) {
console.error("加载宠物_socket_spine失败", loadInfo.err);
} else {
if (this.info == info) {
const spine = this.socketNode.getOrAddComponent(sp.Skeleton, "Spine");
spine.animation = undefined;
spine.skeletonData = loadInfo.asset as sp.SkeletonData;
spine.setAnimation(0, "idle", true);
} else {
console.warn("加载宠物_socket_spine失败但是不是当前宠物");
ResManager.getInstance().releaseAsset(loadInfo.asset);
}
}
}
this.socketNode.setParent(partSkeleton.node);
const socket = this.getSocketNode(partSkeleton, bonePath);
this.socketNode.layer = partSkeleton.node.layer;
socket.target = this.socketNode;
const socketSpine = this.socketNode.getOrAddComponent(sp.Skeleton);
if (socketSpine && socketSpine.skeletonData) {
socketSpine.setAnimation(0, "idle", true);
}
// eslint-disable-next-line no-self-assign
partSkeleton.sockets = partSkeleton.sockets;
this.setSocketZIndex();
}
protected setSocketZIndex() {
if (this.socketNode) {
this.socketNode.setSiblingIndex(0);
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "e07784d9-9898-4cde-b467-3deaba247a36",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,82 @@
import { Component, _decorator, sp } from "cc";
import { COMMON_FACE_ANIM, DRESS_PART, IDressInfo, PET_ANIM_NAME, PET_BODY_FACE_ANIM_MAP, PetInfo } from "./Types";
import { autoBind } from "@max-studio/core/ui/UIDecorator";
import { BasePart } from "./BasePart";
import { GlarePart } from "./GlarePart";
const { ccclass } = _decorator;
@ccclass("BasePet")
export class BasePet extends Component {
private petInfo: PetInfo;
@autoBind("RootNode/PetAni", sp.Skeleton)
private petBodySkeleton: sp.Skeleton = null;
@autoBind("RootNode/PetAni/face", sp.Skeleton)
private petFace: sp.Skeleton = null;
private parts: Map<DRESS_PART, BasePart> = new Map();
protected onLoad(): void {
this.parts.set(DRESS_PART.GLARE, new GlarePart(this.petBodySkeleton, DRESS_PART.GLARE));
this.parts.set(DRESS_PART.BAG, new BasePart(this.petBodySkeleton, DRESS_PART.BAG));
this.parts.set(DRESS_PART.GLASSES, new BasePart(this.petBodySkeleton, DRESS_PART.GLASSES));
this.parts.set(DRESS_PART.HAT, new BasePart(this.petBodySkeleton, DRESS_PART.HAT));
this.parts.set(DRESS_PART.ACCESS, new BasePart(this.petBodySkeleton, DRESS_PART.ACCESS));
}
public setInfo(info: PetInfo) {
this.petInfo = info;
}
public getInfo(): PetInfo {
return this.petInfo;
}
public async putOn(info: IDressInfo) {
const { type, sourceLocationType, sourceName } = info;
if (type == DRESS_PART.SUIT) {
if (info.dressMap) {
info.dressMap.forEach(async (dressInfo) => {
await this.parts.get(dressInfo.type)?.putOn(dressInfo);
});
}
return;
}
await this.parts.get(type)?.putOn(info);
}
public takeOff(type: DRESS_PART = DRESS_PART.ALL) {
if (type == DRESS_PART.ALL) {
this.parts.forEach((part) => {
part.takeOff();
});
} else {
this.parts.get(type)?.takeOff();
}
}
public playAnim(anim: PET_ANIM_NAME) {
this.petBodySkeleton.setAnimation(0, anim, true);
const faceAnim = PET_BODY_FACE_ANIM_MAP[anim] ?? PET_ANIM_NAME.IDLE;
this.petFace.setAnimation(0, faceAnim, true);
this.setFaceSkinFromAnim(faceAnim);
}
protected setFaceSkinFromAnim(faceAnim: PET_ANIM_NAME) {
let faceSkin: string = faceAnim;
if (!COMMON_FACE_ANIM.includes(faceAnim)) {
faceSkin = `eye/${this.petInfo.name}`;
}
this.petFace.setSkin(faceSkin);
this.petFace._skeleton?.slots.forEach((slot) => {
const slotName = slot.data.name.toLowerCase();
if (slotName.endsWith("_hui")) {
slot.color.a = slotName == `${this.petInfo.name}_hui`.toLowerCase() ? 1 : 0;
}
if (slotName.startsWith("dk")) {
console.log("slotName:", slotName);
}
});
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "5df90b9c-7a32-4e70-b46f-1510986c73d4",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,3 @@
import { BasePart } from "./BasePart";
export class FacePart extends BasePart {}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "dbc0d9b3-b0a1-4121-8e48-9c991101a10b",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,90 @@
import { easing, instantiate, Node, Prefab, sp, tween, Tween, Vec3 } from "cc";
import { BasePart } from "./BasePart";
import { DRESS_PART, DRESS_SOURCE_TYPE, IDressInfo } from "./Types";
import ResManager from "@max-studio/core/res/ResManager";
const GLARE_NODE_NAME = "glare";
const GLARE_DEFAULT_POSITION = new Vec3(-170, 0, 0);
export class GlarePart extends BasePart {
private glareNode: Node = null;
private glareSpine: sp.Skeleton = null;
private glarePrefab: Prefab = null;
constructor(ske: sp.Skeleton, part: DRESS_PART) {
super(ske, part);
this.getGlareNode();
}
public async putOn(info: IDressInfo) {
this.takeOff();
this.info = info;
const loadInfo = await ResManager.getInstance().loadAsset({
bundle: "dress-spine",
path: `DressGlare/${info.sourceName}`,
type: Prefab,
});
if (loadInfo.err) {
console.error("加载宠物_槽位_失败", loadInfo.err);
return;
}
this.glarePrefab = loadInfo.asset;
const node = instantiate(loadInfo.asset);
node.name = "sp";
node.setParent(this.glareNode);
if (node == null) {
return;
}
this.glareSpine = node.getComponent(sp.Skeleton);
this.glareSpine.setAnimation(0, "animation", false);
this.glareNode.setScale(this.skeleton.node.scale);
Tween.stopAllByTarget(this.glareNode);
const dir = this.glareNode.scale.x;
GLARE_DEFAULT_POSITION.x = dir > 0 ? -170 : 170;
tween(this.glareNode).to(0.35, { position: GLARE_DEFAULT_POSITION }, { easing: easing.sineOut }).start();
if (this.info.sourceLocationType == DRESS_SOURCE_TYPE.NONE) {
this.glareNode.setSiblingIndex(0);
} else {
this.glareNode.setSiblingIndex(this.glareNode.parent.children.length - 1);
}
}
public takeOff() {
if (this.glareSpine == null) {
return;
}
if (this.glareSpine) {
this.glareSpine.node.destroy();
this.glareSpine = null;
}
if (this.glarePrefab) {
ResManager.getInstance().releaseAsset(this.glarePrefab);
this.glarePrefab = null;
}
if (this.glareNode) {
Tween.stopAllByTarget(this.glareNode);
}
this.info = null;
}
private getGlareNode() {
if (this.glareNode) {
return this.glareNode;
}
const root = this.skeleton.node.parent;
if (!root) {
console.error("没有找到根节点");
return null;
}
this.glareNode = new Node(GLARE_NODE_NAME);
this.glareNode.setParent(root);
this.glareNode.setPosition(GLARE_DEFAULT_POSITION);
this.glareNode.setSiblingIndex(0);
return this.glareNode;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "f5f29e43-e981-42ee-96c5-b993931e25e4",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,9 @@
import { BasePart } from "./BasePart";
export class GlassesPart extends BasePart {
protected setSocketZIndex(): void {
if (this.socketNode) {
this.socketNode.setSiblingIndex(this.socketNode.parent.children.length);
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "86abc774-d404-4392-b642-463b5e5470dc",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,55 @@
import ResManager from "@max-studio/core/res/ResManager";
import { Singleton } from "@max-studio/core/Singleton";
import { instantiate, Prefab } from "cc";
import { BasePet } from "./BasePet";
import { releaseDressSocketNode } from "./PetUtils";
export class PetManager extends Singleton {
private petPrefabCache: Map<string, Prefab> = new Map();
public async getPet(name: string): Promise<BasePet> {
let asset: Prefab = null;
if (this.petPrefabCache.has(name)) {
asset = this.petPrefabCache.get(name);
if (asset == null) {
console.error(`宠物预制体缓存为空 ${name}`);
return null;
}
asset.addRef();
} else {
const loadInfo = await ResManager.getInstance().loadAsset({
bundle: "pet-spine",
path: name,
type: Prefab,
});
if (loadInfo.err) {
console.error(`加载宠物预制体失败 ${name}`, loadInfo.err);
return null;
}
asset = loadInfo.asset;
this.petPrefabCache.set(name, asset);
}
const basePet = instantiate(asset).getOrAddComponent(BasePet);
basePet.setInfo({ name: name });
return basePet;
}
public releasePet(pet: BasePet) {
const petName = pet.getInfo().name;
pet.takeOff();
pet.node.removeFromParent();
pet.node.destroy();
if (this.petPrefabCache.has(petName)) {
const prefab = this.petPrefabCache.get(petName);
ResManager.getInstance().releaseAsset(prefab);
if (prefab.refCount == 0) {
this.petPrefabCache.delete(petName);
console.log(`释放宠物预制体成功 ${petName}`);
}
}
}
protected onRelease(): void {
releaseDressSocketNode();
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "e9aeecff-fbae-4e76-8620-bb0f5664ad62",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,29 @@
import ResManager from "@max-studio/core/res/ResManager";
import { Prefab } from "cc";
const DRESS_SOCKET_NODE_PATH = "prefabs/pet/DressSocketNode";
let socketPrefab: Prefab = null;
export async function loadDressSocketNode(): Promise<Prefab> {
if (socketPrefab != null) {
return socketPrefab;
}
const loadInfo = await ResManager.getInstance().loadAsset({
bundle: "games",
path: DRESS_SOCKET_NODE_PATH,
type: Prefab,
});
if (loadInfo.err) {
console.error(`加载 DressSocketNode 失败: ${loadInfo.err}`);
return null;
}
socketPrefab = loadInfo.asset;
return socketPrefab;
}
export function releaseDressSocketNode() {
if (socketPrefab != null) {
ResManager.getInstance().releaseAsset(socketPrefab);
socketPrefab = null;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "ccf9a987-4dc8-4993-856e-b9ea38c19731",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,125 @@
export interface PetInfo {
name: string;
petId?: string;
}
export interface IDressInfo {
/**
* 装扮部位
*/
type: DRESS_PART;
sourceLocationType: DRESS_SOURCE_TYPE;
sourceName: string;
/**
* 套装信息
*/
dressMap?: Map<number, IDressInfo>;
}
export enum DRESS_PART {
/**
* 套装
*/
SUIT = 0,
/**
* 背包
*/
BAG = 1,
/**
* 帽子
*/
HAT = 2,
/**
* 眼镜
*/
GLASSES = 3,
/**
* 附件
*/
ACCESS = 4,
/**
* 炫光
*/
GLARE = 5,
/**
* 所有
*/
ALL = 6,
}
export enum DRESS_SOURCE_TYPE {
NONE = 0,
/**
* 槽位
*/
SLOT = 1,
/**
* 挂点静态图
*/
SOCKET_TEX = 2,
/**
* 挂点动画
*/
SOCKET_SPINE = 3,
/**
* 挂点静态图-脸
*/
SOCKET_TEX_FACE = 4,
/**
* 挂点动画-脸
*/
SOCKET_SPINE_FACE = 5,
}
export const SPINE_SLOT: Record<number, string> = {
[DRESS_PART.BAG]: "glasses/bag",
[DRESS_PART.HAT]: "glasses/zs_hat_01",
[DRESS_PART.GLASSES]: "glasses/zs_glass_01",
[DRESS_PART.ACCESS]: "glasses/zs_hdi_01",
};
export const SPINE_SOCKET: Record<number, string> = {
[DRESS_PART.BAG]: "Bag",
[DRESS_PART.HAT]: "Hat",
[DRESS_PART.GLASSES]: "Glasses",
[DRESS_PART.ACCESS]: "ZS",
};
export enum PET_ANIM_NAME {
IDLE = "idle",
HAPPY = "happy",
SLEEP = "sleep",
VERTIGO = "vertigo",
EAT = "eat",
MOTOU = "motou",
RUN = "run",
WALK = "walk",
PLAY = "hudong_hudie",
ANGRY = "angry",
}
export const PET_BODY_FACE_ANIM_MAP: Record<PET_ANIM_NAME, PET_ANIM_NAME> = {
[PET_ANIM_NAME.IDLE]: PET_ANIM_NAME.IDLE,
[PET_ANIM_NAME.HAPPY]: PET_ANIM_NAME.HAPPY,
[PET_ANIM_NAME.SLEEP]: PET_ANIM_NAME.SLEEP,
[PET_ANIM_NAME.VERTIGO]: PET_ANIM_NAME.VERTIGO,
[PET_ANIM_NAME.EAT]: PET_ANIM_NAME.HAPPY,
[PET_ANIM_NAME.MOTOU]: PET_ANIM_NAME.MOTOU,
[PET_ANIM_NAME.RUN]: PET_ANIM_NAME.IDLE,
[PET_ANIM_NAME.WALK]: PET_ANIM_NAME.IDLE,
[PET_ANIM_NAME.PLAY]: PET_ANIM_NAME.HAPPY,
[PET_ANIM_NAME.ANGRY]: PET_ANIM_NAME.ANGRY,
};
export const COMMON_FACE_ANIM = [PET_ANIM_NAME.SLEEP, PET_ANIM_NAME.ANGRY, PET_ANIM_NAME.VERTIGO, PET_ANIM_NAME.HAPPY];

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "25f7a591-83b6-4490-9f3f-bc18d0dfbf76",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,3 @@
// import BasePet from "./BasePet";
export { PetManager } from "./PetManager";
export { BasePet } from "./BasePet";

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "d269dbc8-fcc2-48c2-8f83-4c35dcb4a760",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,9 +1,9 @@
import BaseToast from "@max-studio/core/ui/BaseToast";
import { uiConfig, UIType } from "@max-studio/core/ui/UIDecorator";
import UIManager from "@max-studio/core/ui/UIManager";
import { SpriteAtlas, tween, Vec3, UITransform } from "cc";
import { SpriteAtlas, tween, Vec3 } from "cc";
import { RichText } from "cc";
import { _decorator, Component, Node } from "cc";
import { _decorator, Node } from "cc";
const { ccclass, property } = _decorator;
@uiConfig({

View File

@@ -1,14 +1,10 @@
import { _decorator } from "cc";
import { _decorator, SpriteFrame } from "cc";
import BaseLayer from "@max-studio/core/ui/BaseLayer";
import { uiConfig, UIType } from "@max-studio/core/ui/UIDecorator";
import UIManager from "@max-studio/core/ui/UIManager";
import { CommonDialogBox } from "./CommonDialogBox";
import { CommonToast } from "./CommonToast";
import { ResManager } from "@max-studio/core/res/ResManager";
import { SpriteAtlas } from "cc";
import { uiConfig } from "@max-studio/core/ui/UIDecorator";
const { ccclass, property, menu } = _decorator;
const globalSpriteFrame: SpriteFrame | null = null; // 全局变量
@ccclass("MainUI")
@uiConfig({
@@ -17,6 +13,4 @@ const { ccclass, property, menu } = _decorator;
isCache: false,
})
@menu("max/ui/MainUI")
export class MainUI extends BaseLayer {
async onShow(...args: any[]) {}
}
export class MainUI extends BaseLayer {}

View File

@@ -17,7 +17,7 @@ const { ccclass, property, menu } = _decorator;
export class ShopUI extends BaseLayer {
protected onLoad(): void {
// ProtoDefinitions.pkg1.User
let user = new ProtoDefinitions.pkg1.User();
const user = new ProtoDefinitions.pkg1.User();
console.log(user, ProtoDefinitions.pkg1.User.encode(user));
}
}