首页 > 分享 > 【菜菜丸的菜鸟教程】桌宠制作经验分享

【菜菜丸的菜鸟教程】桌宠制作经验分享

最近我做了一个桌宠小项目,可以实现随机对话、随机动画以及密码保管箱等实用功能。演示视频:https://www.bilibili.com/video/BV1wJ4m1K74p/

项目安装包已上传到GitHub,地址如下:https://github.com/pennylmj/Unity-Projects https://github.com/pennylmj/Unity-Projects

(如果大家导入工程后发现点击人物无反应,请添加一个名为“Player”的Layer,并将场景中的物体“Ob”设为这个Layer)

鉴于整个桌宠项目涉及2D动画、3D动画、数据加密、UI制作等大量内容,做成分步教程会很繁琐。所以这里我用发布项目工程+知识点总结的方式,和大家分享我在制作过程中积累的一些经验,希望能帮助到更多小伙伴。

参考脚本:https://www.bilibili.com/read/cv21407303/

背景颜色需要选择和模型边缘相近的颜色,因为抠掉背景后会带一圈毛边(大概1个像素),毛边的颜色就是背景色。代码中使用的颜色是COLORREF值,微软官方手册的解释如下:

也就是说,COLORREF值的格式是0x00+蓝色分量值+绿色分量值+红色分量值

其中Hexadecimal是16进制颜色值,但它的排列顺序是RGB(红色分量值、绿色分量值、蓝色分量值)

从直观上看,只需要把Hexadecimal颜色值的顺序按BGR来调整,并在前面加上0x00,就能转换为COLORREF值。

模型姿态会产生变化,比如坐、跑、转身等等,所以需要根据情况动态计算模型和屏幕边缘的距离。就我的模型和动作而言,只需用头部和脚部碰撞器来进行计算。先计算出模型中心和碰撞器的位置偏移,再加上碰撞器的半径,就可以得出模型和屏幕边缘的最小允许距离。在Update里,根据算出的数值进行屏幕边界检测,实时更新物体的位置,使之不超过屏幕边界,具体是用Mathf.Clamp这个函数来实现。

我的模型动画需要根据模型在屏幕上的位置来决定是否镜像。比如,模型在左侧时,打盹动画是人物头向左躺下;在右侧时,打盹动画是人物头向右躺下。

一是和屏幕边缘检测有关,比如人物躺下的动画是用头部碰撞器来检测和屏幕边缘的距离,那么在屏幕左侧和右侧躺下时,都需要头部离屏幕边缘最近,因此就要镜像动画。

二是看起来更符合行为逻辑,更顺眼。跑步:在左侧就往左边跑,在右侧就往右边跑。

实现方法:我写了一个有参的镜像动画函数,传入模型在屏幕上的位置(左侧还是右侧),据此决定是否镜像动画。

具体的镜像动画方法是把Animator.transform.localScale对应的轴(注意:不是旋转轴)的值改为-1。例如,在x轴上镜像(即左右镜像),则为

Vector3 scale = obAnimator.transform.localScale; scale.x = -1; obAnimator.transform.localScale = scale;

原则:空闲动作(Idle)可以切换为任意一种动作(跑步、打盹、看书等),其他动作只能切换为空闲动作。这是为了避免来回乱切,比如跑着跑着突然躺下睡觉,看起来会很怪。

实现方法:用协程做一个倒计时器,每种动作的持续时间在一定范围内随机,倒计时结束时就按一定概率切换为另一个动作。

在我的游戏中,需要UI跟随人物移动,因此我把Canvas改为了world space。但改为world space后,UI将变得非常巨大。我的项目最后把Canvas的scale改为(0.001, 0.001, 0),这样看起来是比较正常的,后面计算UI实时位置也比较好换算。也可以根据官方手册推荐的方法来进行调整:https://docs.unity3d.com/cn/2021.1/Manual/HOWTO-UIWorldSpace.html https://docs.unity3d.com/cn/2021.1/Manual/HOWTO-UIWorldSpace.html

我的项目中按钮很多,所以我也写了个有参的按钮事件函数,把按钮传进去,不同按钮执行不同逻辑。

我的游戏中右键可以呼出菜单,为此我制作了一个菜单打开动画。最开始我用SetActive来控制菜单的打开和关闭,但我发现,直接这样写关闭菜单的逻辑有问题:

menuAnimator.SetBool("openMenu2", false); menu.SetActive(false);

关闭菜单动画的bool后,如果直接失活菜单,动画有可能来不及执行完。这样再次激活菜单时,菜单还是在打开状态,会闪一下再播放菜单打开动画。

解决方法:失活菜单的SpriteRenderer而非GameObject

八、根据输入的中文/英文灵活控制输入框字符长度限制

由于单行输入框长度有限,因此在输入文字或密码时,一般会限制输入内容的长度。在TMP Input Field中,用参数Character Limit来控制输入内容长度。但这个参数不区分中文英文。例如,如果把它设为10,那么无论输入的是中文还是英文,最多都可以输入10个字。但中文占位长度是英文的两倍,所以如果按英文字符长度设置限制,那么输入中文时就可能溢出输入框。

解决方法:根据UTF-16里的基本汉字范围(0x4e00到0x9fff)来判断输入的文字是否为中文

public int InputCharacterLimit(string input) { int limit = 12; foreach (char c in input) { if (char.IsHighSurrogate(c) || char.IsLowSurrogate(c)) { continue; } else if (c >= 0x4e00 && c <= 0x9fff) { limit --; } else { } } return limit; }

#region 检测输入框字符长度 if(inputNameText != null && namePanel.activeSelf == true) { inputNameText.characterLimit = InputCharacterLimit(inputNameText.text); } #endregion

此外,TMP字体和True Type字体相比会占用较大体积,因此使用TMP之前务必考虑清楚。

在我的游戏中,需要根据模型在屏幕上的位置(左侧还是右侧)决定跑步、读书等动画播放完成后的旋转方向。利用在Unity基础课程中学习的向量点乘知识,我用模型面朝向和Vector3.right的点乘来判断模型是面朝左还是面朝右。(如果点积接近1则面朝右,如果点积接近-1则面朝左。在我的游戏中,模型需要旋转时一般都面朝正右或正左方向,所以下面的逻辑简略了)

if (Vector3.Dot(transform.forward, Vector3.right) > 0.5f) { } else { }

当脚本需要大量修改调整时,下载TODO Tree插件,并用它来进行分类标记非常方便。以下是TODO Tree的默认分类标签,对我来说足够用了。当然,也可以设置更个性化的分类标签。

相关知识

【菜菜丸的菜鸟教程】桌宠制作经验分享
[官方新闻] 盛世庆典原创经验分享
桌宠吧
【Python教程】教你用Python代码制作一个桌面宠物,专属桌宠,体验感升级1000%(附源码)
【Python程序】用200行Python代码制作有趣的桌面宠物(源码可分享),大打工人解压放松程序,如何用Python制作一个桌面宠物!
玩具鼠手工制作教程
虚拟桌宠模拟器 常见问题 Q&A
【附源码】教你用Python1分钟制作出专属你的桌面宠物,桌面体验感100%拉满!小白也能学会的保姆级教程,桌面宠物,Python0基础
电脑病毒=桌宠?
怎么制作狗唱歌特效教程,宠物唱歌的视频怎么做:在线特效教程大全

网址: 【菜菜丸的菜鸟教程】桌宠制作经验分享 https://m.mcbbbk.com/newsview371666.html

所属分类:萌宠日常
上一篇: 基于Qt实现桌面宠物
下一篇: 在 30 分钟内构建宠物探测器!