mark~~
native的MeshAttachment无法更换有排查建议吗,RegionAttachment的可以,也没报错之类,不知道怎么看
同求,这个问题不解决,很多地方也用不成
3.x 版本的局部换装的 native上更换 MeshAttachment 方案,(目前)需要定制引擎
在 3.4.0以上版本,合并以下PR
- 修改 engine cocos/spine/skeleton.ts 文件
platforms/native/engine/jsb-spine-skeleton.js 文件 - 修改 engine-native
cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp
cocos/editor-support/spine-creator-support/SkeletonRenderer.h
cocos/editor-support/spine/Attachment.cpp
cocos/editor-support/spine/Attachment.h
cocos/editor-support/spine/MeshAttachment.cpp
cocos/editor-support/spine/RegionAttachment.cpp
tools/tojs/spine.ini
备注
- 修改engine后,记得在编辑器顶部菜单栏点击编译引擎
- 修改engine-native后,记得运行 engine-native\tools\tojs目录下的genbindings.py脚本,重新生成绑定
- 用户脚本上,直接调用 changeSlotSkin(slotName, tex2d)函数完成换肤
mark~
请问这些pr会被添加到之后的哪个新版本?
如果用了自动图集的话可以用下面的方法 v2.4.8可用
/**
* 获取spine运行时图片数据
*/
private loadRegion(frame:cc.SpriteFrame):sp.spine.TextureAtlasRegion{
let texture=frame.getTexture()
let skeletonTexture = new sp.SkeletonTexture()
skeletonTexture.setRealTexture(texture)
let page = new sp.spine.TextureAtlasPage()
page.texture = skeletonTexture
page.name = texture.name
page.uWrap = sp.spine.TextureWrap.ClampToEdge
page.vWrap = sp.spine.TextureWrap.ClampToEdge
page.texture = skeletonTexture
page.texture.setWraps(page.uWrap, page.vWrap)
page.width = texture.width
page.height = texture.height
let region = new sp.spine.TextureAtlasRegion()
region.page = page
let size=frame.getOriginalSize()
region.width = size.width
region.height = size.height
region.originalWidth = size.width
region.originalHeight = size.height
region.u = frame["uv"][0]
region.v = frame["uv"][7]
region.u2 = frame["uv"][6]
region.v2 = frame["uv"][1]
region.texture = skeletonTexture
return region
}
原生打包这个方案直接寄了。。。
spine换装,mark一个~
原生不能这么干要另外做处理
if (JSB) {
// @ts-ignore
let skeleton = cc.internal.SpineSkeleton.prototype;
// @ts-ignore
let spineSkeletonData = cc.internal.SpineSkeletonData.prototype;
// 局部换装
skeleton.updateRegion = function (attachment: any, tex2d: any) {
// @ts-ignore
var jsbTex2d = new middleware.Texture2D();
jsbTex2d.setRealTextureIndex(spineSkeletonData.recordTexture(tex2d));
jsbTex2d.setPixelsWide(tex2d.width);
jsbTex2d.setPixelsHigh(tex2d.height);
// @ts-ignore
sp.spine.updateRegion(attachment, jsbTex2d);
}
}
十分感谢,我最后还是用了官方的方案,新建了一个全部是武器的spine文件来替换使用了。。。
赞,有用。
mark~~
请问怎么用呢
在其他帖子找到的答案,用这个转一下 var medTex = new middleware.Texture2D();
medTex.setRealTextureIndex(0);//参数随便设置的没怎么研究
medTex.setPixelsHigh(texture.height);
medTex.setPixelsWide(texture.width);
medTex.setNativeTexture(texture.getImpl());
skeleton._nativeSkeleton.loadTextureForSpine(regionName, medTex);
大佬,如果是MeshAttachment类型要怎么改
贴一下支持mesh的,测试过了没啥问题
void SkeletonRenderer::loadTextureForSpine(const std::string& slotName, cocos2d::middleware::Texture2D* texture)
{
if (!texture || slotName.empty()) {
CCLOG(“Error: Invalid texture or slot name”);
return;
}
Slot *slot = _skeleton->findSlot(slotName.c_str());
if (!slot) {
CCLOG("Error: Slot '%s' not found", slotName.c_str());
return;
}
Attachment* attachment = slot->getAttachment();
if (!attachment) {
CCLOG("Error: No attachment found for slot '%s'", slotName.c_str());
return;
}
Texture* texture2D = texture->getNativeTexture();
float width = texture2D->getWidth();
float height = texture2D->getHeight();
float wide = texture->getPixelsWide();
float high = texture->getPixelsHigh();
texture->setPixelsWide(width);
texture->setPixelsHigh(height);
texture->setRealTextureIndex(1);
// 处理RegionAttachment
if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) {
RegionAttachment* regionAttachment = (RegionAttachment*)attachment;
AttachmentVertices *attachV = (AttachmentVertices *)regionAttachment->getRendererObject();
if (attachV->_texture == texture) return;
CC_SAFE_RELEASE(attachV->_texture);
attachV->_texture = texture;
CC_SAFE_RETAIN(texture);
// 设置UV和尺寸信息
regionAttachment->setUVs(0, 0, 1, 1, false);
regionAttachment->setWidth(wide);
regionAttachment->setHeight(high);
regionAttachment->setRegionWidth(wide);
regionAttachment->setRegionHeight(high);
regionAttachment->setRegionOriginalWidth(wide);
regionAttachment->setRegionOriginalHeight(high);
regionAttachment->setRegionOffsetX(0);
regionAttachment->setRegionOffsetY(15);
// 更新顶点UV坐标
V2F_T2F_C4B* vertices = attachV->_triangles->verts;
auto& uvsVector = regionAttachment->getUVs();
for (int i = 0, ii = 0; i < 4; ++i, ii += 2) {
vertices[i].texCoord.u = uvsVector[ii];
vertices[i].texCoord.v = uvsVector[ii+1];
}
// 更新偏移量
regionAttachment->updateOffset();
// 强制更新骨架变换
_skeleton->updateWorldTransform();
}
// 处理MeshAttachment - 正确实现换皮功能
else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) {
MeshAttachment* meshAttachment = (MeshAttachment*)attachment;
AttachmentVertices *attachV = (AttachmentVertices *)meshAttachment->getRendererObject();
if (attachV->_texture == texture) return;
CC_SAFE_RELEASE(attachV->_texture);
attachV->_texture = texture;
CC_SAFE_RETAIN(texture);
// 关键步骤1: 设置MeshAttachment的区域参数,使其使用整个新纹理
meshAttachment->setRegionU(0);
meshAttachment->setRegionV(0);
meshAttachment->setRegionU2(1);
meshAttachment->setRegionV2(1);
meshAttachment->setRegionWidth(wide);
meshAttachment->setRegionHeight(high);
meshAttachment->setRegionOriginalWidth(wide);
meshAttachment->setRegionOriginalHeight(high);
meshAttachment->setRegionOffsetX(0);
meshAttachment->setRegionOffsetY(0);
meshAttachment->setRegionRotate(false);
meshAttachment->setRegionDegrees(0);
// 关键步骤2: 调用updateUVs()方法重新计算UV坐标
meshAttachment->updateUVs();
// 关键步骤3: 将重新计算的UV坐标应用到渲染顶点
if (attachV->_triangles && attachV->_triangles->verts) {
V2F_T2F_C4B* vertices = attachV->_triangles->verts;
auto& uvsVector = meshAttachment->getUVs();
int vertexCount = meshAttachment->getWorldVerticesLength() / 2;
// 确保顶点数量不超过实际可用顶点数
int actualVertexCount = (vertexCount < (int)(uvsVector.size() / 2)) ? vertexCount : (int)(uvsVector.size() / 2);
for (int i = 0; i < actualVertexCount; i++) {
// 直接使用updateUVs()计算后的UV坐标
vertices[i].texCoord.u = uvsVector[i * 2];
vertices[i].texCoord.v = uvsVector[i * 2 + 1];
}
}
// 关键步骤4: 更新骨架变换,确保渲染正确
_skeleton->updateWorldTransform();
}
else {
CCLOG("Warning: Unsupported attachment type for slot '%s'", slotName.c_str());
return;
}
CCLOG("Texture loaded successfully for slot '%s'", slotName.c_str());
}