Unity2D:简单人物纸娃娃换装实现:服装的变换

效果预览

基本效果

鄙人不才,实现的方法较为粗暴,如果有更好的方案还望大神指教一二。

准备工作

巧妇难为无米之炊,制作换装系统首先得有“装备”才可以。如果大家会美术可以自己画,注意所有的素材的遮挡顺序和运动细节需要一致,当然如果用程序控制遮罩来实现更为优秀的遮挡管理我觉得也是可行的。

给大家看看我用的素材集合(自制)截图:

有了这些替换用的素材就可以开始实现换装了。

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; }
	
	//还有很多...
	...

}

在合适的关键帧调用切换图片的函数

以上,就实现了一个简单的纸娃娃,最耗时的,其实是绘画各种替换素材的过程。 ​

评论

  1. 111
    3年前
    2021-12-14 13:36:41

    111

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇