社区问答 | 本周问答汇总 0921-0927

文摘   科技   2024-09-27 19:10   上海  

本文汇总了 2024 年 9 月 21 日 - 2024 年 9 月 27 日 Unity 中文社区精选问答。如果在使用 Unity 过程中遇到任何问题,欢迎点击阅读原文前往 Unity 中文社区提问,将有官方技术支持及社区贡献者当日解答此外,本周还有少量待解决问题,欢迎小伙伴们到社区分享经验,为他人答疑解惑。

本期问题目录:

新手答疑:
1. 无法导入文件
2. 动画动作切换
3. 求回合制战斗 RPG 的游戏学习路线
4. Unity 6 代码过时问题
5. Unity Android 打包
6. 为什么我中添加了一个角色之后原先的角色动不了了,添加空父对象也动不了?

7. netcode 问题

技术支持:

8. 在信号处理函数中无法获取完整 C# 栈

技术交流:

9. 关于 collision.GetComponent<脚本名字>(). 方法会导致系统报错却任然可以正常运行的问题

10. sence 画面和 game 画面颜色不一样

团结引擎:

11. 关于打包鸿蒙安装包时包体大小的疑问

微信小游戏:

12. 微信小游戏分享失败

云开发:

13. 为什么切换不了组织了

建议与反馈:
14. 开发 2D 俯视角游戏,不知道怎么设置精灵锚点和相机渲染排序
新手答疑
  Q1.无法导入文件

答主 溜肉段
你现在是安全模式,如果 textmesh pro 不需要的话,可以把 textmesh pro 插件先卸载,进入正常模式后再进行文件导入操作。

  Q2.动画动作切换

当动画动作切换时,比如按下方向键由 idle 切换到 running 时,会有一个 idle 滑动的状态后,才会开始跑起来。或者松开方向键由 running 切换到 idle 时,会原地跑步。

答主 溜肉段:
可以把过渡时间去掉再试下。

  Q3.求回合制战斗 RPG 的游戏学习路线

想做类似 RPGmaker 结构的游戏,类似《雨血》系列这种,但非常不想要 RPGmaker,实在太限制而且没教程。

想学如何丰富战斗系统,比如技能设计、动作关键帧判定、各种 buff/debuff 设计等;

另外架构思维和内容设计的教程几乎没有,大部分都是做个 DEMO,代码不像做产品那样条理规整,希望大佬们推荐个学习路线~

答主 Penny Lu
Unity 通过协程实现回合制战斗:

https://learn.u3d.cn/tutorial/unity-tbs

  Q4.Unity 6 代码过时问题

各位大佬,现在 Unity 6 里 EditorWindow 的 onSelectionChange 过时了我有什么解决办法?顺便问一下这种过时代码的替代要怎么去找?

答主 溜肉段

可以看下 Unity 6 的文档~

https://docs.unity3d.com/6000.0/Documentation/ScriptReference/index.html
  Q5.Unity Android 打包

官方回答:

更新一下你的安卓 sdk 版本。

  Q6.为什么我中添加了一个角色之后原先的角色动不了了,添加空父对象也动不了?

官方回答:

把 Time.timeScale=0 注释掉试试

  Q7.netcode 问题

[Netcode] A ConnectionApproval callback is defined but ConnectionApproval is disabled. In order to use ConnectionApproval it has to be explicitly enabled ConnectionApproval 设置为 true 的时候,数据传入 ConnectionData,会报上面的 warn,怎么解决?本地局域网的连接。

团结 MuseChat 已解决:

解决这个问题的步骤如下:
确保在 NetworkManager 的 Inspector 中启用了 ConnectionApproval 选项。
定义并实现 ConnectionApproval 回调函数。

在回调函数中处理传入的 ConnectionData,并根据你的逻辑决定是否批准连接。

技术支持
  Q8.在信号处理函数中无法获取完整 C# 栈

在安卓应用崩溃后尝试获取 C# 栈。但是在崩溃的信号处理函数中调用 StackTraceUtility.ExtractStackTrace() 或者 Environment.StackTrace,获取的栈中只有 C# 回调函数,没有崩溃前的栈,请问这是个 bug 还是特性?动态库代码:

#include <android/log.h>#include <signal.h>#include <string.h>#include <unistd.h>
#define LOG_TAG "SigTest"#define LOGI(...) __android_log_print(3, LOG_TAG, __VA_ARGS__)
typedef char* (*CrashCallback)();static CrashCallback gUserCallback = nullptr;struct sigaction old_handler;
//调用C#函数GetCsharpStacktrace()获取C#栈extern "C" void callCsharpFunc() { if (gUserCallback) { LOGI("Call user callback"); char *stack = gUserCallback(); if (stack != nullptr) { LOGI("c# stack: %s", stack); } } else { LOGI("No user callback registered"); }}
//崩溃信号处理函数void SignalHandler(int sig, siginfo_t* info, void* uc) { callCsharpFunc(); if (sigaction(SIGSEGV, &old_handler, NULL) == -1) { signal(SIGSEGV, SIG_DFL); } _exit(1);}
//注册崩溃信号处理函数extern "C" void installSigHandler() { if (sigaction(SIGSEGV, NULL, &old_handler) == -1) { return; } struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = SignalHandler; sa.sa_flags = SA_SIGINFO; if (sigaction(SIGSEGV, &sa, NULL) == -1) { LOGI("sigaction fail"); } LOGI("installSigHandler ok");}
//保存C#回调函数指针extern "C" void registerCrashCallback(CrashCallback crashCallback) { gUserCallback = crashCallback; LOGI("registerCrashCallback ok");}
//抛信号,造成崩溃extern "C" void makeCrash() { LOGI("make crash"); raise(SIGSEGV);}
C# 代码:
 using AOT;using System;using System.Runtime.InteropServices;using UnityEngine;
class MyClass{ public delegate string CrashCallback();
[DllImport("SigTest")] public static extern void installSigHandler();//注册SIGSEGV信号处理函数
[DllImport("SigTest")] public static extern void registerCrashCallback(CrashCallback crashCallback);//注册C#函数
[DllImport("SigTest")] public static extern void callCsharpFunc();//从Native层直接调用C#函数
[DllImport("SigTest")] public static extern void makeCrash();
[MonoPInvokeCallback(typeof(CrashCallback))] public static string GetCsharpStacktrace()//注册到Native层的回调函数 { return StackTraceUtility.ExtractStackTrace(); }
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void OnRuntimeMethodLoad() { installSigHandler(); registerCrashCallback(GetCsharpStacktrace); }}
public class init : MonoBehaviour{ private void OnGUI() { MyClass.callCsharpFunc();//调用注册到动态库中的C#函数
MyClass.makeCrash();//在信号处理函数中调用C#函数 }}

logcat 打印的崩溃前的栈:

MyClass:GetCsharpStacktrace()MyClass:callCsharpFunc() ConsoleToScreen:OnGUI()
崩溃后的栈:
MyClass:GetCsharpStacktrace()
团结 MuseChat 已解决
在信号处理函数中无法获取完整的 C# 栈信息是一个已知的限制,而不是一个 bug。这是因为信号处理函数的执行环境与正常代码执行环境不同,导致无法获取完整的堆栈信息。在信号处理函数中调用 StackTraceUtility.ExtractStackTrace() 或者 Environment.StackTrace 时,只能获取到当前调用栈的信息,而无法获取崩溃前的完整堆栈。
技术交流
  Q9.关于 collision.GetComponent<脚本名字>(). 方法会导致系统报错却任然可以正常运行的问题

我给我游戏里的敌人的脚本添加了一个方法 BeAttacked(),然后想要在我的攻击命中敌人(也就是两者的碰撞检测器相碰撞时)调用这个方法。

但是我现在遇到一个很奇怪的问题,我使用的是 collision.GetComponent().BeAttacked(Damage),然后运行的时候我每攻击一次系统就会报错说我未实例化对象。

但是我用 Debug.Log(collision.gameObject); 获取到的对象是正常的,如上图所示。后来我把"错误暂停"功能关了,虽然每次都会报错但是游戏就是正常运行的,敌人能够正常的受到伤害,并且其它的功能也都能正常的运行。 

请问这个问题是不是 Unity 引擎的问题?有没有什么方法可以解决或者替代方案 (比如不用 collision.GetComponent<脚本名字>().方法(),而是通过别的什么方式实现同样的效果),麻烦大佬帮我答疑解惑一下谢谢!

自答:

笨办法挨个试了一下发现是 Random.Range() 的问题。

  Q10.sence 画面和 game 画面颜色不一样

sence 画面颜色正常,game 画面非常曝,把所有灯全部关闭后,sence 已经变暗了,game 画面还是很亮。

团结 MuseChat 已解决:

请确认以下几点:

在 Game 视图中是否启用了后处理效果(Post Processing)?可以在 Game 视图的右上角找到相关设置。

检查 Lighting 窗口中的环境光设置(Environment Lighting),确保 Scene 和 Game 视图中的设置一致。

确认是否有额外的光源在 Game 视图中启用,可以在 Hierarchy 窗口中查看所有光源对象。
团结引擎
  Q11.关于打包鸿蒙安装包时包体大小的疑问
看到团结引擎支持鸿蒙系统的消息后,深受鼓舞,于是想把自己的一个 2D 游戏项目打包成鸿蒙安装包。打包过程倒是很顺利,没有提示任何报错,可是一看包体大小吓了一跳: 这个项目打包安卓包时只有 38.8MB,可是打包成鸿蒙包后 app 包体大小是 81Mb。而且产生了两个文件:一个是 app 后缀的,对应安卓的话应该是安装包;可是还有两个文件,另一个是后缀为 .hap 的文件,大小也是 81Mb,另一个是个文件夹,里面有好多文件,共计 200 多 MB。三个文件加起来共计 407MB。
由于我以前没有打包过鸿蒙安装包,所以并不知道除了 app 外其他两个是否必需。如果是的话,那么一个在安卓中只有 38mb 的游戏项目,打包成鸿蒙包后将是 407Mb 的体量,增大了整整 10 多倍..... 我相信肯定不是这样的,肯定还有什么设置我不知道,所以我想问问各位大佬专家,团结引擎打包鸿蒙包的时候,要如何做才能让包体减少到跟安卓包差不多大小的程度?至少也不要相差太大。(我用的团结引擎版本是截止提问时的最新版本 1.2.6)。

答主 溜肉段:

hap 是鸿蒙的程序包,包体大小您可以参考下文档,调整一下设置,优化一下代码资源等~

微信小游戏
  Q12.微信小游戏分享失败
showShareMenu:fail no permission
答主 溜肉段:

确定下权限和 appid~

云开发
  Q13.为什么切换不了组织了
Unity ID 中显示有两个组织的:

但是在 UnityHub 中点入“打开远程项目”的时候却只有一个组织,无法切换。

并且在 TjDevops 中也是这样,无法切换。

官方回答

尝试下去添加新组织,在下拉列表中选择另一个组织进入。云开发组织需要先开通,才能在切换组织那里出现。

建议与反馈
  Q14.开发 2D 俯视角游戏,不知道怎么设置精灵锚点和相机渲染排序
开发这类俯视角 2D 游戏的时候,我们必须要做的一个效果就是人物和物体直接的遮挡效果。如图- 我用了一个简单的角色和一个草的资源来演示这个 BUG。 首先我们需要在 Porject Settings 下的 Graphics 里找到相机渲染顺序的轴,如下图。将其设置为自定义渲染顺序的轴,这里我切换成 Custom Axis,值改成了 (0,1,0)。这样呢,相机就可以根据 Y 轴的大小顺序来渲染 Sprite Renderer 图片的遮挡排序了。
然后我将角色和草的锚点也都设置成了底部,参数为(0.5f,0)这样是为了更好的遮挡效果,而 BUG 就出在这样设置之后,渲染顺序没有根据锚点来遮挡,引擎依然是按照图片的中心来识别 Y 轴的遮挡关系,也就是说自己给图片资源设置的锚点是不起作用的。如下情况,注意看注解!

然而这个 BUG,还有一些很奇怪的地方。如果把老的游戏工程文件打开,自定义锚点和 Y 轴排序是正常运行的,但如果在老的工程里新建一个场景,那么 6000/2022/2021 等版本新建出来的场景自定义锚点和 Y 轴顺序渲染又会变得失去作用。而之前 2019 的一些版本则是正常的。

答主 zmrTUvbpkd:
会不会是以 sprite renderer 的 Sprite Sort Point 为排序,而不是以图片的锚点排序。老版本和新版本不一样了,图片锚点设置成底部,再把 sprite renderer 里 Sprite Sort Point 设置成 Pivot 就可以了。


本系列问题汇总将每周更新,欢迎点击阅读原文,与 Unity 中文社区成员一起答疑互助,共同进步。
长按关注
Unity 官方开发者服务平台
第一时间了解 Unity 社区动向,学习开发技巧

 点击“阅读原文”,访问 Unity 社区问答


Unity官方开发者服务平台
Unity引擎官方开发者服务平台,分享技术干货、学习课程、产品信息、前沿案例、活动资讯、直播信息等内容。
 最新文章