当前位置: 首页 > article >正文

Unity3D仿星露谷物语开发60之定制角色其他部位

1、目标

上一篇中定制了角色的衬衫、手臂。

本篇中将定制角色其他部位的图形,包括:裤子、发型、皮肤、帽子等。

2、定制裤子

(1)修改ApplyCharacterCustomisation.cs脚本

我们需要设置一个输入框选择裤子的颜色。

 // Select Trouser Color[SerializeField] private Color inputTrouserColor = Color.blue;

 Color字段序列化之后,点击就会在编辑器中弹出一个颜色选择器。

目前角色的裤子颜色,基本上都是白色和灰色的,我们要做的是取那个被选中的颜色,在这些裤子上层绘制新的颜色。

添加新的处理方法:

添加如下方法:

    private void ProcessTrousers(){// Get trouser pixels to recolorColor[] farmerTrouserPixels = farmerBaseTexture.GetPixels(288, 0, 96, farmerBaseTexture.height);// Change trouser colorsTintPixelColors(farmerTrouserPixels, inputTrouserColor);// Set changed trouser pixelsfarmerBaseCustomised.SetPixels(288, 0, 96, farmerBaseTexture.height, farmerTrouserPixels);// Apply texture changesfarmerBaseCustomised.Apply();}private void TintPixelColors(Color[] basePixelArray, Color tintColor){// Loop through pixels to tintfor(int i = 0; i < basePixelArray.Length; i++){basePixelArray[i].r = basePixelArray[i].r * tintColor.r;basePixelArray[i].g = basePixelArray[i].g * tintColor.g;basePixelArray[i].b = basePixelArray[i].b * tintColor.b;}}

为了得到新的像素,我们将基础像素和色调颜色相乘。

在MergeCustomisations方法中,将farmerBaseTexture修改为farmerBaseCustomised。

(2)游戏效果

运行游戏后,查看以下文件,可以看到精灵表中裤子都换成了蓝色。

选择黄色裤子后,可以看到角色的裤子更新了。

3、定制发型

(1)修改ApplyCharacterCustomisation.cs脚本

添加1个输入:

在下面可以看到所有的发型信息:

这些发型没有颜色,只是白色和灰色的阴影。这里面有2种(列)发型,每种发型有3个方向的发型。

添加1个输出:

添加输入项:

添加发型的维度信息:

添加处理发型的方法:

添加处理方法:

    private void ProcessHair(){// Create Selected Hair TextureAddHairToTexture(inputHairStyleNo);// Get hair pixels to recolorColor[] farmerSelectedHairPixels = hairCustomised.GetPixels();// Tint hair pixelsTintPixelColors(farmerSelectedHairPixels, inputHairColor);hairCustomised.SetPixels(farmerSelectedHairPixels);hairCustomised.Apply();}private void AddHairToTexture(int hairStyleNo){// Calculate coordinates for hair pixelsint y = (hairStyleNo / hairStylesInSpriteWidth) * hairTextureHeight;int x = (hairStyleNo % hairStylesInSpriteWidth) * hairTextureWidth;// Get hair pixelsColor[] hairPixels = hairBaseTexture.GetPixels(x, y, hairTextureWidth, hairTextureHeight);// Apply selected hair pixels to texturehairCustomised.SetPixels(hairPixels);hairCustomised.Apply();}

(2)配置Player对象

配置CharacterCustomiser对象。

程序会从assets -> Sprites -> Output Textures中读取数据(真实有用,而不仅仅为了展示效果) 

反选hat避免遮挡发型。

(3)游戏效果

运行游戏,可以看到红色的新发型。

4、定制肤色

(1)修改ApplyCharacterCustomisation.cs脚本

定义要替换的皮肤颜色:

   // Target skin colours for color replacementprivate Color32 skinTargetColor1 = new Color32(145, 117, 90, 255); // darkestprivate Color32 skinTargetColor2 = new Color32(204, 155, 108, 255); // next darkestprivate Color32 skinTargetColor3 = new Color32(207, 166, 128, 255); // next darkestprivate Color32 skinTargetColor4 = new Color32(238, 195, 154, 255); // lightest

这4个颜色对应脸部、手掌上的颜色如下:

   

后面会用新定义的颜色来代替上面这些颜色。

增加新的函数如下:

    private void ProcessSkin(){// Get skin pixels to recolorColor[] farmerPixelsToRecolor = farmerBaseCustomised.GetPixels(0, 0, 288, farmerBaseTexture.height);// Populate Skin Color Swap ListPopulateSkinColorSwapList(inputSkinType);// Change skin colorsChangePixelColors(farmerPixelsToRecolor, colorSwapList);// Set recoloured pixelsfarmerBaseCustomised.SetPixels(0, 0, 288, farmerBaseTexture.height, farmerPixelsToRecolor);// Apply texture changesfarmerBaseCustomised.Apply();}private void PopulateSkinColorSwapList(int skinType){// Clear color swap listcolorSwapList.Clear();// Skin replacement colors//Switch on skin typeswitch(skinType){case 0:colorSwapList.Add(new colorSwap(skinTargetColor1, skinTargetColor1));colorSwapList.Add(new colorSwap(skinTargetColor2, skinTargetColor2));colorSwapList.Add(new colorSwap(skinTargetColor3, skinTargetColor3));colorSwapList.Add(new colorSwap(skinTargetColor4, skinTargetColor4));break;case 1:colorSwapList.Add(new colorSwap(skinTargetColor1, new Color32(187, 157, 128, 255)));colorSwapList.Add(new colorSwap(skinTargetColor2, new Color32(231, 187, 144, 255)));colorSwapList.Add(new colorSwap(skinTargetColor3, new Color32(221, 186, 154, 255)));colorSwapList.Add(new colorSwap(skinTargetColor4, new Color32(213, 189, 167, 255)));break;case 2:colorSwapList.Add(new colorSwap(skinTargetColor1, new Color32(105, 69, 2, 255)));colorSwapList.Add(new colorSwap(skinTargetColor2, new Color32(128, 87, 12, 255)));colorSwapList.Add(new colorSwap(skinTargetColor3, new Color32(145, 103, 26, 255)));colorSwapList.Add(new colorSwap(skinTargetColor4, new Color32(161, 114, 25, 255)));break;case 3:colorSwapList.Add(new colorSwap(skinTargetColor1, new Color32(151, 132, 0, 255)));colorSwapList.Add(new colorSwap(skinTargetColor2, new Color32(187, 166, 15, 255)));colorSwapList.Add(new colorSwap(skinTargetColor3, new Color32(209, 188, 39, 255)));colorSwapList.Add(new colorSwap(skinTargetColor4, new Color32(211, 199, 112, 255)));break;default:colorSwapList.Add(new colorSwap(skinTargetColor1, skinTargetColor1));colorSwapList.Add(new colorSwap(skinTargetColor2, skinTargetColor2));colorSwapList.Add(new colorSwap(skinTargetColor3, skinTargetColor3));colorSwapList.Add(new colorSwap(skinTargetColor4, skinTargetColor4));break;}}

(2)游戏效果

理论上脸部要发生颜色变化,实际上脸部颜色没有发生变化,尝试了修改skinTargetColor1~4也无果。

5、定制帽子

目前角色使用到的帽子的精灵图(output目录下)位于:

输入的帽子的精灵图位于:

目前只有一种帽子,此时构造2个选择:0没有帽子,1有帽子。

编写ApplyCharacterCustomisation.cs脚本:

    private void ProcessHat(){// Create Selected Hat TextureAddHatToTexture(inputHatStyleNo);}private void AddHatToTexture(int hatStyleNo){// Calculate coordinates for hat pixelsint y = (hatStyleNo / hatStylesInSpriteWidth) * hatTextureHeight;int x = (hatStyleNo % hatStylesInSpriteWidth) * hatTextureWidth;// Get hat pixelsColor[] hatPixels = hatsBaseTexture.GetPixels(x, y, hatTextureWidth, hatTextureHeight);// Apply selected hat pixels to texturehatsCustomised.SetPixels(hatPixels);hatsCustomised.Apply();}

配置CharacterCustomiser的信息:

运行游戏:

Select Hat Style=0时没有帽子:

Select Hat Style=1时有帽子:

6、定制角色装饰

目标:用户选择不同的装饰(0没有,1眼镜,2胡子)。

下面可以看到装饰信息:

第一个位置是空的,下一个位置为眼镜,再下一个位置是胡子。并且只有正面和侧面的图片。

 private void ProcessAdornments(){// Initialise body adornments offset arraybodyAdornmentsOffsetArray = new Vector2Int[bodyColumns, bodyRows];// Populate body adornments offset arrayPopulateBodyAdornmentsOffsetArray();// Create Selected Adornments TextureAddAdornmentsToTexture(inputAdornmentsStyleNo);// Create new adornments base texturefarmerBaseAdornmentsUpdated = new Texture2D(farmerBaseTexture.width, farmerBaseTexture.height);farmerBaseAdornmentsUpdated.filterMode = FilterMode.Point;// Set adornments base texture to transparentSetTextureToTransparent(farmerBaseAdornmentsUpdated);ApplyAdornmentsTextureToBase();}private void AddAdornmentsToTexture(int adornmentsStyleNo){// Create adornment textureselectedAdornment = new Texture2D(adornmentsTextureWidth, adornmentsTextureHeight);selectedAdornment.filterMode = FilterMode.Point;// Calculate coordinates for adornments pixelsint y = (adornmentsStyleNo / adornmentsStylesInSpriteWidth) * adornmentsTextureHeight;int x = (adornmentsStyleNo % adornmentsStylesInSpriteWidth) * adornmentsTextureWidth;// Get adornments pixelsColor[] adornmentsPixels = adornmentsBaseTexture.GetPixels(x, y, adornmentsTextureWidth, adornmentsTextureHeight);// Apply selected adornments pixels to textureselectedAdornment.SetPixels(adornmentsPixels);selectedAdornment.Apply();  }private void ApplyAdornmentsTextureToBase(){Color[] frontAdornmentsPixels;Color[] rightAdornmentsPixels;frontAdornmentsPixels = selectedAdornment.GetPixels(0, adornmentsSpriteHeight * 1, adornmentsSpriteWidth, adornmentsSpriteHeight);rightAdornmentsPixels = selectedAdornment.GetPixels(0, adornmentsSpriteHeight * 0, adornmentsSpriteWidth, adornmentsSpriteHeight);// Loop through base texture and apply adornments pixelsfor(int x = 0; x < bodyColumns; x++){for(int y = 0; y < bodyRows; y++){int pixelX = x * farmerSpriteWidth;int pixelY = y * farmerSpriteHeight;if (bodyAdornmentsOffsetArray[x, y] != null){pixelX += bodyAdornmentsOffsetArray[x, y].x;pixelY += bodyAdornmentsOffsetArray[x, y].y;}// Switch on facing directionswitch(bodyFacingArray[x, y]){case Facing.none:break;case Facing.front:// Populate front adornments pixelsfarmerBaseAdornmentsUpdated.SetPixels(pixelX, pixelY, adornmentsSpriteWidth, adornmentsSpriteHeight, frontAdornmentsPixels);break;case Facing.right:// Populate right adornments pixelsfarmerBaseAdornmentsUpdated.SetPixels(pixelX, pixelY, adornmentsSpriteWidth, adornmentsSpriteHeight, rightAdornmentsPixels);break;default:break;}}}// Apply adornments texture pixelsfarmerBaseAdornmentsUpdated.Apply();}

ApplyCharacterCustomisation.cs的完整代码如下:

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;[System.Serializable]
public class colorSwap
{public Color fromColor;public Color toColor;public colorSwap(Color fromColor, Color toColor){this.fromColor = fromColor;this.toColor = toColor;}
}public class ApplyCharacterCustomisation : MonoBehaviour
{// Input Textures[Header("Base Textures")][SerializeField] private Texture2D maleFarmerBaseTexture = null;[SerializeField] private Texture2D femaleFarmerBaseTexture = null;[SerializeField] private Texture2D shirtsBaseTexture = null;[SerializeField] private Texture2D hairBaseTexture = null;[SerializeField] private Texture2D hatsBaseTexture = null;[SerializeField] private Texture2D adornmentsBaseTexture = null;private Texture2D farmerBaseTexture;// Created Textures[Header("OutputBase Texture To Be Used For Animation")][SerializeField] private Texture2D farmerBaseCustomised = null;[SerializeField] private Texture2D hairCustomised = null;[SerializeField] private Texture2D hatsCustomised = null;private Texture2D farmerBaseShirtsUpdated;private Texture2D selectedShirt;private Texture2D farmerBaseAdornmentsUpdated;private Texture2D selectedAdornment;// Select Shirt style[Header("Select Shirt Style")][Range(0, 1)]   // 红色衬衫或者绿色衬衫[SerializeField] private int inputShirtStyleNo = 0;// Select Hair Style[Header("Select Hair Style")][Range(0, 2)][SerializeField] private int inputHairStyleNo = 0;// Select Hat Style[Header("Select Hat Style")][Range(0, 1)][SerializeField] private int inputHatStyleNo = 0;// Select Adornments Style[Header("Select Adornments Style")][Range(0, 2)][SerializeField] private int inputAdornmentsStyleNo = 0;// Select Skin Type[Header("Select Skin Type")][Range(0, 3)][SerializeField] private int inputSkinType = 0;// Select Hair Color[SerializeField] private Color inputHairColor = Color.black;// Selecct Sex[Header("Select Sex:0=Male, 1=female")][Range(0, 1)][SerializeField] private int inputSex = 0;// Select Trouser Color[SerializeField] private Color inputTrouserColor = Color.blue;private Facing[,] bodyFacingArray;private Vector2Int[,] bodyShirtOffsetArray;private Vector2Int[,] bodyAdornmentsOffsetArray;// 定义精灵表的维度信息private int bodyRows = 21;private int bodyColumns = 6;private int farmerSpriteWidth = 16;private int farmerSpriteHeight = 32;private int shirtTextureWidth = 9;private int shirtTextureHeight = 36;private int shirtSpriteWidth = 9;private int shirtSpriteHeight = 9;private int shirtStylesInSpriteWidth = 16;  // 纹理可以容纳衬衫的件数private int hairTextureWidth = 16;private int hairTextureHeight = 96;private int hairStylesInSpriteWidth = 8;  // 发型的最多数量private int hatTextureWidth = 20;private int hatTextureHeight = 80; // output中的hat的texture就是20*80大小private int hatStylesInSpriteWidth = 12; // 帽子的最多数量private int adornmentsTextureWidth = 16;private int adornmentsTextureHeight = 32;private int adornmentsStylesInSpriteWidth = 8;private int adornmentsSpriteWidth = 16;private int adornmentsSpriteHeight = 16;// 颜色交换列表private List<colorSwap> colorSwapList;// Target arm colours for color replacementprivate Color32 armTargetColor1 = new Color32(77, 13, 13, 255); // darkestprivate Color32 armTargetColor2 = new Color32(138, 41, 41, 255); // next darkestprivate Color32 armTargetColor3 = new Color32(172, 50, 50, 255); // lightest// Target skin colours for color replacementprivate Color32 skinTargetColor1 = new Color32(145, 117, 90, 255); // darkestprivate Color32 skinTargetColor2 = new Color32(204, 155, 108, 255); // next darkestprivate Color32 skinTargetColor3 = new Color32(207, 166, 128, 255); // next darkestprivate Color32 skinTargetColor4 = new Color32(238, 195, 154, 255); // lightestprivate void Awake(){// Initialise color swap listcolorSwapList = new List<colorSwap>();// Process CustomisationProcessCustomisation();}private void ProcessCustomisation(){ProcessGender();ProcessShirt();ProcessArms();ProcessTrousers();ProcessHair();ProcessSkin();ProcessHat();ProcessAdornments();MergeCustomisations();}private void ProcessGender(){// Set base spritesheet by genderif(inputSex == 0){farmerBaseTexture = maleFarmerBaseTexture;}else if(inputSex == 1){farmerBaseTexture = femaleFarmerBaseTexture;}// Get base pixelsColor[] farmerBasePixels = farmerBaseTexture.GetPixels();// Set changed base pixelsfarmerBaseCustomised.SetPixels(farmerBasePixels);farmerBaseCustomised.Apply();}private void ProcessShirt(){// Initialise body facing shirt arraybodyFacingArray = new Facing[bodyColumns, bodyRows];// Populate body facing shirt arrayPopulateBodyFacingArray();// Initialise body shirt offset arraybodyShirtOffsetArray = new Vector2Int[bodyColumns, bodyRows];// Populate body shirt offset arrayPopulateBodyShirtOffsetArray();// Create Selected Shirt TextureAddShirtToTexture(inputShirtStyleNo);// Apply shirt texture to baseApplyShirtTextureToBase();}private void ProcessArms(){// Get arm pixels to recolorColor[] farmerPixelsToRecolor = farmerBaseTexture.GetPixels(0, 0, 288, farmerBaseTexture.height);// Populate arm color swap listPopulateArmColorSwapList();// Change arm colorsChangePixelColors(farmerPixelsToRecolor, colorSwapList);// Set recolored pixelsfarmerBaseCustomised.SetPixels(0, 0, 288, farmerBaseTexture.height, farmerPixelsToRecolor);// Apply texture changesfarmerBaseCustomised.Apply();}private void ProcessTrousers(){// Get trouser pixels to recolorColor[] farmerTrouserPixels = farmerBaseTexture.GetPixels(288, 0, 96, farmerBaseTexture.height);// Change trouser colorsTintPixelColors(farmerTrouserPixels, inputTrouserColor);// Set changed trouser pixelsfarmerBaseCustomised.SetPixels(288, 0, 96, farmerBaseTexture.height, farmerTrouserPixels);// Apply texture changesfarmerBaseCustomised.Apply();}private void ProcessHair(){// Create Selected Hair TextureAddHairToTexture(inputHairStyleNo);// Get hair pixels to recolorColor[] farmerSelectedHairPixels = hairCustomised.GetPixels();// Tint hair pixelsTintPixelColors(farmerSelectedHairPixels, inputHairColor);hairCustomised.SetPixels(farmerSelectedHairPixels);hairCustomised.Apply();}private void ProcessSkin(){// Get skin pixels to recolorColor[] farmerPixelsToRecolor = farmerBaseCustomised.GetPixels(0, 0, 288, farmerBaseTexture.height);// Populate Skin Color Swap ListPopulateSkinColorSwapList(inputSkinType);// Change skin colorsChangePixelColors(farmerPixelsToRecolor, colorSwapList);// Set recoloured pixelsfarmerBaseCustomised.SetPixels(0, 0, 288, farmerBaseTexture.height, farmerPixelsToRecolor);// Apply texture changesfarmerBaseCustomised.Apply();}private void ProcessHat(){// Create Selected Hat TextureAddHatToTexture(inputHatStyleNo);}private void ProcessAdornments(){// Initialise body adornments offset arraybodyAdornmentsOffsetArray = new Vector2Int[bodyColumns, bodyRows];// Populate body adornments offset arrayPopulateBodyAdornmentsOffsetArray();// Create Selected Adornments TextureAddAdornmentsToTexture(inputAdornmentsStyleNo);// Create new adornments base texturefarmerBaseAdornmentsUpdated = new Texture2D(farmerBaseTexture.width, farmerBaseTexture.height);farmerBaseAdornmentsUpdated.filterMode = FilterMode.Point;// Set adornments base texture to transparentSetTextureToTransparent(farmerBaseAdornmentsUpdated);ApplyAdornmentsTextureToBase();}private void AddAdornmentsToTexture(int adornmentsStyleNo){// Create adornment textureselectedAdornment = new Texture2D(adornmentsTextureWidth, adornmentsTextureHeight);selectedAdornment.filterMode = FilterMode.Point;// Calculate coordinates for adornments pixelsint y = (adornmentsStyleNo / adornmentsStylesInSpriteWidth) * adornmentsTextureHeight;int x = (adornmentsStyleNo % adornmentsStylesInSpriteWidth) * adornmentsTextureWidth;// Get adornments pixelsColor[] adornmentsPixels = adornmentsBaseTexture.GetPixels(x, y, adornmentsTextureWidth, adornmentsTextureHeight);// Apply selected adornments pixels to textureselectedAdornment.SetPixels(adornmentsPixels);selectedAdornment.Apply();  }private void ApplyAdornmentsTextureToBase(){Color[] frontAdornmentsPixels;Color[] rightAdornmentsPixels;frontAdornmentsPixels = selectedAdornment.GetPixels(0, adornmentsSpriteHeight * 1, adornmentsSpriteWidth, adornmentsSpriteHeight);rightAdornmentsPixels = selectedAdornment.GetPixels(0, adornmentsSpriteHeight * 0, adornmentsSpriteWidth, adornmentsSpriteHeight);// Loop through base texture and apply adornments pixelsfor(int x = 0; x < bodyColumns; x++){for(int y = 0; y < bodyRows; y++){int pixelX = x * farmerSpriteWidth;int pixelY = y * farmerSpriteHeight;if (bodyAdornmentsOffsetArray[x, y] != null){pixelX += bodyAdornmentsOffsetArray[x, y].x;pixelY += bodyAdornmentsOffsetArray[x, y].y;}// Switch on facing directionswitch(bodyFacingArray[x, y]){case Facing.none:break;case Facing.front:// Populate front adornments pixelsfarmerBaseAdornmentsUpdated.SetPixels(pixelX, pixelY, adornmentsSpriteWidth, adornmentsSpriteHeight, frontAdornmentsPixels);break;case Facing.right:// Populate right adornments pixelsfarmerBaseAdornmentsUpdated.SetPixels(pixelX, pixelY, adornmentsSpriteWidth, adornmentsSpriteHeight, rightAdornmentsPixels);break;default:break;}}}// Apply adornments texture pixelsfarmerBaseAdornmentsUpdated.Apply();}private void AddHatToTexture(int hatStyleNo){// Calculate coordinates for hat pixelsint y = (hatStyleNo / hatStylesInSpriteWidth) * hatTextureHeight;int x = (hatStyleNo % hatStylesInSpriteWidth) * hatTextureWidth;// Get hat pixelsColor[] hatPixels = hatsBaseTexture.GetPixels(x, y, hatTextureWidth, hatTextureHeight);// Apply selected hat pixels to texturehatsCustomised.SetPixels(hatPixels);hatsCustomised.Apply();}private void PopulateSkinColorSwapList(int skinType){// Clear color swap listcolorSwapList.Clear();// Skin replacement colors//Switch on skin typeswitch(skinType){case 0:colorSwapList.Add(new colorSwap(skinTargetColor1, skinTargetColor1));colorSwapList.Add(new colorSwap(skinTargetColor2, skinTargetColor2));colorSwapList.Add(new colorSwap(skinTargetColor3, skinTargetColor3));colorSwapList.Add(new colorSwap(skinTargetColor4, skinTargetColor4));break;case 1:colorSwapList.Add(new colorSwap(skinTargetColor1, new Color32(187, 157, 128, 255)));colorSwapList.Add(new colorSwap(skinTargetColor2, new Color32(231, 187, 144, 255)));colorSwapList.Add(new colorSwap(skinTargetColor3, new Color32(221, 186, 154, 255)));colorSwapList.Add(new colorSwap(skinTargetColor4, new Color32(213, 189, 167, 255)));break;case 2:colorSwapList.Add(new colorSwap(skinTargetColor1, new Color32(105, 69, 2, 255)));colorSwapList.Add(new colorSwap(skinTargetColor2, new Color32(128, 87, 12, 255)));colorSwapList.Add(new colorSwap(skinTargetColor3, new Color32(145, 103, 26, 255)));colorSwapList.Add(new colorSwap(skinTargetColor4, new Color32(161, 114, 25, 255)));break;case 3:colorSwapList.Add(new colorSwap(skinTargetColor1, new Color32(151, 132, 0, 255)));colorSwapList.Add(new colorSwap(skinTargetColor2, new Color32(187, 166, 15, 255)));colorSwapList.Add(new colorSwap(skinTargetColor3, new Color32(209, 188, 39, 255)));colorSwapList.Add(new colorSwap(skinTargetColor4, new Color32(211, 199, 112, 255)));break;default:colorSwapList.Add(new colorSwap(skinTargetColor1, skinTargetColor1));colorSwapList.Add(new colorSwap(skinTargetColor2, skinTargetColor2));colorSwapList.Add(new colorSwap(skinTargetColor3, skinTargetColor3));colorSwapList.Add(new colorSwap(skinTargetColor4, skinTargetColor4));break;}}private void AddHairToTexture(int hairStyleNo){// Calculate coordinates for hair pixelsint y = (hairStyleNo / hairStylesInSpriteWidth) * hairTextureHeight;int x = (hairStyleNo % hairStylesInSpriteWidth) * hairTextureWidth;// Get hair pixelsColor[] hairPixels = hairBaseTexture.GetPixels(x, y, hairTextureWidth, hairTextureHeight);// Apply selected hair pixels to texturehairCustomised.SetPixels(hairPixels);hairCustomised.Apply();}private void TintPixelColors(Color[] basePixelArray, Color tintColor){// Loop through pixels to tintfor(int i = 0; i < basePixelArray.Length; i++){basePixelArray[i].r = basePixelArray[i].r * tintColor.r;basePixelArray[i].g = basePixelArray[i].g * tintColor.g;basePixelArray[i].b = basePixelArray[i].b * tintColor.b;}}private void MergeCustomisations(){// Farmer Shirt pixelsColor[] farmerShirtPixels = farmerBaseShirtsUpdated.GetPixels(0, 0, bodyColumns * farmerSpriteWidth, farmerBaseTexture.height);// Farmer Trouser PixelsColor[] farmerTrouserPixelsSelection = farmerBaseCustomised.GetPixels(288, 0, 96, farmerBaseTexture.height);// Farmer Adornments PixelsColor[] farmerAdornmentsPixels = farmerBaseAdornmentsUpdated.GetPixels(0, 0, bodyColumns * farmerSpriteWidth, farmerBaseTexture.height);// Farmer Body PixelsColor[] farmerBodyPixels = farmerBaseCustomised.GetPixels(0, 0, bodyColumns * farmerSpriteWidth, farmerBaseTexture.height);MergeColorArray(farmerBodyPixels, farmerTrouserPixelsSelection);MergeColorArray(farmerBodyPixels, farmerShirtPixels);MergeColorArray(farmerBodyPixels, farmerAdornmentsPixels);// Paste merged pixelsfarmerBaseCustomised.SetPixels(0, 0, bodyColumns * farmerSpriteWidth, farmerBaseTexture.height, farmerBodyPixels);// Apply texture changesfarmerBaseCustomised.Apply();}private void MergeColorArray(Color[] baseArray, Color[] mergeArray){for(int i = 0; i < baseArray.Length; i++){if (mergeArray[i].a > 0){// Merge array has colorif (mergeArray[i].a >= 1){// Fully replacebaseArray[i] = mergeArray[i];}else{// Interpolate colorsfloat alpha = mergeArray[i].a;baseArray[i].r += (mergeArray[i].r - baseArray[i].r) * alpha;baseArray[i].g += (mergeArray[i].g - baseArray[i].g) * alpha;baseArray[i].b += (mergeArray[i].b - baseArray[i].b) * alpha;baseArray[i].a += mergeArray[i].a;}}}}private void PopulateArmColorSwapList(){// Clear color swap listcolorSwapList.Clear();// Arms replacement colorscolorSwapList.Add(new colorSwap(armTargetColor1, selectedShirt.GetPixel(0, 7)));colorSwapList.Add(new colorSwap(armTargetColor2, selectedShirt.GetPixel(0, 6)));colorSwapList.Add(new colorSwap(armTargetColor3, selectedShirt.GetPixel(0, 5)));}private void ChangePixelColors(Color[] baseArray, List<colorSwap> colorSwapList){for(int i = 0; i < baseArray.Length; i++){// Loop through color swap listif(colorSwapList.Count > 0){for(int j = 0; j < colorSwapList.Count; j++){if (isSameColor(baseArray[i], colorSwapList[j].fromColor)){baseArray[i] = colorSwapList[j].toColor;}}}}}private bool isSameColor(Color color1, Color color2){if ((color1.r == color2.r) && (color1.g == color2.g) && (color1.b == color2.b) && (color1.a == color2.a)){return true;}else{return false;}}private void AddShirtToTexture(int shirtStyleNo){// Create shirt textureselectedShirt = new Texture2D(shirtTextureWidth, shirtTextureHeight);selectedShirt.filterMode = FilterMode.Point;// Calculate coordinates for shirt pixelsint y = (shirtStyleNo / shirtStylesInSpriteWidth) * shirtTextureHeight;int x = (shirtStyleNo % shirtStylesInSpriteWidth) * shirtTextureWidth;// Get shirts pixelsColor[] shirtPixels = shirtsBaseTexture.GetPixels(x, y, shirtTextureWidth, shirtTextureHeight);// Apply selected shirt pixels to textureselectedShirt.SetPixels(shirtPixels);selectedShirt.Apply();}private void ApplyShirtTextureToBase(){// Create new shirt base texturefarmerBaseShirtsUpdated = new Texture2D(farmerBaseTexture.width, farmerBaseTexture.height);farmerBaseShirtsUpdated.filterMode = FilterMode.Point;// Set shirt base texture to transparentSetTextureToTransparent(farmerBaseShirtsUpdated);Color[] frontShirtPixels;Color[] backShirtPixels;Color[] rightShirtPixels;frontShirtPixels = selectedShirt.GetPixels(0, shirtSpriteHeight * 3, shirtSpriteWidth, shirtSpriteHeight);backShirtPixels = selectedShirt.GetPixels(0, shirtSpriteHeight * 0, shirtSpriteWidth, shirtSpriteHeight);rightShirtPixels = selectedShirt.GetPixels(0, shirtSpriteHeight * 2, shirtSpriteWidth, shirtSpriteHeight);// Loop through base texture and apply shirt pixelsfor(int x = 0; x < bodyColumns; x++){for(int y = 0; y < bodyRows; y++){int pixelX = x * farmerSpriteWidth;int pixelY = y * farmerSpriteHeight;if (bodyShirtOffsetArray[x, y] != null){if (bodyShirtOffsetArray[x, y].x == 99 && bodyShirtOffsetArray[x, y].y == 99) // do not populate with shirtcontinue;pixelX += bodyShirtOffsetArray[x, y].x;pixelY += bodyShirtOffsetArray[x, y].y;}// Switch on facing directionswitch(bodyFacingArray[x, y]){case Facing.none:break;case Facing.front:// populate front shirt pixelsfarmerBaseShirtsUpdated.SetPixels(pixelX, pixelY, shirtSpriteWidth, shirtSpriteHeight, frontShirtPixels);break;case Facing.back:// populate back shirt pixelsfarmerBaseShirtsUpdated.SetPixels(pixelX, pixelY, shirtSpriteWidth, shirtSpriteHeight, backShirtPixels);break;case Facing.right:// populate right shirt pixelsfarmerBaseShirtsUpdated.SetPixels(pixelX, pixelY, shirtSpriteWidth, shirtSpriteHeight, rightShirtPixels);break;default:break;}}}// Apply shirt texture pixelsfarmerBaseShirtsUpdated.Apply();}private void SetTextureToTransparent(Texture2D texture2D){// fill texture with transparencyColor[] fill = new Color[texture2D.height * texture2D.width];for(int i = 0; i < fill.Length; i++){fill[i] = Color.clear;}texture2D.SetPixels(fill);}private void PopulateBodyFacingArray(){bodyFacingArray[0, 0] = Facing.none;bodyFacingArray[1, 0] = Facing.none;bodyFacingArray[2, 0] = Facing.none;bodyFacingArray[3, 0] = Facing.none;bodyFacingArray[4, 0] = Facing.none;bodyFacingArray[5, 0] = Facing.none;bodyFacingArray[0, 1] = Facing.none;bodyFacingArray[1, 1] = Facing.none;bodyFacingArray[2, 1] = Facing.none;bodyFacingArray[3, 1] = Facing.none;bodyFacingArray[4, 1] = Facing.none;bodyFacingArray[5, 1] = Facing.none;bodyFacingArray[0, 2] = Facing.none;bodyFacingArray[1, 2] = Facing.none;bodyFacingArray[2, 2] = Facing.none;bodyFacingArray[3, 2] = Facing.none;bodyFacingArray[4, 2] = Facing.none;bodyFacingArray[5, 2] = Facing.none;bodyFacingArray[0, 3] = Facing.none;bodyFacingArray[1, 3] = Facing.none;bodyFacingArray[2, 3] = Facing.none;bodyFacingArray[3, 3] = Facing.none;bodyFacingArray[4, 3] = Facing.none;bodyFacingArray[5, 3] = Facing.none;bodyFacingArray[0, 4] = Facing.none;bodyFacingArray[1, 4] = Facing.none;bodyFacingArray[2, 4] = Facing.none;bodyFacingArray[3, 4] = Facing.none;bodyFacingArray[4, 4] = Facing.none;bodyFacingArray[5, 4] = Facing.none;bodyFacingArray[0, 5] = Facing.none;bodyFacingArray[1, 5] = Facing.none;bodyFacingArray[2, 5] = Facing.none;bodyFacingArray[3, 5] = Facing.none;bodyFacingArray[4, 5] = Facing.none;bodyFacingArray[5, 5] = Facing.none;bodyFacingArray[0, 6] = Facing.none;bodyFacingArray[1, 6] = Facing.none;bodyFacingArray[2, 6] = Facing.none;bodyFacingArray[3, 6] = Facing.none;bodyFacingArray[4, 6] = Facing.none;bodyFacingArray[5, 6] = Facing.none;bodyFacingArray[0, 7] = Facing.none;bodyFacingArray[1, 7] = Facing.none;bodyFacingArray[2, 7] = Facing.none;bodyFacingArray[3, 7] = Facing.none;bodyFacingArray[4, 7] = Facing.none;bodyFacingArray[5, 7] = Facing.none;bodyFacingArray[0, 8] = Facing.none;bodyFacingArray[1, 8] = Facing.none;bodyFacingArray[2, 8] = Facing.none;bodyFacingArray[3, 8] = Facing.none;bodyFacingArray[4, 8] = Facing.none;bodyFacingArray[5, 8] = Facing.none;bodyFacingArray[0, 9] = Facing.none;bodyFacingArray[1, 9] = Facing.none;bodyFacingArray[2, 9] = Facing.none;bodyFacingArray[3, 9] = Facing.none;bodyFacingArray[4, 9] = Facing.none;bodyFacingArray[5, 9] = Facing.none;bodyFacingArray[0, 10] = Facing.back;bodyFacingArray[1, 10] = Facing.back;bodyFacingArray[2, 10] = Facing.right;bodyFacingArray[3, 10] = Facing.right;bodyFacingArray[4, 10] = Facing.right;bodyFacingArray[5, 10] = Facing.right;bodyFacingArray[0, 11] = Facing.front;bodyFacingArray[1, 11] = Facing.front;bodyFacingArray[2, 11] = Facing.front;bodyFacingArray[3, 11] = Facing.front;bodyFacingArray[4, 11] = Facing.back;bodyFacingArray[5, 11] = Facing.back;bodyFacingArray[0, 12] = Facing.back;bodyFacingArray[1, 12] = Facing.back;bodyFacingArray[2, 12] = Facing.right;bodyFacingArray[3, 12] = Facing.right;bodyFacingArray[4, 12] = Facing.right;bodyFacingArray[5, 12] = Facing.right;bodyFacingArray[0, 13] = Facing.front;bodyFacingArray[1, 13] = Facing.front;bodyFacingArray[2, 13] = Facing.front;bodyFacingArray[3, 13] = Facing.front;bodyFacingArray[4, 13] = Facing.back;bodyFacingArray[5, 13] = Facing.back;bodyFacingArray[0, 14] = Facing.back;bodyFacingArray[1, 14] = Facing.back;bodyFacingArray[2, 14] = Facing.right;bodyFacingArray[3, 14] = Facing.right;bodyFacingArray[4, 14] = Facing.right;bodyFacingArray[5, 14] = Facing.right;bodyFacingArray[0, 15] = Facing.front;bodyFacingArray[1, 15] = Facing.front;bodyFacingArray[2, 15] = Facing.front;bodyFacingArray[3, 15] = Facing.front;bodyFacingArray[4, 15] = Facing.back;bodyFacingArray[5, 15] = Facing.back;bodyFacingArray[0, 16] = Facing.back;bodyFacingArray[1, 16] = Facing.back;bodyFacingArray[2, 16] = Facing.right;bodyFacingArray[3, 16] = Facing.right;bodyFacingArray[4, 16] = Facing.right;bodyFacingArray[5, 16] = Facing.right;bodyFacingArray[0, 17] = Facing.front;bodyFacingArray[1, 17] = Facing.front;bodyFacingArray[2, 17] = Facing.front;bodyFacingArray[3, 17] = Facing.front;bodyFacingArray[4, 17] = Facing.back;bodyFacingArray[5, 17] = Facing.back;bodyFacingArray[0, 18] = Facing.back;bodyFacingArray[1, 18] = Facing.back;bodyFacingArray[2, 18] = Facing.back;bodyFacingArray[3, 18] = Facing.right;bodyFacingArray[4, 18] = Facing.right;bodyFacingArray[5, 18] = Facing.right;bodyFacingArray[0, 19] = Facing.right;bodyFacingArray[1, 19] = Facing.right;bodyFacingArray[2, 19] = Facing.right;bodyFacingArray[3, 19] = Facing.front;bodyFacingArray[4, 19] = Facing.front;bodyFacingArray[5, 19] = Facing.front;bodyFacingArray[0, 20] = Facing.front;bodyFacingArray[1, 20] = Facing.front;bodyFacingArray[2, 20] = Facing.front;bodyFacingArray[3, 20] = Facing.back;bodyFacingArray[4, 20] = Facing.back;bodyFacingArray[5, 20] = Facing.back;}private void PopulateBodyShirtOffsetArray(){bodyShirtOffsetArray[0, 0] = new Vector2Int(99, 99);bodyShirtOffsetArray[1, 0] = new Vector2Int(99, 99);bodyShirtOffsetArray[2, 0] = new Vector2Int(99, 99);bodyShirtOffsetArray[3, 0] = new Vector2Int(99, 99);bodyShirtOffsetArray[4, 0] = new Vector2Int(99, 99);bodyShirtOffsetArray[5, 0] = new Vector2Int(99, 99);bodyShirtOffsetArray[0, 1] = new Vector2Int(99, 99);bodyShirtOffsetArray[1, 1] = new Vector2Int(99, 99);bodyShirtOffsetArray[2, 1] = new Vector2Int(99, 99);bodyShirtOffsetArray[3, 1] = new Vector2Int(99, 99);bodyShirtOffsetArray[4, 1] = new Vector2Int(99, 99);bodyShirtOffsetArray[5, 1] = new Vector2Int(99, 99);bodyShirtOffsetArray[0, 2] = new Vector2Int(99, 99);bodyShirtOffsetArray[1, 2] = new Vector2Int(99, 99);bodyShirtOffsetArray[2, 2] = new Vector2Int(99, 99);bodyShirtOffsetArray[3, 2] = new Vector2Int(99, 99);bodyShirtOffsetArray[4, 2] = new Vector2Int(99, 99);bodyShirtOffsetArray[5, 2] = new Vector2Int(99, 99);bodyShirtOffsetArray[0, 3] = new Vector2Int(99, 99);bodyShirtOffsetArray[1, 3] = new Vector2Int(99, 99);bodyShirtOffsetArray[2, 3] = new Vector2Int(99, 99);bodyShirtOffsetArray[3, 3] = new Vector2Int(99, 99);bodyShirtOffsetArray[4, 3] = new Vector2Int(99, 99);bodyShirtOffsetArray[5, 3] = new Vector2Int(99, 99);bodyShirtOffsetArray[0, 4] = new Vector2Int(99, 99);bodyShirtOffsetArray[1, 4] = new Vector2Int(99, 99);bodyShirtOffsetArray[2, 4] = new Vector2Int(99, 99);bodyShirtOffsetArray[3, 4] = new Vector2Int(99, 99);bodyShirtOffsetArray[4, 4] = new Vector2Int(99, 99);bodyShirtOffsetArray[5, 4] = new Vector2Int(99, 99);bodyShirtOffsetArray[0, 5] = new Vector2Int(99, 99);bodyShirtOffsetArray[1, 5] = new Vector2Int(99, 99);bodyShirtOffsetArray[2, 5] = new Vector2Int(99, 99);bodyShirtOffsetArray[3, 5] = new Vector2Int(99, 99);bodyShirtOffsetArray[4, 5] = new Vector2Int(99, 99);bodyShirtOffsetArray[5, 5] = new Vector2Int(99, 99);bodyShirtOffsetArray[0, 6] = new Vector2Int(99, 99);bodyShirtOffsetArray[1, 6] = new Vector2Int(99, 99);bodyShirtOffsetArray[2, 6] = new Vector2Int(99, 99);bodyShirtOffsetArray[3, 6] = new Vector2Int(99, 99);bodyShirtOffsetArray[4, 6] = new Vector2Int(99, 99);bodyShirtOffsetArray[5, 6] = new Vector2Int(99, 99);bodyShirtOffsetArray[0, 7] = new Vector2Int(99, 99);bodyShirtOffsetArray[1, 7] = new Vector2Int(99, 99);bodyShirtOffsetArray[2, 7] = new Vector2Int(99, 99);bodyShirtOffsetArray[3, 7] = new Vector2Int(99, 99);bodyShirtOffsetArray[4, 7] = new Vector2Int(99, 99);bodyShirtOffsetArray[5, 7] = new Vector2Int(99, 99);bodyShirtOffsetArray[0, 8] = new Vector2Int(99, 99);bodyShirtOffsetArray[1, 8] = new Vector2Int(99, 99);bodyShirtOffsetArray[2, 8] = new Vector2Int(99, 99);bodyShirtOffsetArray[3, 8] = new Vector2Int(99, 99);bodyShirtOffsetArray[4, 8] = new Vector2Int(99, 99);bodyShirtOffsetArray[5, 8] = new Vector2Int(99, 99);bodyShirtOffsetArray[0, 9] = new Vector2Int(99, 99);bodyShirtOffsetArray[1, 9] = new Vector2Int(99, 99);bodyShirtOffsetArray[2, 9] = new Vector2Int(99, 99);bodyShirtOffsetArray[3, 9] = new Vector2Int(99, 99);bodyShirtOffsetArray[4, 9] = new Vector2Int(99, 99);bodyShirtOffsetArray[5, 9] = new Vector2Int(99, 99);bodyShirtOffsetArray[0, 10] = new Vector2Int(4, 11);bodyShirtOffsetArray[1, 10] = new Vector2Int(4, 10);bodyShirtOffsetArray[2, 10] = new Vector2Int(4, 11);bodyShirtOffsetArray[3, 10] = new Vector2Int(4, 12);bodyShirtOffsetArray[4, 10] = new Vector2Int(4, 11);bodyShirtOffsetArray[5, 10] = new Vector2Int(4, 10);bodyShirtOffsetArray[0, 11] = new Vector2Int(4, 11);bodyShirtOffsetArray[1, 11] = new Vector2Int(4, 12);bodyShirtOffsetArray[2, 11] = new Vector2Int(4, 11);bodyShirtOffsetArray[3, 11] = new Vector2Int(4, 10);bodyShirtOffsetArray[4, 11] = new Vector2Int(4, 11);bodyShirtOffsetArray[5, 11] = new Vector2Int(4, 12);bodyShirtOffsetArray[0, 12] = new Vector2Int(3, 9);bodyShirtOffsetArray[1, 12] = new Vector2Int(3, 9);bodyShirtOffsetArray[2, 12] = new Vector2Int(4, 10);bodyShirtOffsetArray[3, 12] = new Vector2Int(4, 9);bodyShirtOffsetArray[4, 12] = new Vector2Int(4, 9);bodyShirtOffsetArray[5, 12] = new Vector2Int(4, 9);bodyShirtOffsetArray[0, 13] = new Vector2Int(4, 10);bodyShirtOffsetArray[1, 13] = new Vector2Int(4, 9);bodyShirtOffsetArray[2, 13] = new Vector2Int(5, 9);bodyShirtOffsetArray[3, 13] = new Vector2Int(5, 9);bodyShirtOffsetArray[4, 13] = new Vector2Int(4, 10);bodyShirtOffsetArray[5, 13] = new Vector2Int(4, 9);bodyShirtOffsetArray[0, 14] = new Vector2Int(4, 9);bodyShirtOffsetArray[1, 14] = new Vector2Int(4, 12);bodyShirtOffsetArray[2, 14] = new Vector2Int(5, 7);bodyShirtOffsetArray[3, 14] = new Vector2Int(5, 5);bodyShirtOffsetArray[4, 14] = new Vector2Int(4, 9);bodyShirtOffsetArray[5, 14] = new Vector2Int(4, 12);bodyShirtOffsetArray[0, 15] = new Vector2Int(4, 8);bodyShirtOffsetArray[1, 15] = new Vector2Int(4, 5);bodyShirtOffsetArray[2, 15] = new Vector2Int(4, 9);bodyShirtOffsetArray[3, 15] = new Vector2Int(4, 12);bodyShirtOffsetArray[4, 15] = new Vector2Int(4, 8);bodyShirtOffsetArray[5, 15] = new Vector2Int(4, 5);bodyShirtOffsetArray[0, 16] = new Vector2Int(4, 9);bodyShirtOffsetArray[1, 16] = new Vector2Int(4, 10);bodyShirtOffsetArray[2, 16] = new Vector2Int(4, 7);bodyShirtOffsetArray[3, 16] = new Vector2Int(4, 8);bodyShirtOffsetArray[4, 16] = new Vector2Int(4, 9);bodyShirtOffsetArray[5, 16] = new Vector2Int(4, 10);bodyShirtOffsetArray[0, 17] = new Vector2Int(4, 7);bodyShirtOffsetArray[1, 17] = new Vector2Int(4, 8);bodyShirtOffsetArray[2, 17] = new Vector2Int(4, 9);bodyShirtOffsetArray[3, 17] = new Vector2Int(4, 10);bodyShirtOffsetArray[4, 17] = new Vector2Int(4, 7);bodyShirtOffsetArray[5, 17] = new Vector2Int(4, 8);bodyShirtOffsetArray[0, 18] = new Vector2Int(4, 10);bodyShirtOffsetArray[1, 18] = new Vector2Int(4, 9);bodyShirtOffsetArray[2, 18] = new Vector2Int(4, 9);bodyShirtOffsetArray[3, 18] = new Vector2Int(4, 10);bodyShirtOffsetArray[4, 18] = new Vector2Int(4, 9);bodyShirtOffsetArray[5, 18] = new Vector2Int(4, 9);bodyShirtOffsetArray[0, 19] = new Vector2Int(4, 10);bodyShirtOffsetArray[1, 19] = new Vector2Int(4, 9);bodyShirtOffsetArray[2, 19] = new Vector2Int(4, 9);bodyShirtOffsetArray[3, 19] = new Vector2Int(4, 10);bodyShirtOffsetArray[4, 19] = new Vector2Int(4, 9);bodyShirtOffsetArray[5, 19] = new Vector2Int(4, 9);bodyShirtOffsetArray[0, 20] = new Vector2Int(4, 10);bodyShirtOffsetArray[1, 20] = new Vector2Int(4, 9);bodyShirtOffsetArray[2, 20] = new Vector2Int(4, 9);bodyShirtOffsetArray[3, 20] = new Vector2Int(4, 10);bodyShirtOffsetArray[4, 20] = new Vector2Int(4, 9);bodyShirtOffsetArray[5, 20] = new Vector2Int(4, 9);}private void PopulateBodyAdornmentsOffsetArray(){bodyAdornmentsOffsetArray[0, 1] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 1] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 1] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[3, 1] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[4, 1] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 1] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 2] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 2] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 2] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[3, 2] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[4, 2] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 2] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 3] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 3] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 3] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[3, 3] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[4, 3] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 3] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 4] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 4] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 4] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[3, 4] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[4, 4] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 4] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 5] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 5] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 5] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[3, 5] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[4, 5] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 5] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 6] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 6] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 6] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[3, 6] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[4, 6] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 6] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 7] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 7] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 7] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[3, 7] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[4, 7] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 7] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 8] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 8] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 8] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[3, 8] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[4, 8] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 8] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 9] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 9] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 9] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[3, 9] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[4, 9] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 9] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 10] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 10] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 10] = new Vector2Int(0, 1 + 16);bodyAdornmentsOffsetArray[3, 10] = new Vector2Int(0, 2 + 16);bodyAdornmentsOffsetArray[4, 10] = new Vector2Int(0, 1 + 16);bodyAdornmentsOffsetArray[5, 10] = new Vector2Int(0, 0 + 16);bodyAdornmentsOffsetArray[0, 11] = new Vector2Int(0, 1 + 16);bodyAdornmentsOffsetArray[1, 11] = new Vector2Int(0, 2 + 16);bodyAdornmentsOffsetArray[2, 11] = new Vector2Int(0, 1 + 16);bodyAdornmentsOffsetArray[3, 11] = new Vector2Int(0, 0 + 16);bodyAdornmentsOffsetArray[4, 11] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 11] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 12] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 12] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 12] = new Vector2Int(0, 0 + 16);bodyAdornmentsOffsetArray[3, 12] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[4, 12] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[5, 12] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[0, 13] = new Vector2Int(0, 0 + 16);bodyAdornmentsOffsetArray[1, 13] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[2, 13] = new Vector2Int(1, -1 + 16);bodyAdornmentsOffsetArray[3, 13] = new Vector2Int(1, -1 + 16);bodyAdornmentsOffsetArray[4, 13] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 13] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 14] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 14] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 14] = new Vector2Int(0, -3 + 16);bodyAdornmentsOffsetArray[3, 14] = new Vector2Int(0, -5 + 16);bodyAdornmentsOffsetArray[4, 14] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[5, 14] = new Vector2Int(0, 1 + 16);bodyAdornmentsOffsetArray[0, 15] = new Vector2Int(0, -2 + 16);bodyAdornmentsOffsetArray[1, 15] = new Vector2Int(0, -5 + 16);bodyAdornmentsOffsetArray[2, 15] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[3, 15] = new Vector2Int(0, 2 + 16);bodyAdornmentsOffsetArray[4, 15] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 15] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 16] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 16] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 16] = new Vector2Int(0, -3 + 16);bodyAdornmentsOffsetArray[3, 16] = new Vector2Int(0, -2 + 16);bodyAdornmentsOffsetArray[4, 16] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[5, 16] = new Vector2Int(0, 0 + 16);bodyAdornmentsOffsetArray[0, 17] = new Vector2Int(0, -3 + 16);bodyAdornmentsOffsetArray[1, 17] = new Vector2Int(0, -2 + 16);bodyAdornmentsOffsetArray[2, 17] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[3, 17] = new Vector2Int(0, 0 + 16);bodyAdornmentsOffsetArray[4, 17] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 17] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[0, 18] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[1, 18] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[2, 18] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[3, 18] = new Vector2Int(0, 0 + 16);bodyAdornmentsOffsetArray[4, 18] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[5, 18] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[0, 19] = new Vector2Int(0, 0 + 16);bodyAdornmentsOffsetArray[1, 19] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[2, 19] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[3, 19] = new Vector2Int(0, 0 + 16);bodyAdornmentsOffsetArray[4, 19] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[5, 19] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[0, 20] = new Vector2Int(0, 0 + 16);bodyAdornmentsOffsetArray[1, 20] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[2, 20] = new Vector2Int(0, -1 + 16);bodyAdornmentsOffsetArray[3, 20] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[4, 20] = new Vector2Int(99, 99);bodyAdornmentsOffsetArray[5, 20] = new Vector2Int(99, 99);}}

运行效果:

Select Adornments Style=1时:

Select Adornments Style=2时:

相关文章:

Unity3D仿星露谷物语开发60之定制角色其他部位

1、目标 上一篇中定制了角色的衬衫、手臂。 本篇中将定制角色其他部位的图形&#xff0c;包括&#xff1a;裤子、发型、皮肤、帽子等。 2、定制裤子 &#xff08;1&#xff09;修改ApplyCharacterCustomisation.cs脚本 我们需要设置一个输入框选择裤子的颜色。 // Select …...

C++动态链接库封装,供C#/C++ 等编程语言使用——C++动态链接库概述(总)

目录&#xff1a; 一、前言及背景1.1需求描述1.2常见编程语言对比1.3应用背景 二、C对外接口2.1C对外封装2.2基于目标平台封装接口形式 三、系列文章汇总 一、前言及背景 1.1需求描述 不同的编程语言&#xff0c;具有不同的编程生态环境&#xff0c;对于项目应用来说&#xff…...

Google机器学习实践指南(机器学习模型泛化能力)

&#x1f525; Google机器学习(14)-机器学习模型泛化能力解析 Google机器学习(14)-机器学习模型泛化原理与优化&#xff08;约10分钟&#xff09; 一、泛化问题引入 ▲ 模型表现对比&#xff1a; 假设森林中树木健康状况预测模型&#xff1a; 图1&#xff1a;初始模型表现 …...

MySQL性能调优:Mysql8高频面试题汇总

1&#xff0c;主键和唯一键有什么区别&#xff1f; 主键不能重复&#xff0c;不能为空&#xff0c;唯一键不能重复&#xff0c;可以为空。 建立主键的目的是让外键来引用。 一个表最多只有一个主键&#xff0c;但可以有很多唯一键 2&#xff0c;MySQL常用的存储引擎有哪些&…...

Neo4j 数据建模:原理、技术与实践指南

Neo4j 作为领先的图数据库,其核心优势在于利用图结构直观地表达和高效地查询复杂关系。其数据建模理念与传统关系型数据库截然不同,专注于实体(节点)及其连接(关系)。以下基于官方文档,系统阐述其建模原理、关键技术、实用技巧及最佳实践: 一、 核心原理:以关系为中心…...

【数据结构知识分享】顺序表详解

一、存储结构 物理相邻性&#xff1a; 若元素 a 和 b 逻辑相邻&#xff0c;则它们在内存中的地址也连续&#xff08;如 &a[i1] &a[i] sizeof(ElemType)&#xff09;。 内存布局x&#xff1a; 基地址 索引 元素大小&#xff0c;通过首地址直接计算任意位置地址。 …...

vue+elementUI+springboot实现文件合并前端展示文件类型

项目场景&#xff1a; element的table上传文件并渲染出文件名称点击所属行可以查看文件,并且可以导出合并文件,此文章是记录合并文档前端展示的帖子 解决方案&#xff1a; 后端定义三个工具类 分别是pdf,doc和word的excle的目前我没整 word的工具类 package com.sc.modules…...

高效绘制业务流程图!专业模板免费下载

在复杂的业务流程管理中&#xff0c;可视化工具已成为提升效能的核心基础设施。为助力开发者、项目经理及业务架构师高效落地流程标准化&#xff0c;本文将为你精选5套开箱即用的专业流程图模板。这些模板覆盖跨部门协作、电商订单、客户服务等高频场景&#xff0c;具备以下核心…...

Spring Boot + Prometheus 实现应用监控(基于 Actuator 和 Micrometer)

文章目录 Spring Boot Prometheus 实现应用监控&#xff08;基于 Actuator 和 Micrometer&#xff09;环境准备示例结构启动和验证验证 Spring Boot 应用Prometheus 抓取配置&#xff08;静态方式&#xff09;Grafana 面板配置总结 Spring Boot Prometheus 实现应用监控&…...

PowerBI企业运营分析—列互换式中国式报表分析

PowerBI企业运营分析—列互换式中国式报表分析 欢迎来到Powerbi小课堂&#xff0c;在竞争激烈的市场环境中&#xff0c;企业运营分析平台成为提升竞争力的核心工具。 该平台通过高效整合多源数据&#xff0c;并实时监控关键指标&#xff0c;能够迅速揭示业务表现的全貌&#…...

BugKu Web渗透之需要管理员

启动场景&#xff0c;打开网页&#xff0c;显示如下&#xff1a; 一般没有上面头绪的时候&#xff0c;就是两步&#xff1a;右键查看源代码 和 扫描网站目录。 步骤一&#xff1a; 右键查看源代码 和 扫描网站目录。 右键查看源代码没有发现异常。 于是扫描网站目录&…...

Java集合初始化:Lists.newArrayList vs new ArrayList()

文章目录 前言一、核心区别全景图二、代码实现深度对比1. 初始化方式对比2. 容量预分配机制 三、性能与底层原理1. 内存分配策略2. 基准测试数据&#xff08;JMH&#xff09; 四、Guava的进阶功能生态1. 集合转换2. 集合分片3. 不可变集合创建 五、最佳实践指南六、源码级实现解…...

VBA清空数据

列数转字母 Function CNtoW(ByVal num As Long) As String CNtoW Replace(Cells(1, num).Address(False, False), "1", "") End Function 字母转列数 Function CWtoN(ByVal AB As String) As Long CWtoN Range("a1:" & AB & &…...

【信息系统项目管理师-选择真题】2025上半年(第二批)综合知识答案和详解(回忆版)

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20题】【第…...

Java Lambda 表达式的缺点和替代方案

Java 8 引入的 Lambda 表达式曾被誉为编写简洁、函数式代码的革命性工具。但说实话,它们并不是万能钥匙。它有不少问题,比如它没有宣传的那么易读,在某些场景下还带来性能开销。 作为一名多年与 Java 冗长语法搏斗的开发者,我找到了更注重清晰、可维护性和性能的替代方案。…...

TDengine 开发指南—— UDF函数

UDF 简介 在某些应用场景中&#xff0c;应用逻辑需要的查询功能无法直接使用内置函数来实现&#xff0c;TDengine 允许编写用户自定义函数&#xff08;UDF&#xff09;&#xff0c;以便解决特殊应用场景中的使用需求。UDF 在集群中注册成功后&#xff0c;可以像系统内置函数一…...

使用vsftpd搭建FTP服务器(TLS/SSL显式加密)

安装vsftpd服务 使用vsftpd RPM安装包安装即可&#xff0c;如果可以访问YUM镜像源&#xff0c;通过dnf或者yum工具更加方便。 yum -y install vsftpd 启动vsftpd、查看服务状态 systemctl enable vsftpd systemctl start vsftpd systemctl status vsftpd 备份配置文件并进…...

1.1Nodejs和浏览器中的二进制处理

Buffer 在 Node.js 中&#xff0c;Buffer 类用于处理二进制数据。由于 JavaScript 在浏览器环境中主要用于处理字符串和数字等类型的数据&#xff0c;对二进制数据的处理能力较弱&#xff0c;因此 Node.js 引入了 Buffer 类来弥补这一不足&#xff0c;特别是在处理文件系统操作…...

入门AJAX——XMLHttpRequest(Post)

一、前言 在上篇文章中&#xff0c;我们已经介绍了 HMLHttpRequest 的GET 请求的基本用法&#xff0c;并基于我提供的接口练习了两个简单的例子。如果你还没有看过第一篇文章&#xff0c;强烈建议你在学习完上篇文章后再学习本篇文章&#xff1a; &#x1f517;入门AJAX——XM…...

Qt(part1)Qpushbutton,信号与槽,对象树,自定义信号与槽,lamda表达式。

1、创建Qt程序 2、命名规范及快捷键 3、Qpushbutton按钮创建 4、对象树概念 5、信号与槽 6、自定义信号与槽 7、当自定义信号和槽发生重载时 8、信号可以连接信号&#xff0c;信号也可以断开。 9、lamda表达式...

西北某省级联通公司:3D动环模块如何实现机房“一屏统管”?

一、运营商机房监控痛点凸显 在通信行业快速发展的当下&#xff0c;西北某省级联通公司肩负着保障区域通信畅通的重任。然而&#xff0c;公司分布广泛的机房面临着诸多监控难题&#xff0c;尤其是偏远机房环境风险无法实时感知这一痛点&#xff0c;严重影响了机房的稳定运行和通…...

【WPF】从普通 ItemsControl 到支持筛选的 ItemsControl:深入掌握 CollectionViewSource 用法

✨ 从普通 ItemsControl 到支持筛选的 ItemsControl&#xff1a;深入掌握 CollectionViewSource 用法 在日常 WPF 开发中&#xff0c;我们经常需要对数据进行筛选、排序、分组等操作&#xff0c;而原生的 ItemsControl 并不直接支持这些功能。本文将介绍如何通过 CollectionVi…...

Zookeeper 和 Kafka 版本与 JDK 要求

Apache Zookeeper 和 Apache Kafka 在不同版本中对 JDK 的要求如下表所示(基于官方文档和历史版本记录整理): 1. Zookeeper 版本与 JDK 要求 Zookeeper 版本要求的最低 JDK 版本说明3.4.x 系列JDK 6生产环境建议用 JDK 8(旧版兼容性强)。3.5.x 系列(3.5.5+)JDK 83.5.0 …...

3步布局关键词让流量更精准

其实流量不精准&#xff0c;90% 是关键词没布局好&#xff01; 掌握这 3 个超实用技巧&#xff0c;让你的内容精准推给目标人群&#xff01; 第一步&#xff1a;深挖高潜力关键词 别再一股脑用 “好看”“好用” 这些泛词啦&#xff01;打开平台搜索框&#xff0c;输入核心词…...

视觉分析在人员行为属性检测中的应用

基于视觉分析的人员行为属性检测方案 一、背景与需求分析 在工业生产、建筑施工、公共安全等领域&#xff0c;人员行为属性的合规性检测是保障安全生产的关键环节。例如&#xff0c;工地工人未佩戴安全帽、厨房人员未佩戴手套、作业现场人员使用手机等行为&#xff0c;均可能…...

学习 React【Plan - June - Week 1】

一、使用 JSX 书写标签语言 JSX 是一种 JavaScript 的语法扩展&#xff0c;React 使用它来描述用户界面。 什么是 JSX&#xff1f; JSX 是 JavaScript 的一种语法扩展。看起来像 HTML&#xff0c;但它实际上是在 JavaScript 代码中写 XML/HTML。浏览器并不能直接运行 JSX&…...

电子行业AI赋能软件开发经典案例——某金融软件公司

01.案例标题 金融行业某金融软件公司通过StarShip CodeSouler达成效率突破性增长&#xff0c;零流程侵入验证AI代码高度可行性 02.执行摘要 某金融软件公司在核心产品研发中引入开放传神&#xff08;OpenCSG&#xff09;的StarShip CodeSouler AI代码生成平台&#xff0c;在无…...

【前端】js如何处理计算精度问题

JavaScript 的精度问题源于其遵循 IEEE 754 标准的 64 位双精度浮点数表示法&#xff0c;导致 0.1 0.2 ! 0.3 等经典问题。以下是系统化的解决方案及适用场景&#xff1a; ⚙️ 一、整数转换法&#xff08;适合简单运算&#xff09; 将小数转换为整数运算后再还原&#xff0…...

使用 Python 自动化 Word 文档样式复制与内容生成

在办公自动化领域&#xff0c;如何高效地处理 Word 文档的样式和内容复制是一个常见需求。本文将通过一个完整的代码示例&#xff0c;展示如何利用 Python 的 python-docx 库实现 Word 文档样式的深度复制 和 动态内容生成&#xff0c;并结合知识库中的最佳实践优化文档处理流程…...

Kafka 核心架构与消息模型深度解析(二)

案例实战&#xff1a;Kafka 在实际场景中的应用 &#xff08;一&#xff09;案例背景与需求介绍 假设我们正在为一个大型电商平台构建数据处理系统。该电商平台拥有庞大的用户群体&#xff0c;每天会产生海量的订单数据、用户行为数据&#xff08;如浏览、点击、收藏等&#…...