iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Unity实现简单换装系统的方法
  • 123
分享到

Unity实现简单换装系统的方法

2023-06-14 12:06:01 123人浏览 八月长安
摘要

小编给大家分享一下Unity实现简单换装系统的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!代码如下:using UnityEngine;using

小编给大家分享一下Unity实现简单换装系统的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

代码如下:

using UnityEngine;using System.Collections;using System.Collections.Generic; public enum AvatarPart{    helmet,    chest,    shoulders,    gloves,    boots,} // 人物换装public class ActorAvatar : MonoBehaviour{    // 换装的部件信息    public class AvatarInfo    {        public string partName;        public GameObject defaultPart;        public GameObject avatarPart;    }     protected int _bodyModelId;    protected GameObject _body;         // 基础模型动画    protected Dictionary<string, AvatarInfo> _avatarInfo = new Dictionary<string, AvatarInfo>();        // 换装信息     private List<int> _avatarLoadQueue = new List<int>();     void Start()    {    }     void Update()    {    }     // 创建模型    public void LoadModel(int modelId)    {        _bodyModelId = modelId;        ResourceMgr.Instance.LoadModel(modelId, (GameObject obj) =>        {            _body = obj;             // 换装请求            if (_avatarLoadQueue.Count > 0) {                foreach (var avatar in _avatarLoadQueue) {                    LoadAvatar(avatar);                }                _avatarLoadQueue.Clear();            }        }, true);    }     // 给人物换装    public void LoadAvatar(int avatarId)    {        // 如果还没有加载完基础模型,则等待        if (_body == null) {            _avatarLoadQueue.Add(avatarId);            return;        }         AvatarData adata = DataMgr.Instance.GetAvatarData(avatarId);        ResourceMgr.Instance.LoadModel(adata.model, (GameObject obj) => {            ChangeAvatar(obj, adata.addpart);        });    }     // 替换部件    public void ChangeAvatar(GameObject avatarModel, string partName)    {        // 先卸载当前部件        AvatarInfo currentInfo;        if (_avatarInfo.TryGetValue(partName, out currentInfo)) {            if (currentInfo.avatarPart != null) {                Destroy(currentInfo.avatarPart);                currentInfo.avatarPart = null;            }             if (currentInfo.defaultPart != null) {                currentInfo.defaultPart.SetActive(true);            }        }         // avatarModel是一个resource,并没有实例化        if (avatarModel == null) {            return;        }         // 需要替换的部件        TransfORM avatarPart = GetPart(avatarModel.transform, partName);        if (avatarPart == null) {            Debug.LogError(string.Format("Avatar Part Not Found: ", partName));            return;        }         // 将原始部件隐藏        Transform bodyPart = GetPart(_body.transform, partName);        if (bodyPart != null) {            bodyPart.gameObject.SetActive(false);        }         // 设置到body上的新物件        GameObject newPart = new GameObject(partName);        newPart.transform.parent = _body.transform;        SkinnedMeshRenderer newPartRender = newPart.AddComponent<SkinnedMeshRenderer>();        SkinnedMeshRenderer avatarRender = avatarPart.GetComponent<SkinnedMeshRenderer>();         // 刷新骨骼模型数据        SetBones(newPart, avatarPart.gameObject, _body);        newPartRender.sharedMesh = avatarRender.sharedMesh;        newPartRender.sharedMaterials = avatarRender.sharedMaterials;         // 记录换装信息        AvatarInfo info = new AvatarInfo();        info.partName = partName;        if (bodyPart != null) {            info.defaultPart = bodyPart.gameObject;        } else {            info.defaultPart = null;        }         info.avatarPart = newPart;        _avatarInfo[partName] = info;    }      // 递归遍历子物体    public static Transform GetPart(Transform t, string searchName)    {        foreach (Transform c in t) {            string partName = c.name.ToLower();                        if (partName.IndexOf(searchName) != -1) {                return c;            } else {                Transform r = GetPart(c, searchName);                if (r != null) {                    return r;                }            }        }        return null;    }     public static Transform FindChild(Transform t, string searchName)    {        foreach (Transform c in t) {            string partName = c.name;            if (partName == searchName) {                return c;            } else {                Transform r = FindChild(c, searchName);                if (r != null) {                    return r;                }            }        }        return null;    }     // 刷新骨骼数据   将root物体的bodyPart骨骼更新为avatarPart    public static void SetBones(GameObject GoBodyPart, GameObject goAvatarPart, GameObject root)    {        var bodyRender = goBodyPart.GetComponent<SkinnedMeshRenderer>();        var avatarRender = goAvatarPart.GetComponent<SkinnedMeshRenderer>();        var myBones = new Transform[avatarRender.bones.Length];        for (var i = 0; i < avatarRender.bones.Length; i++) {            myBones[i] = FindChild(root.transform, avatarRender.bones[i].name);        }        bodyRender.bones = myBones;    } }

Unity换装有三种需求:

添加武器的挂载式换装,这个只要创建对应的模型,并且设置好transform.parent就可以了。

替换纹理,这个取到对应的material,然后设置texture就可以了。

模型部件的替换,这个是此处处理的,也是相对最复杂的换装。

最核心的部分是ChangeAvatar,它完成了模型换装的功能。模型部件的替换其实就是替换SkinnedMeshRender中的sharedMesh和sharedMaterials。

(这里稍微插一下sharedMaterials   sharedMaterial  Materials  Material这几个变量的区别。sharedMaterials是共享和引用的关系,只要修改这个,所有使用到这个material的模型都会受到影响。如果是在编辑器模式下,它还会修改实际material文件的属性。Materials是sharedMaterials的一份拷贝,只有当前模型使用。materia是materials数组中的第一个对象,这个仅仅是为了方便书写而存在的。)

仅仅替换了sharedMesh还不够,模型会变成一坨麻花。 还应该修改SkinnedMeshRender中的bones属性,它记录了模型的骨骼信息(其实就是一大堆Transform)。  SetBones函数完成了骨骼替换的操作。它查找avatar部件中的所有骨骼名称,然后查找当前模型中的对应骨骼名字,并存储起来。这个数组就是新部件的骨骼信息。

一个逻辑上的处理细节。保留了原始模型的对应部件,并没有销毁这个部件,仅仅是隐藏起来。这样卸载装备的时候,只需要删掉装备部件,然后把默认部件设为可见就可以了。

可以考虑使用Unity的CombineInstance把模型合并,这样的好处是可以提高运行性能。但是只有材质共用一个的时候才能真正起到优化效果。有个MeshBaker的插件很酷。如果要进行千人战,就必须考虑这方面的优化。

Unity实现简单换装系统的方法

以上是“Unity实现简单换装系统的方法”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: Unity实现简单换装系统的方法

本文链接: https://www.lsjlt.com/news/270582.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Unity实现简单换装系统的方法
    小编给大家分享一下Unity实现简单换装系统的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!代码如下:using UnityEngine;using...
    99+
    2023-06-14
  • Unity实现简单换装系统
    关于Unity的换装,网上有几篇文章,我之前也简单的描述过实现。不过那个时候只是粗略的试验了下。今天好好梳理了下代码。 先上代码(自己的游戏项目,不是公司的,所以放心的贴上项目代码了...
    99+
    2024-04-02
  • Unity实现换装系统的方法
    这篇文章主要介绍Unity实现换装系统的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体内容如下1.创建Sprite Library Asset2.添加新目录Label 可以理解为标签,在代码调用过程中使用,将...
    99+
    2023-06-14
  • Unity实现换装系统
    Unity如何实现换装系统,供大家参考,具体内容如下 1.创建Sprite Library Asset 2.添加新目录 Label 可以理解为标签,在代码调用过程中使用,将该部位...
    99+
    2024-04-02
  • 无需系统盘超简单重装WINXP系统的方法
    电脑用时间长了免不了会在系统里留下很多垃圾,造成系统运行慢,易死机等问题。经常会有朋友打电话给我,说自已的系统出了这样那样的问题,是不是有时间可以帮他装一下系统。其实,安装操作系统对于一个电脑使用者来说是一件很简单的事,...
    99+
    2023-06-11
    系统盘 重装WINXP系统 WINXP 重装 系统 方法
  • Unity实现简单摇杆的制作
    利用UGUI制作一个简单摇杆,效果图 1、首先建立两个Image,然后将其中一个为父物体,另一个为子物体,并且调整好大小: ps:将子物体的锚点设置为居中  ...
    99+
    2024-04-02
  • unity实现简单的贪吃蛇游戏
    本文实例为大家分享了unity实现简单贪吃蛇游戏的具体代码,供大家参考,具体内容如下 SatUIController代码 using UnityEngine; using Un...
    99+
    2024-04-02
  • C#实现简单的点餐系统
    本文项目为大家分享了C#实现点餐系统,供大家参考,具体内容如下 项目介绍:一家店铺使用的外卖点餐系统本项目分三大模块:登录注册模块,用户模块,店家模块 1.登录注册模块 登录分为用户...
    99+
    2024-04-02
  • js实现简单的抽奖系统
    一个用js编写的简单的抽奖系统,供大家参考,具体内容如下 效果图如图所示:字节带闪动,点击开始,可进行抽奖,并且按钮变为结束按钮,然后点击结束按钮,可以结束,并抽奖成功。 代码如下...
    99+
    2024-04-02
  • Unity实现简单的多人聊天工具
    本文实例为大家分享了Unity实现多人聊天工具的具体代码,供大家参考,具体内容如下 代码1 : 服务端代码 using UnityEngine; using System.Net.S...
    99+
    2024-04-02
  • JavaScript实现简单抽奖系统
    本文实例为大家分享了JavaScript实现简单抽奖系统的具体代码,供大家参考,具体内容如下 模拟实现抽奖系统 前端使用JavaScript代码实现抽奖系统,代码如下: 样式代码: ...
    99+
    2024-04-02
  • java实现简单快递系统
    本文实例为大家分享了java实现简单快递系统的具体代码,供大家参考,具体内容如下 创建四个类Express,Locker, User, Administrator分别模拟快递,快递...
    99+
    2024-04-02
  • Java实现简单点餐系统
    用Java实现简单点餐系统,供大家参考,具体内容如下 程序控制分析: 1、欢迎页循环:do-while2、Scanner 控制输入3、选择页循环:switch-case 要求: 订单...
    99+
    2024-04-02
  • C#实现简单点餐系统
    本文实例为大家分享了C#实现简单点餐系统的具体代码,供大家参考,具体内容如下 实现简单点餐系统剖析 1、设计界面(给菜品的序号(index),名称(name),单价(money)加上...
    99+
    2024-04-02
  • Unity实现单机游戏每日签到系统
    本文实例为大家分享了Unity实现每日签到系统的具体代码,供大家参考,具体内容如下 代码: using System; using System.Collections; us...
    99+
    2024-04-02
  • 重装win7系统的简单教程
    相信很多小伙伴都知道重装win7系统,,比如:使用U盘重装、光驱重装或者使用工具重装什么的,但是也不排除有的小白用户不知道,怎么重装win7系统。其实最简单的方法就使用系统重装软件来进行了,这里小编给大家推荐咔咔一键装机,下面小编就教大家使...
    99+
    2023-07-11
  • java实现简单银行ATM系统
    本文实例为大家分享了java实现简单银行ATM系统的具体代码,供大家参考,具体内容如下 #ATM系统 ##功能 模拟银行ATM机系统,具有注册、登录功能用户登录后可实现以下功能:1)...
    99+
    2024-04-02
  • C++实现简单通讯录系统
    本文实例为大家分享了C++实现简单通讯录系统的具体代码,供大家参考,具体内容如下 需求分析: 1.通讯录可以添加联系人。 2.通讯录可以显示所有联系人。 3.通讯录可以查找联系人。 ...
    99+
    2024-04-02
  • Java简单实现银行ATM系统
    本文实例为大家分享了Java实现银行ATM系统的具体代码,供大家参考,具体内容如下 实现步骤: 定义账户类,用于后期创建账户对象封装用户的账户信息。 账户类中的信息至少需要包含(卡号...
    99+
    2024-04-02
  • C语言实现简单的抽奖系统
    本文实例为大家分享了C语言实现简单的抽奖系统的具体代码,供大家参考,具体内容如下 效果图 #include<stdio.h> #include<string.h...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作