山西做網(wǎng)站運(yùn)營的公司網(wǎng)店運(yùn)營培訓(xùn)哪里好
文章目錄
- 每篇一句
- 前言
- 素材
- 開始
- 切換頭型
- 添加更改顏色
- 隨機(jī)控制頭型和顏色
- 新增眼睛
- 同樣的方法配置人物的其他部位
- 設(shè)置相同顏色部位
- 全部部位隨機(jī)
- 繪制UI并添加點(diǎn)擊事件
- 通過代碼控制點(diǎn)擊事件
- 添加顏色修改的事件
- 其他部位效果UI切換
- 添加隨機(jī)按鈕
- 保存角色變更數(shù)據(jù)
- 跳轉(zhuǎn)場景顯示角色數(shù)據(jù)
- 源碼
- 完結(jié)
每篇一句
你進(jìn)步的速度,取決于你學(xué)習(xí)的速度,昨天的我,也跟今天的你一樣。
前言
本文我們來手戳一個自定義角色換裝系統(tǒng),它包括基本的人物部位、顏色修改,并跨場景顯示修改的人物信息,2d3d通用
最終效果
素材
鏈接:https://pan.baidu.com/s/1dubEMMBO-ZSm3gQWPkvmsA?pwd=5zi6
提取碼:5zi6
開始
切換頭型
新建PositionedSprite腳本,保存圖片和位置位置
using UnityEngine;[System.Serializable]
public class PositionedSprite
{public Sprite Sprite; // Sprite對象public Vector3 PositionModifier; // 位置修正器
}
新建CustomizableElement腳本,控制圖片切換
using System.Collections.Generic;
using UnityEngine;public class CustomizableElement : MonoBehaviour
{[SerializeField]private SpriteRenderer _spriteRenderer; // Sprite渲染器[SerializeField]private List<PositionedSprite> _spriteOptions; // 可選的Sprite列表[SerializeField]private List<Color> _colorOptions; // 可選的顏色列表[field: SerializeField]public int ColorIndex { get; set; } // 顏色索引[field: SerializeField]public int SpriteIndex { get; private set; } // Sprite索引[ContextMenu(itemName: "下一個圖片")]public PositionedSprite NextSprite(){SpriteIndex = Mathf.Min(SpriteIndex + 1, _spriteOptions.Count - 1); // 切換到下一個SpriteUpdateSprite();return _spriteOptions[SpriteIndex];}[ContextMenu(itemName: "上一個圖片")]public PositionedSprite PreviousSprite(){SpriteIndex = Mathf.Max(SpriteIndex - 1, 0); // 切換到上一個SpriteUpdateSprite();return _spriteOptions[SpriteIndex];}private void UpdateSprite(){if(_spriteOptions.Count == 0) return;SpriteIndex = Mathf.Clamp(SpriteIndex, 0, _spriteOptions.Count - 1); // 限制Sprite索引在合法范圍內(nèi)var positionedSprite = _spriteOptions[SpriteIndex];_spriteRenderer.sprite = positionedSprite.Sprite; // 更新Spritetransform.localPosition = positionedSprite.PositionModifier; // 更新位置}
}
掛載并配置參數(shù)
效果
添加更改顏色
[ContextMenu(itemName: "下一個顏色")]
public Color NextColor()
{ColorIndex = Mathf.Min(ColorIndex + 1, _colorOptions.Count - 1); // 切換到下一個顏色UpdateColor();return _colorOptions[ColorIndex];
}[ContextMenu(itemName: "上一個顏色")]
public Color PreviousColor()
{ColorIndex = Mathf.Max(ColorIndex - 1, 0); // 切換到上一個顏色UpdateColor();return _colorOptions[ColorIndex];
}private void UpdateColor()
{if(_colorOptions.Count == 0) return;_spriteRenderer.color = _colorOptions[ColorIndex]; // 更新顏色
}
配置
效果
隨機(jī)控制頭型和顏色
[ContextMenu(itemName: "隨機(jī)化")]
public void Randomize()
{SpriteIndex = Random.Range(0, _spriteOptions.Count); // 隨機(jī)選擇一個Sprite索引ColorIndex = Random.Range(0, _colorOptions.Count); // 隨機(jī)選擇一個顏色索引UpdateSprite();UpdateColor();
}
效果
新增眼睛
同理,添加眼睛,并配置眼睛的位置
效果
同樣的方法配置人物的其他部位
效果
設(shè)置相同顏色部位
可能我們不希望所有部位都真的隨機(jī)變色,比如我希望角色的膚色顏色保持一致
修改代碼
[SerializeField]
private List<SpriteRenderer> _copyColorTo; // 需要拷貝顏色的SpriteRenderer列表// ...private void UpdateColor()
{if(_colorOptions.Count == 0) return;var newColor = _colorOptions[ColorIndex]; // 獲取新的顏色_spriteRenderer.color = newColor; // 更新當(dāng)前SpriteRenderer的顏色// 將顏色拷貝到其他SpriteRenderer_copyColorTo.ForEach(sr => sr.color = newColor);
}
配置
當(dāng)我們更新頭顏色時,手會同步更新,保持頭跟手顏色一樣
效果
全部部位隨機(jī)
新增CustomizationRandomizer 代碼
using UnityEngine;public class CustomizationRandomizer : MonoBehaviour
{[ContextMenu(itemName: "隨機(jī)全部")]public void Randomize(){var elements = GetComponentsInChildren<CustomizableElement>(); // 獲取所有CustomizableElement組件foreach (var element in elements){element.Randomize(); // 調(diào)用CustomizableElement的Randomize方法,隨機(jī)化每個元素}}
}
掛載腳本,效果
繪制UI并添加點(diǎn)擊事件
效果
通過代碼控制點(diǎn)擊事件
一個個配置按鈕事件太麻煩了,我們可以通過腳本來控制
public class UI_CustomizationPicker : MonoBehaviour
{[SerializeField]private CustomizableElement _customizableElement; // 自定義元素對象[SerializeField]private Button _previousSpriteButton;[SerializeField]private Button _nextSpriteButton;[SerializeField]private TMP_Text _spriteId;private void Start(){UpdateSpriteId();// 為按鈕添加點(diǎn)擊事件_previousSpriteButton.onClick.AddListener(() =>{_customizableElement.PreviousSprite(); // 切換到上一個SpriteUpdateSpriteId(); // 更新Sprite的ID文本});_nextSpriteButton.onClick.AddListener(() =>{_customizableElement.NextSprite(); // 切換到下一個SpriteUpdateSpriteId(); // 更新Sprite的ID文本});}private void UpdateSpriteId(){// 更新Sprite的ID文本_spriteId.SetText(_customizableElement.SpriteIndex.ToString().PadLeft(2, '0'));}
}
配置參數(shù)
效果
添加顏色修改的事件
修改CustomizableElement獲取當(dāng)前的顏色
public Color CurrentColor => _colorOptions.Count == 0 ? Color.white : _colorOptions[ColorIndex]; //獲取當(dāng)前的顏色
修改UI_CustomizationPicker,添加顏色切換事件
[SerializeField]
private Button _previousColorButton;
[SerializeField]
private Button _nextColorButton;
[SerializeField]
private Image _colorIcon;private void Start()
{// 。。。if(_colorIcon != null){_previousColorButton.onClick.AddListener(() =>{_customizableElement.PreviousColor();UpdateColorIcon();});_nextColorButton.onClick.AddListener(() =>{_customizableElement.NextColor();UpdateColorIcon();});}
}private void UpdateColorIcon()
{_colorIcon.color = _customizableElement.CurrentColor;
}
效果
其他部位效果UI切換
跟前面一樣配置各個部位的切換即可,配置其他部位最終效果
效果
添加隨機(jī)按鈕
新增腳本UI_CustomizationUI,定義隨機(jī)按鈕事件
public class UI_CustomizationUI : MonoBehaviour
{private List<UI_CustomizationPicker> _pickers; // 自定義選擇器列表void Start(){_pickers = GetComponentsInChildren<UI_CustomizationPicker>().ToList(); // 獲取所有自定義選擇器組件并轉(zhuǎn)換為列表}// 更新所有選擇器的狀態(tài)public void UpdatePickersState(){_pickers.ForEach(picker =>{picker._customizableElement.Randomize();//隨機(jī)修改picker.UpdateSpriteId(); // 更新Sprite的ID文本picker.UpdateColorIcon(); // 更新顏色圖標(biāo)});}
}
掛載腳本
效果
保存角色變更數(shù)據(jù)
新增CustomizationType 腳本,定義不同部位類型
using UnityEngine;[CreateAssetMenu]
public class CustomizationType : ScriptableObject
{}
添加各個部位配置
新增CustomizationData腳本,定義各種數(shù)據(jù)
using UnityEngine;
using System;[Serializable]
public class CustomizationData
{// 使用情況:指定自定義類型[field:SerializeField]public CustomizationType Type { get; private set; }// 使用情況:指定帶位置的精靈[field:SerializeField]public PositionedSprite Sprite { get; private set; }// 使用情況:指定顏色[field:SerializeField]public Color Color { get; private set; }// CustomizationData 類的構(gòu)造函數(shù)public CustomizationData(CustomizationType t, PositionedSprite s, Color c){Type = t;Sprite = s;Color = c;}
}
修改CustomizableElement
[SerializeField]
private CustomizationType _type;public CustomizationData GetCustomizationData(){return new CustomizationData(_type, _spriteOptions[SpriteIndex], _spriteRenderer.color);
}
綁定對應(yīng)數(shù)據(jù)
新增CustomizedCharacter,保存人物各個部位數(shù)據(jù)
using UnityEngine;
using System.Collections.Generic;[CreateAssetMenu]
public class CustomizedCharacter : ScriptableObject
{// Usage: 包含所有自定義數(shù)據(jù)的列表[field:SerializeField]public List<CustomizationData> Data { get; private set; }// 收集所有可定制元素的自定義數(shù)據(jù)public void GatherCustomizationData(){// 查找場景中的所有可定制元素var customizableElements = FindObjectsOfType<CustomizableElement>();// 創(chuàng)建一個新的自定義數(shù)據(jù)列表Data = new List<CustomizationData>();// 遍歷所有可定制元素并添加它們的自定義數(shù)據(jù)到列表中foreach (var element in customizableElements){Data.Add(element.GetCustomizationData());}}
}
新增人物配置
新增CustomizableCharacter
using UnityEngine;public class CustomizableCharacter : MonoBehaviour
{[SerializeField]private CustomizedCharacter _character;// Usage: 在編輯器中的上下文菜單中添加 "Randomize All" 選項(xiàng)[ContextMenu(itemName: "Randomize All")]// Usage: 隨機(jī)化所有可定制元素的外觀public void Randomize(){// 獲取所有子物體中的 CustomizableElement 組件數(shù)組var elements = GetComponentsInChildren<CustomizableElement>();// 遍歷每個可定制元素,隨機(jī)化其外觀foreach (var element in elements){element.Randomize();}}// Usage: 存儲定制信息public void StoreCustomizationInformation(){// 獲取所有子物體中的 CustomizableElement 組件數(shù)組var elements = GetComponentsInChildren<CustomizableElement>();// 清空已有的定制數(shù)據(jù)_character.Data.Clear();// 遍歷每個可定制元素,獲取其定制數(shù)據(jù)并添加到角色的數(shù)據(jù)列表中foreach (var element in elements){_character.Data.Add(element.GetCustomizationData());}}
}
掛載腳本,配置數(shù)據(jù)
新增按鈕用于跳轉(zhuǎn)和保持角色數(shù)據(jù)
效果,數(shù)據(jù)被保存在了Player里
跳轉(zhuǎn)場景顯示角色數(shù)據(jù)
新增CustomizedCharacterElement腳本,用來渲染角色各個部位的圖片和顏色
using UnityEngine;
using System.Linq;public class CustomizedCharacterElement : MonoBehaviour
{// Usage: 指定該元素的自定義類型[field:SerializeField]public CustomizationType Type { get; private set; }// Usage: 指定所屬的自定義角色[SerializeField]private CustomizedCharacter _character;private SpriteRenderer _spriteRenderer;// Start 方法在對象實(shí)例化時調(diào)用private void Start(){// 獲取 SpriteRenderer 組件_spriteRenderer = GetComponent<SpriteRenderer>();// 查找自定義角色中指定類型的自定義數(shù)據(jù)var customization = _character.Data.FirstOrDefault(d => d.Type == Type);// 如果找不到匹配的自定義數(shù)據(jù),則返回if (customization == null){return;}// 應(yīng)用自定義數(shù)據(jù)中的顏色和精靈到元素上_spriteRenderer.color = customization.Color;_spriteRenderer.sprite = customization.Sprite.Sprite;// 應(yīng)用自定義數(shù)據(jù)中的位置修正器到元素上transform.localPosition = customization.Sprite.PositionModifier;}
}
新建場景,掛載腳本,添加配置角色屬性
修改CustomizableCharacter腳本,添加跳轉(zhuǎn)場景方法
//跳轉(zhuǎn)場景
SceneManager.LoadScene("Game");
效果
源碼
為了防止大家變懶,源碼就不提供了,大家直接可以照著文章思路進(jìn)行學(xué)習(xí)
完結(jié)
贈人玫瑰,手有余香!如果文章內(nèi)容對你有所幫助,請不要吝嗇你的點(diǎn)贊評論和關(guān)注
,以便我第一時間收到反饋,你的每一次支持
都是我不斷創(chuàng)作的最大動力。點(diǎn)贊越多,更新越快哦!當(dāng)然,如果你發(fā)現(xiàn)了文章中存在錯誤
或者有更好的解決方法
,也歡迎評論私信告訴我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奮斗的開發(fā)者,出于興趣愛好,于是最近才開始自習(xí)unity。如果你遇到任何問題,也歡迎你評論私信找我, 雖然有些問題我可能也不一定會,但是我會查閱各方資料,爭取給出最好的建議,希望可以幫助更多想學(xué)編程的人,共勉~