Unity简易实现人物换装功能

      人物换装是动作类游戏必不可少的一个功能,本篇就介绍一个简易的换装功能,如要换装,人物身体肯定会拆分成几个部分,如头部,武器,身体等,每个部分都有一个SkinnedMeshRenderer组件,这个组件有三个重要元素,分别是bone(骨骼)、material(材质)、mesh(网格信息),根据这些进行蒙皮计算。若要实现换装,将待换部件的SkinnedMeshRenderer组件的信息替换原部件即可。本篇文章中的代码实现的功能为:角色的血量在高于某一个设定值的时候是正常衣服,否则换为破洞衣服。测试时将完整衣服与破洞衣服对应的.FBX拖拽到脚本即可,具体代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChangeSkin : MonoBehaviour
{
	[Header("破洞衣服")]
	public GameObject lousyClothes;//破洞衣服
	[Header("完整衣服")]
	public GameObject fullClothes;//完整衣服
	[Header("换装血量百分比")]
	public float percent;//换装血量百分比

	private Player _player;//人物控制脚本,存贮人物血量、ID等信息
	private GameObject _clothes;//当前人物的衣服
	private GameObject _flagClothes;//衣服换装标志
	private List<Transform> _bones;//存储Skin合并后的骨骼引用
	private GameObject _rootBone;//根骨骼

	void Start ()
	{
		_player=transform.GetComponentInParent<Player>();
		_rootBone = gameObject.transform.FindChildByName ("Bip001 Pelvis").gameObject;//根骨骼名字会不同
		_bones = new List<Transform> ();
		_clothes = fullClothes;
		_flagClothes = _clothes;
		ChangeSkinnedMesh ();
	}

	void Update()
	{
		//根据血量来控制人物所穿的衣服
		if (_player.Life>_player.MaxLife*percent)
		_clothes = fullClothes;
		else 
		_clothes = lousyClothes;

		//为避免每帧都调用ChangeSkinnedMesh()方法重构,仅当检测到衣服变化进行调用
		if (_clothes.name!=_flagClothes.name) {
			ChangeSkinnedMesh ();
			_flagClothes=_clothes;
		}
	}

	public void ChangeSkinnedMesh()
	{
		_bones.Clear ();
		List<CombineInstance> combineInstances = new List<CombineInstance> ();
		List<Material> materials = new List<Material> ();
		Transform[] transforms = _rootBone.GetComponentsInChildren<Transform> (true);

		if (_clothes==null ) 
			return;
		SkinnedMeshRenderer smr = _clothes.GetComponentInChildren<SkinnedMeshRenderer> ();
		//将要更换衣服的SkinnedMeshRenderer组件上的信息记录保存下来
		if (smr!=null) {
			for (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++) {
				for (int j = 0; j < smr.bones.Length; j++) {
					for (int index = 0; index < transforms.Length; index++) {
						if (smr.bones [j].name.Equals (transforms [index].name)) {
							_bones.Add (transforms [index]);
							break;
						}
					}
				}
				CombineInstance ci = new CombineInstance ();
				ci.mesh = smr.sharedMesh;
				ci.subMeshIndex = sub;
				combineInstances.Add (ci);
			}
			materials.AddRange (smr.sharedMaterials);
		}
		//将原来的SkinnedMeshRenderer删除,将更换信息的添加上去
		SkinnedMeshRenderer oldSkin = GetComponent<SkinnedMeshRenderer> ();
		if (oldSkin != null) {
			GameObject.DestroyImmediate (oldSkin);
		}
		SkinnedMeshRenderer newSmr = gameObject.AddComponent<SkinnedMeshRenderer> ();
		newSmr.sharedMesh = new Mesh ();
		newSmr.sharedMesh.CombineMeshes (combineInstances.ToArray (), false, false);
		newSmr.bones = _bones.ToArray ();
		newSmr.rootBone = _rootBone.transform;
		newSmr.materials = materials.ToArray ();
	}
}

本篇博客参考博文:浅谈角色换装功能–Unity简单例子实现,有关更多换装详细介绍可进行查看。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值