效果預覽
鄙人不才,實現的方法較爲粗暴,如果有更好的方案還望大神指教一二。
準備工作
巧婦難爲無米之炊,製作換裝系統首先得有“裝備”纔可以。如果大家會美術可以自己畫,注意所有的素材的遮擋順序和運動細節需要一致,當然如果用程序控制遮罩來實現更爲優秀的遮擋管理我覺得也是可行的。
給大家看看我用的素材集合(自制)截圖:
有了這些替換用的素材就可以開始實現換裝了。
Plyer的建立
我將人物拆成了各個不同的身體部件,它們每一個都是一個SpriteRander,手部因爲比較複雜所以拆的尤其的多。(這裏的DrawCall可能會很高,用Shader來合併素材應該能節省性能,可惜我不會(*^_^*))
建立好Player之後,請手動確保渲染順序(OrderInLayer)的正確性。
接下來要給人物建立好不同的動畫,譬如走路跳躍攻擊。這一步關於Unity本身動畫狀態機的使用相信大家都會的。
素材庫的建立
使用類似的腳本來存儲圖片:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//用以存儲身體圖片的類
public class Doll_body : MonoBehaviour
{
//圖片的存儲結構體
//使用此註解使其能顯示在Unity的編輯面板上
[System.Serializable]
public struct DollBody
{
public Sprite bodyNormal;
public Sprite bodyFront;
public Sprite leftHandNormal;
public Sprite leftHandBack;
public Sprite leftHandFront;
public Sprite leftHand_SwordAttackStab_prepare;
public Sprite leftHand_SwordAttackStab_attack;
public Sprite leftHand_SwordAttackCleave_up;
public Sprite leftHand_SwordAttackCleave_mid;
public Sprite leftHand_bowAttack_01;
public Sprite leftHand_bowAttack_02;
public Sprite leftHand_bowAttack_03;
public Sprite rightHandFront;
public Sprite rightHandNormal;
public Sprite rightHand_holdBow;
}
//不同的裝備
public DollBody piBody;
public DollBody xunlinBody;
public DollBody zibiBody;
}
創建一個空物體名爲“換裝管理器 ”,給它加上上述組件,在拖動圖片賦值,切換場景時注意不要銷燬此物體。(因爲是像素風遊戲,所以圖集比較小,大遊戲的話也許得用更高效的素材庫了,具體怎麼實現沒有思路)
創建下面這個腳本,同樣作爲“換裝管理器 ”的組件,用來給各個圖片組起個名字,方便調用。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DollDictionary : MonoBehaviour
{
public static Dictionary<string,Doll_foot.DollFoot> footDictionary = new Dictionary<string, Doll_foot.DollFoot>();
public static Dictionary<string,Doll_body.DollBody> bodyDictionary = new Dictionary<string, Doll_body.DollBody> ();
public static Dictionary<string,Doll_hair.DollHair> hairDictionary = new Dictionary<string, Doll_hair.DollHair>();
public static Dictionary<string,Doll_helmet.DollHelmet> helmetDictionary =new Dictionary<string, Doll_helmet.DollHelmet>();
public static Dictionary<string,Doll_Skin.DollSkin> skinDictionary = new Dictionary<string, Doll_Skin.DollSkin>();
void Awake ()
{
Doll_foot tempDollFoot = this.GetComponent<Doll_foot> ();
footDictionary.Add ("皮質腿甲", tempDollFoot.piFoot);
footDictionary.Add ("巡林腿甲", tempDollFoot.xunlinFoot);
footDictionary.Add("緊身褲", tempDollFoot.jinshengFoot);
Doll_body tempDollBody = this.GetComponent<Doll_body> () ;
bodyDictionary.Add ("皮質胸甲", tempDollBody.piBody);
bodyDictionary.Add ("巡林胸甲", tempDollBody.xunlinBody);
bodyDictionary.Add("自閉胸甲", tempDollBody.zibiBody);
Doll_hair tempDollHair = this.GetComponent<Doll_hair> ();
hairDictionary.Add ("普通", tempDollHair.putongHair);
hairDictionary.Add ("半遮", tempDollHair.banzheHair);
hairDictionary.Add ("丸子", tempDollHair.wanziHair);
hairDictionary.Add ("莫辛甘", tempDollHair.moxingganHair);
hairDictionary.Add("飛機頭", tempDollHair.feijiHair);
Doll_helmet tempDollHelmet = this.GetComponent<Doll_helmet> ();
helmetDictionary.Add ("兜帽", tempDollHelmet.doumaoHelmet);
helmetDictionary.Add ("巫師帽", tempDollHelmet.fashiHelmet);
helmetDictionary.Add ("鐵頭盔", tempDollHelmet.metalHelmet);
helmetDictionary.Add ("皮帽", tempDollHelmet.piHelmett);
Doll_Skin tempDollSkin = this.GetComponent<Doll_Skin> ();
skinDictionary.Add ("皮膚A", tempDollSkin.SkinTyprA);
skinDictionary.Add ("皮膚B", tempDollSkin.SkinTyprB);
skinDictionary.Add ("皮膚C", tempDollSkin.SkinTyprC);
}
}
添加動畫事件
給Player附上下面這個腳本,用以在特定的時候改變人物的圖片。
其中SetBody(PlayerAttribute),用以改變人物的圖集,PlayerAttribute是我自己定義的人物狀態類,當裏面的字段改變時會自動出發一個事件來調用SetBody更改圖集。
setBodyXXX(),用以在動畫中觸發改變圖片,衆所周知,動畫就是一系列變化的圖片,這樣便實現了動態。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SwarpSprites : MonoBehaviour
{
[SerializeField]
SpriteRenderer helmetRender,hairRender,skinHeadRender,bodyRender,footRender;
Sprite walkMid,walkFront,walkBack,footStand,footFall;
Sprite bodyNormal,bodyFront;
Sprite skinHeadNormal,skinHeadUp,skinHeadDown;
Sprite helmetNormal,helmetUp,helmetDown;
Sprite hairNormal,hairUp,hairDown;
public SwarpHandSprites swarpHandSprites;
void Start ()
{
setAll ();
}
public void setAll()
{
PlayerAttribute playerAttribute = this.GetComponent<PlayerAttribute> ();
setFoot (playerAttribute);
setBody (playerAttribute);
setSkin (playerAttribute);
setHelmet (playerAttribute);
setHair (playerAttribute);
}
public void setBody(PlayerAttribute playerAttribute)
{
Doll_body.DollBody bodySet = DollDictionary.bodyDictionary [playerAttribute.bodyType];
bodyNormal = bodySet.bodyNormal;
bodyFront = bodySet.bodyFront;
swarpHandSprites.bodyLeftHandNormal = bodySet.leftHandNormal;
swarpHandSprites.bodyLeftHandFront = bodySet.leftHandFront;
swarpHandSprites.bodyLeftHandBack = bodySet.leftHandBack;
swarpHandSprites.bodyLeftHand_SwordAttackStab_prepare = bodySet.leftHand_SwordAttackStab_prepare;
swarpHandSprites.bodyLeftHand_SwordAttack_attack = bodySet.leftHand_SwordAttackStab_attack;
swarpHandSprites.bodyLeftHand_SwardAttackCleave_mid = bodySet.leftHand_SwordAttackCleave_mid;
swarpHandSprites.bodyLeftHand_SwardAttackCleave_Up = bodySet.leftHand_SwordAttackCleave_up;
swarpHandSprites.bodyLeftHand_bowAttack01 = bodySet.leftHand_bowAttack_01;
swarpHandSprites.bodyLeftHand_bowAttack02 = bodySet.leftHand_bowAttack_02;
swarpHandSprites.bodyLeftHand_bowAttack03 = bodySet.leftHand_bowAttack_03;
swarpHandSprites.bodyRightHandNormal = bodySet.rightHandNormal;
swarpHandSprites.bodyRightHandFront = bodySet.rightHandFront;
swarpHandSprites.bodyRightHand_holdBow = bodySet.rightHand_holdBow;
}
//設置足部動畫
void setWalkMid()
{ footRender.sprite = walkMid; }
void setWalkFront()
{ footRender.sprite = walkFront; }
void setWalkBack()
{ footRender.sprite = walkBack; }
void setFootStand()
{ footRender.sprite = footStand; }
void setFootFallDown()
{ footRender.sprite = footFall; }
//設置身體動畫
public void setBodyNormal()
{ bodyRender.sprite = bodyNormal; }
void setBodyFront()
{ bodyRender.sprite = bodyFront; }
//還有很多...
...
}
以上,就實現了一個簡單的紙娃娃,最耗時的,其實是繪畫各種替換素材的過程。