问题:属性(Property)和访问器(Accessor)
如果在当前属性中直接添加自定义get和set访问器,在Unity引擎中访问/修改此属性时游戏会闪退。
1 2 3 4 5 6 7 8 9
| public class TestClass : MonoBehaviour { public int TestProperty { get { return TestProperty;} set { TestProperty = value; } } }
|
解决方案
- 直接使用默认访问器
1 2 3 4 5 6 7
| public class StartPage : MonoBehaviour { public int TestProperty { get; set; } }
|
- 创建一个新属性专门用于访问
1 2 3 4 5 6 7 8 9 10 11
| public class StartPage : MonoBehaviour { private int testProperty;
public int TestProperty { get { return testProperty;} set { testProperty = value; } } }
|
问题:Start函数中使用不当loop循环
如果在start函数中使用while循环处理资源加载进度条,Unity引擎会在importing asset弹窗中卡死
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class TestClass : MonoBehaviour { [SerializeField] private Progressbar loadingBar; [SerializeField] private AssetLabelReference gameImageAssets; void Start() { AsyncOperationHandle asyncHandle = Addressables.LoadAssetsAsync<Sprite>(gameImageAssets, _ => {}); asyncHandle.Completed += EnterGame; StartCoroutine(GameLoadingCoroutine(asyncHandle)); }
private IEnumerator GameLoadingCoroutine(AsyncOperationHandle handle) {
while (!handle.IsDone && handle.PercentComplete < 1f) loadingBar.SetProgressPercent(handle.PercentComplete); }
private void EnterGame() { } }
|
解决方案
使用协程(Coroutine)将while操作与Unity生命周期同步
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class TestClass : MonoBehaviour { [SerializeField] private Progressbar loadingBar; [SerializeField] private AssetLabelReference gameImageAssets; void Start() { AsyncOperationHandle asyncHandle = Addressables.LoadAssetsAsync<Sprite>(gameImageAssets, _ => {}); StartCoroutine(GameLoadingCoroutine(asyncHandle)); }
private IEnumerator GameLoadingCoroutine(AsyncOperationHandle handle) { while (!handle.IsDone && handle.PercentComplete < 1f) { loadingBar.SetProgressPercent(handle.PercentComplete); yield return null; }
if (handle.Status == AsyncOperationStatus.Succeeded) EnterGame(); else Debug.LogError($"Failed to load game asset sprites: {handle.Status}"); }
private void EnterGame() { } }
|
问题:在Awake/Start函数中修改GameObject位置
在Awake/Start函数中GameObject的position component尚未初始化完成,此时修改位置将不会起作用
1 2 3 4 5 6
| private void Start() { var newPos = transform.localPosition; newPos.y += 100; transform.localPosition = newPos; }
|
解决方案
- 在Start函数中等待一帧后再修改位置,此时GameObject的position component可使用
1 2 3 4 5 6 7 8
| private IEnumerator Start() { yield return null; var newPos = transform.localPosition; newPos.y += 100; transform.localPosition = newPos; }
|
- 在Awake/Start函数之后的函数进行修改位置操作
问题:使用dotween移动layout group中的游戏对象会影响其他游戏对象
举例:一个老虎机有5个转轴Reel[] reels,移动reels[2]会将reels[0]和reels[1]的position清零