1. World Space模式下的UI
在我的游戏中,需要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
2. 镜像动画的方法
我的模型动画需要根据模型在屏幕上的位置来决定是否镜像。比如,模型在左侧时,打盹动画是人物头向左躺下;在右侧时,打盹动画是人物头向右躺下。为此,我写了一个有参的镜像动画函数,传入模型在屏幕上的位置(左侧还是右侧),据此决定是否镜像动画。
具体的镜像动画方法是把Animator.transform.localScale对应的轴(注意:不是旋转轴)的值改为-1。例如,在x轴上镜像(即左右镜像),则为
Vector3 scale = obAnimator.transform.localScale;
scale.x = -1;
obAnimator.transform.localScale = scale;
3. 处理大量按钮逻辑的方法
我的项目中按钮很多,所以我也写了个有参的按钮事件函数,把按钮传进去,不同按钮执行不同逻辑。
4. 失活游戏物体可能影响物体的动画播放
我的游戏中右键可以呼出菜单,为此我制作了一个菜单打开动画。最开始我用SetActive来控制菜单的打开和关闭,但我发现,直接这样写关闭菜单的逻辑有问题:
menuAnimator.SetBool("openMenu2", false);
menu.SetActive(false);
关闭菜单动画的bool后,如果直接失活菜单,动画有可能来不及执行完。这样再次激活菜单时,菜单还是在打开状态,会闪一下再播放菜单打开动画。
解决方法:失活菜单的SpriteRenderer而非GameObject
5. 根据输入的中文/英文灵活控制输入框字符长度限制
由于单行输入框长度有限,因此在输入文字或密码时,一般会限制输入内容的长度。在TMP Input Field中,用参数Character Limit来控制输入内容长度。但这个参数不区分中文英文。例如,如果把它设为10,那么无论输入的是中文还是英文,最多都可以输入10个字。但中文占位长度是英文的两倍,所以如果按英文字符长度设置限制,那么输入中文时就可能溢出输入框。
解决方法:根据UTF-16里的基本汉字范围(0×4e00到0×9fff)来判断输入的文字是否为中文
public int InputCharacterLimit(string input)
{
int limit = 12;
foreach (char c in input)
{
if (char.IsHighSurrogate(c) || char.IsLowSurrogate(c))
{
// 对于UTF-16中的代理对(可能表示一个中文字符),计为一个字符
continue;
}
else if (c >= 0x4e00 && c <= 0x9fff) // 基本汉字范围
{
limit --; // 中文字符计为两个单位
}
else
{
// 其他字符计为一个单位
}
}
return limit;
}
在Update代码块中加入以下代码
#region 检测输入框字符长度
if(inputNameText != null && namePanel.activeSelf == true)
{
//实时设置姓名输入框文字长度限制
inputNameText.characterLimit = InputCharacterLimit(inputNameText.text);
}
#endregion
此外,TMP字体和True Type字体相比会占用较大体积,因此使用TMP之前务必考虑清楚。
6. 根据模型面朝向决定旋转方向
在我的游戏中,需要根据模型在屏幕上的位置(左侧还是右侧)决定跑步、读书等动画播放完成后的旋转方向。利用在Unity基础课程中学习的向量点乘知识,我用模型面朝向和Vector3.right的点乘来判断模型是面朝左还是面朝右。(如果点积接近1则面朝右,如果点积接近-1则面朝左。在我的游戏中,模型需要旋转时一般都面朝正右或正左方向,所以下面的逻辑简略了)
// 根据点乘的值判断朝向
if (Vector3.Dot(transform.forward, Vector3.right) > 0.5f) // 假设0.5f是阈值
{
//模型面朝右时的旋转逻辑
}
else
{
//模型面朝左时的旋转逻辑
}
7. 灵活运用TODO Tree
当脚本需要大量修改调整时,使用TODO Tree来进行分类标记非常方便。以下是TODO Tree的默认分类标签,对我来说足够用了。当然,也可以设置更个性化的分类标签。
TODO:待办标记
HACK:待修改标记
FIXME:待修复标记
XXX:改进标记