ZEPETO 캐릭터 색상 및 착용 중인 아이템 색상 변경하기
이 가이드는 매력적인 콘텐츠를 만드는 데 도움을 주기 위한 것입니다.
ZEPETO 캐릭터의 색상 변경
ZEPETO 캐릭터는 실행 시간에 ZepetoCharacter 객체로 인스턴스화됩니다.
ZepetoCharacter의 구조를 검사하면 Zepeto Context라는 하위 객체를 찾을 수 있습니다. Zepeto Context 내에는 body라는 또 다른 객체가 있습니다.
스크립트를 사용하여 실행 시간에 body 객체의 body(Clone) 재질을 교체하면 ZEPETO 캐릭터의 색상을 변경할 수 있습니다.
비애니메이션 아바타의 경우, 이 방법은 전체 얼굴과 몸의 색상을 변경합니다.

그러나 애니메이션 아바타의 경우, body 객체의 자식인 ANIME_BASEMODEL의 body(Clone) 재질도 수정해야 합니다.
재질 교체는 동일한 길이의 재질 배열로 가능하다는 점에 유의하십시오.

아래는 로컬 플레이어의 몸체 색상을 변경하는 샘플 코드입니다.
캐릭터가 로드된 후에만 캐릭터의 색상이 변경되도록 로직을 구현해야 합니다.
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() {
// Find the local player and Set it to _localCharacter
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// Find the material of the local player's zepeto context
this._bodyRend= this._localCharacter.Context.GetComponentInChildren<SkinnedMeshRenderer>();
// Store the original material
this._originalColorMaterial = this._bodyRend.material;
// Determine if it is an animated avatar and save related information
this._bodyRends= this._localCharacter.GetComponentsInChildren<SkinnedMeshRenderer>();
this._bodyRends.forEach((currentRenderer) =>{
if(currentRenderer.name.includes("ANIME_BASEMODEL")){
this._animeRend = currentRenderer;
this._originalAnimeMaterials = this._animeRend.sharedMaterials;
}
});
});
// Replace with the preset material when the button is pressed
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;
}
}
});
// Return to the original material when the button is pressed
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 캐릭터를 포함하여 적용할 수 있습니다.
- 창의력을 발휘하고 재미있는 방법으로 적용해 보세요!