创造你的世界
玩家与角色:提示
更改ZEPETO角色颜色和穿戴物品颜色
7min
本指南旨在帮助创建引人入胜的内容。
ZEPETO角色在运行时作为ZepetoCharacter对象实例化。
如果你检查ZepetoCharacter的结构,你会发现一个名为Zepeto Context的子对象。在Zepeto Context内部,还有一个名为body的对象。
通过在运行时使用脚本替换body对象的body(Clone)材质,你可以更改ZEPETO角色的颜色。
对于非动画头像,这种方法会改变整个面部和身体的颜色。
然而,对于动画头像,你还需要修改ANIME_BASEMODEL的body(Clone)材质,它是body对象的子对象。
请注意,材质替换在相同长度的材质数组中是可行的。
以下是一个示例代码,用于更改本地玩家的身体颜色。
确保实现逻辑,以便角色的颜色仅在角色加载后更改。
TypeScript
1import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
2import {LocalPlayer, SpawnInfo, ZepetoCharacter, ZepetoCharacterCreator, ZepetoPlayers} from "ZEPETO.Character.Controller";
3import {ZepetoPropertyFlag} from "Zepeto";
4import { GameObject, Material, Renderer, SkinnedMeshRenderer, Transform, WaitForSeconds } from 'UnityEngine';
5import { Button } from 'UnityEngine.UI';
6
7
8export default class ChangeSkinColor extends ZepetoScriptBehaviour {
9
10 public newColorMaterial : Material;
11 public changeColorButton : Button;
12 public originalColorButton : Button;
13
14 private _originalColorMaterial : Material;
15 private _originalAnimeMaterials : Material[];
16 private _animeRend : Renderer;
17 private _bodyRend : Renderer;
18 private _bodyRends : Renderer[];
19 private _localCharacter: ZepetoCharacter;
20
21 Start() {
22 // 找到本地玩家并将其设置为 _localCharacter
23 ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
24 this._localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
25 // 找到本地玩家的 zepeto 上下文的材质
26 this._bodyRend= this._localCharacter.Context.GetComponentInChildren<SkinnedMeshRenderer>();
27 // 存储原始材质
28 this._originalColorMaterial = this._bodyRend.material;
29
30
31 // 确定是否为动画头像并保存相关信息
32 this._bodyRends= this._localCharacter.GetComponentsInChildren<SkinnedMeshRenderer>();
33 this._bodyRends.forEach((currentRenderer) =>{
34 if(currentRenderer.name.includes("ANIME_BASEMODEL")){
35 this._animeRend = currentRenderer;
36 this._originalAnimeMaterials = this._animeRend.sharedMaterials;
37 }
38 });
39 });
40
41 // 按下按钮时替换为预设材质
42 this.changeColorButton.onClick.AddListener(() => {
43 if(this._localCharacter != null) {
44 this._bodyRend.material = this.newColorMaterial;
45
46 if(this._animeRend != null) {
47 let tempMaterials : Material[] = [this._animeRend.sharedMaterials[0],this._animeRend.sharedMaterials[1],this.newColorMaterial,this._animeRend.sharedMaterials[3]];
48 this._animeRend.sharedMaterials = tempMaterials;
49 }
50 }
51 });
52
53 // 按下按钮时返回原始材质
54 this.originalColorButton.onClick.AddListener(() => {
55 if(this._localCharacter != null) {
56 this._bodyRend.material = this._originalColorMaterial;
57
58 if(this._animeRend != null) {
59 this._animeRend.sharedMaterials = this._originalAnimeMaterials;
60 }
61 }
62 });
63 }
64}
- 更改身体材料可能导致ZEPETO头像的妆容无法正确显示。
磨损物品作为身体对象下的子对象实例化。
您可以从物品对象的材料部分检查每个物品应用的材料。
通过在运行时使用脚本替换材料,您可以更改物品的颜色。
下面是一个示例代码,用于更改本地玩家所穿戴的第一个物品的颜色。
确保在角色加载后才更改物品的颜色。
TypeScript
1import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
2import {LocalPlayer, ZepetoCharacter, ZepetoPlayers} from "ZEPETO.Character.Controller";
3import { GameObject, Material, Renderer, SkinnedMeshRenderer, Transform, WaitForSeconds } from 'UnityEngine';
4import { Button } from 'UnityEngine.UI';
5
6
7export default class ChangeSkinColor extends ZepetoScriptBehaviour {
8
9 public newColorMaterial : Material;
10 public changeColorButton : Button;
11 public originalColorButton : Button;
12
13 private _originalColorMaterial : Material;
14 private _body : GameObject;
15 private _itemRend : Renderer;
16 private _localCharacter: ZepetoCharacter;
17
18 Start() {
19 // 找到本地玩家并将其设置为 _localCharacter
20 ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
21 this._localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
22 // 访问本地玩家的 Zepeto 上下文的身体
23 this._body = this._localCharacter.Context.GetComponentInChildren<SkinnedMeshRenderer>().gameObject;
24 // 访问身体第一个子物品的材质
25 this._itemRend = this._body.transform.GetChild(0).GetComponent<SkinnedMeshRenderer>();
26 // 存储原始材质
27 this._originalColorMaterial = this._itemRend.material;
28 });
29
30 // 当按钮被按下时替换为预设材质
31 this.changeColorButton.onClick.AddListener(() => {
32 if(this._localCharacter != null) {
33 this._itemRend.material = this.newColorMaterial;
34 }
35 });
36
37 // 当按钮被按下时返回原始材质
38 this.originalColorButton.onClick.AddListener(() => {
39 if(this._localCharacter != null) {
40 this._itemRend.material = this._originalColorMaterial;
41 }
42 });
43 }
44}
- 代码解释
- this.body.transform.GetChild(0) 指的是所穿戴物品中的第一个物品,即索引为 0 的物品。
- 您可以将其调整为更改其他穿戴物品的颜色。
- 对于使用多个材质的物品,请记住材质替换需要相同长度的材质数组。
通过利用我们迄今为止获得的见解,您可以统一修改角色和所有物品的颜色。
这是一个示例代码,当点击“更改颜色”按钮时,会完全改变本地玩家角色和物品的颜色,当点击“原始颜色”按钮时,会恢复到原始颜色:
TypeScript
1import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
2import {LocalPlayer, ZepetoCharacter, ZepetoPlayers} from "ZEPETO.Character.Controller";
3import { GameObject, Material, Renderer, SkinnedMeshRenderer, Transform, WaitForSeconds } from 'UnityEngine';
4import { Button } from 'UnityEngine.UI';
5
6
7export default class ChangeAllMaterial extends ZepetoScriptBehaviour {
8
9 public newColorMaterial : Material;
10 public changeColorButton : Button;
11 public originalColorButton : Button;
12
13 private _originalMaterials : Material[] = new Array();
14 private _bodyRends : Renderer[];
15 private _localCharacter: ZepetoCharacter;
16
17 Start() {
18 // 找到本地玩家并将其设置为 _localCharacter
19 ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
20 this._localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
21
22 // 保存以保持原始材料
23 this._bodyRends= this._localCharacter.GetComponentsInChildren<SkinnedMeshRenderer>();
24 this._bodyRends.forEach((currentRenderer) =>{
25 for(let i=0; i<currentRenderer.sharedMaterials.length;i++){
26 this._originalMaterials.push(currentRenderer.sharedMaterials[i]);
27 }
28 });
29 });
30
31 // 当按钮被按下时用预设材料替换
32 this.changeColorButton.onClick.AddListener(() => {
33 if(this._localCharacter != null) {
34 this._bodyRends.forEach((currentRenderer) =>{
35 let tempMaterials : Material[] = new Array();
36 for(let i=0; i<currentRenderer.sharedMaterials.length;i++){
37 tempMaterials.push(this.newColorMaterial);
38 }
39 currentRenderer.sharedMaterials = tempMaterials;
40 });
41 }
42 });
43
44 // 当按钮被按下时返回到原始材料
45 this.originalColorButton.onClick.AddListener(() => {
46 if(this._localCharacter != null) {
47 let indexNum = 0;
48 this._bodyRends= this._localCharacter.GetComponentsInChildren<SkinnedMeshRenderer>();
49 this._bodyRends.forEach((currentRenderer) =>{
50 let tempMaterials : Material[] = new Array();
51 for(let i=0; i<currentRenderer.sharedMaterials.length;i++){
52 tempMaterials.push(this._originalMaterials[indexNum]);
53 indexNum++;
54 }
55 currentRenderer.sharedMaterials = tempMaterials;
56 });
57 }
58 });
59 }
60}
- 这种方法不仅适用于本地玩家,还适用于运行时创建的任何ZEPETO角色,包括NPC角色。
- 尽情发挥创意,以有趣的方式应用它!