更改ZEPETO角色颜色和穿戴物品颜色
7 分
本指南旨在帮助创建引人入胜的内容。
更改ZEPETO角色的颜色
ZEPETO角色在运行时作为ZepetoCharacter对象实例化。
如果你检查ZepetoCharacter的结构,你会发现一个名为Zepeto Context的子对象。在Zepeto Context内部,还有一个名为body的对象。
通过在运行时使用脚本替换body对象的body(Clone)材质,你可以更改ZEPETO角色的颜色。
对于非动画头像,这种方法会改变整个面部和身体的颜色。

然而,对于动画头像,你还需要修改ANIME_BASEMODEL的body(Clone)材质,它是body对象的子对象。
请注意,材质替换在相同长度的材质数组中是可行的。

以下是一个示例代码,用于更改本地玩家的身体颜色。
确保实现逻辑,以便角色的颜色仅在角色加载后更改。
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import {LocalPlayer, SpawnInfo, ZepetoCharacter, ZepetoCharacterCreator, ZepetoPlayers} from "ZEPETO.Character.Controller";
import {ZepetoPropertyFlag} from "Zepeto";
import { GameObject, Material, Renderer, SkinnedMeshRenderer, Transform, WaitForSeconds } from 'UnityEngine';
import { Button } from 'UnityEngine.UI';
export default class ChangeSkinColor extends ZepetoScriptBehaviour {
public newColorMaterial : Material;
public changeColorButton : Button;
public originalColorButton : Button;
private _originalColorMaterial : Material;
private _originalAnimeMaterials : Material[];
private _animeRend : Renderer;
private _bodyRend : Renderer;
private _bodyRends : Renderer[];
private _localCharacter: ZepetoCharacter;
Start() {
// 找到本地玩家并将其设置为 _localCharacter
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// 找到本地玩家的 zepeto 上下文的材质
this._bodyRend= this._localCharacter.Context.GetComponentInChildren<SkinnedMeshRenderer>();
// 存储原始材质
this._originalColorMaterial = this._bodyRend.material;
// 确定是否为动画头像并保存相关信息
this._bodyRends= this._localCharacter.GetComponentsInChildren<SkinnedMeshRenderer>();
this._bodyRends.forEach((currentRenderer) =>{
if(currentRenderer.name.includes("ANIME_BASEMODEL")){
this._animeRend = currentRenderer;
this._originalAnimeMaterials = this._animeRend.sharedMaterials;
}
});
});
// 按下按钮时替换为预设材质
this.changeColorButton.onClick.AddListener(() => {
if(this._localCharacter != null) {
this._bodyRend.material = this.newColorMaterial;
if(this._animeRend != null) {
let tempMaterials : Material[] = [this._animeRend.sharedMaterials[0],this._animeRend.sharedMaterials[1],this.newColorMaterial,this._animeRend.sharedMaterials[3]];
this._animeRend.sharedMaterials = tempMaterials;
}
}
});
// 按下按钮时返回原始材质
this.originalColorButton.onClick.AddListener(() => {
if(this._localCharacter != null) {
this._bodyRend.material = this._originalColorMaterial;
if(this._animeRend != null) {
this._animeRend.sharedMaterials = this._originalAnimeMaterials;
}
}
});
}
}

- 更改身体材料可能导致ZEPETO头像的妆容无法正确显示。
更改磨损物品的颜色
磨损物品作为身体对象下的子对象实例化。
您可以从物品对象的材料部分检查每个物品应用的材料。
通过在运行时使用脚本替换材料,您可以更改物品的颜色。

下面是一个示例代码,用于更改本地玩家所穿戴的第一个物品的颜色。
确保在角色加载后才更改物品的颜色。
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import {LocalPlayer, ZepetoCharacter, ZepetoPlayers} from "ZEPETO.Character.Controller";
import { GameObject, Material, Renderer, SkinnedMeshRenderer, Transform, WaitForSeconds } from 'UnityEngine';
import { Button } from 'UnityEngine.UI';
export default class ChangeSkinColor extends ZepetoScriptBehaviour {
public newColorMaterial : Material;
public changeColorButton : Button;
public originalColorButton : Button;
private _originalColorMaterial : Material;
private _body : GameObject;
private _itemRend : Renderer;
private _localCharacter: ZepetoCharacter;
Start() {
// 找到本地玩家并将其设置为 _localCharacter
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// 访问本地玩家的 Zepeto 上下文的身体
this._body = this._localCharacter.Context.GetComponentInChildren<SkinnedMeshRenderer>().gameObject;
// 访问身体第一个子物品的材质
this._itemRend = this._body.transform.GetChild(0).GetComponent<SkinnedMeshRenderer>();
// 存储原始材质
this._originalColorMaterial = this._itemRend.material;
});
// 当按钮被按下时替换为预设材质
this.changeColorButton.onClick.AddListener(() => {
if(this._localCharacter != null) {
this._itemRend.material = this.newColorMaterial;
}
});
// 当按钮被按下时返回原始材质
this.originalColorButton.onClick.AddListener(() => {
if(this._localCharacter != null) {
this._itemRend.material = this._originalColorMaterial;
}
});
}
}
- 代码解释
- this.body.transform.GetChild(0) 指的是所穿戴物品中的第一个物品,即索引为 0 的物品。
- 您可以将其调整为更改其他穿戴物品的颜色。
- 对于使用多个材质的物品,请记住材质替换需要相同长度的材质数组。

更改ZEPETO角色和所有物品的颜色
通过利用我们迄今为止获得的见解,您可以统一修改角色和所有物品的颜色。

这是一个示例代码,当点击“更改颜色”按钮时,会完全改变本地玩家角色和物品的颜色,当点击“原始颜色”按钮时,会恢复到原始颜色:
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import {LocalPlayer, ZepetoCharacter, ZepetoPlayers} from "ZEPETO.Character.Controller";
import { GameObject, Material, Renderer, SkinnedMeshRenderer, Transform, WaitForSeconds } from 'UnityEngine';
import { Button } from 'UnityEngine.UI';
export default class ChangeAllMaterial extends ZepetoScriptBehaviour {
public newColorMaterial : Material;
public changeColorButton : Button;
public originalColorButton : Button;
private _originalMaterials : Material[] = new Array();
private _bodyRends : Renderer[];
private _localCharacter: ZepetoCharacter;
Start() {
// 找到本地玩家并将其设置为 _localCharacter
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// 保存以保持原始材料
this._bodyRends= this._localCharacter.GetComponentsInChildren<SkinnedMeshRenderer>();
this._bodyRends.forEach((currentRenderer) =>{
for(let i=0; i<currentRenderer.sharedMaterials.length;i++){
this._originalMaterials.push(currentRenderer.sharedMaterials[i]);
}
});
});
// 当按钮被按下时用预设材料替换
this.changeColorButton.onClick.AddListener(() => {
if(this._localCharacter != null) {
this._bodyRends.forEach((currentRenderer) =>{
let tempMaterials : Material[] = new Array();
for(let i=0; i<currentRenderer.sharedMaterials.length;i++){
tempMaterials.push(this.newColorMaterial);
}
currentRenderer.sharedMaterials = tempMaterials;
});
}
});
// 当按钮被按下时返回到原始材料
this.originalColorButton.onClick.AddListener(() => {
if(this._localCharacter != null) {
let indexNum = 0;
this._bodyRends= this._localCharacter.GetComponentsInChildren<SkinnedMeshRenderer>();
this._bodyRends.forEach((currentRenderer) =>{
let tempMaterials : Material[] = new Array();
for(let i=0; i<currentRenderer.sharedMaterials.length;i++){
tempMaterials.push(this._originalMaterials[indexNum]);
indexNum++;
}
currentRenderer.sharedMaterials = tempMaterials;
});
}
});
}
}
- 这种方法不仅适用于本地玩家,还适用于运行时创建的任何ZEPETO角色,包括NPC角色。
- 尽情发挥创意,以有趣的方式应用它!