【问题标题】:Terrible FPS in simple game简单游戏中可怕的FPS
【发布时间】:2015-07-28 17:41:36
【问题描述】:

所以我正在制作一个简单的 2d 游戏,玩家在 x 轴上移动并捡起掉落的物体。我有一个脚本可以在播放器上方生成对象,这里是:

using UnityEngine;
using System.Collections;

public class Spawner : MonoBehaviour
{
    private GameObject[] locationsToSpawn;
    private float counter = 0;
    [SerializeField]
    string[] listOfPossibleTags;
    [SerializeField]
    GameObject[] objectToSpawn;
    [SerializeField]
    float timeBetweenSpawns = 3.0f;

    void Start()
    {
        locationsToSpawn = GameObject.FindGameObjectsWithTag("SpawnLocation");
    }
    void Update()
    {
        counter += Time.deltaTime;
        if (counter > timeBetweenSpawns)
        {
            GameObject spawnedObject;
            spawnedObject = Instantiate(objectToSpawn[Random.Range(0,objectToSpawn.Length)], locationsToSpawn[Random.Range(0, locationsToSpawn.Length)].transform.position, Quaternion.identity) as GameObject;
            spawnedObject.gameObject.tag = listOfPossibleTags[Random.Range(0, listOfPossibleTags.Length)];
            counter = 0;
        }
    }
}

但是,在拾取了几个对象后,游戏变得如此缓慢,最终导致 Unity 崩溃!我有 Intel i7、8GB RAM、Nvidia 550m,所以我的笔记本电脑可能不是问题。还值得一提的是,我的点数计数器对我的生成对象发疯了,但我完美地计算了我手动放置的对象(换句话说,生成的对象使我的点数计数器计数太多点)。关于为什么我的游戏导致低 FPS 的任何想法?谢谢!

【问题讨论】:

  • 你能在这里添加你的“拾取”脚本吗?
  • 顺便说一句,您应该设置counter -= timeBetweenSpawns,而不是将counter 设置为零。这消除了余数错误,并且您希望养成以这种方式编写它的习惯。当您处理更快的事件时,它变得更加重要,例如每隔几帧发生一次的事件。

标签: performance unity3d frame-rate


【解决方案1】:

使用分析器测试您的游戏并寻找游戏中的尖峰。这将帮助您轻松识别代码的哪一部分造成了问题,因为您的对象生成脚本不一定会导致问题。

在我的一个项目中,我遇到了一个问题,我的字体导致 FPS 下降。

正如您提到的“积分计数器”,我想问您是否使用自定义字体?如果是,那么它是否设置为动态?如果是,那么这可能是问题,因为 Unity 在运行时和每次更新文本时都会呈现动态字体,因此建议对静态菜单使用动态字体,而不是不断更改的文本。

有关分析器的更多详细信息,请查看以下链接:

  1. Introduction to Profiler - Unity Official Tutorial
  2. Unity Manual - Profiler
  3. Unity Manual - Profiler Window

【讨论】:

    【解决方案2】:

    问题似乎是您在运行时在“更新”中实例化了很多游戏对象,而不是销毁它们。理想情况下,您应该做的是只实例化一次所需的游戏对象,将其存储在对象池中并在运行时重用它。有很多例子可以做到这一点,你只需要谷歌。

    【讨论】:

      【解决方案3】:

      你是否正在从记忆中释放“拾取”的物品?当您创建每一个时,它使用内存来处理位置、移动等。如果您不释放该内存,那么最终您会用完它。

      我只看过 Unity 的视频,但从未在其中编码,所以我无法解释如何释放内存,但我知道所有计算机程序都必须释放内存。所以语言和软件自动释放内存......其他必须手动完成。

      【讨论】:

        【解决方案4】:

        首先,所有游戏都将是实例化方法的滞后原因。如果您需要使用它,请在void Start() {...}void Awake() {...} 中使用它并缓存所有创建的对象。使用这些缓存对象创建对象池并节省性能。

        不要使用 Unitys 创建实例的转换,确保创建缓存对象

        private Transform _transform;
        void Start() {
            _transform = transform;
        }
        

        不要自己计算counter > timebetweenSpawn,请确保使用InvokeRepeating 来节省性能。

        确保在编辑器中创建的对象(如果不是移动的对象)是静态的。如果不移动,则不必重新绘制它们。

        Unity Profiler 将是你最好的朋友。对所有内容进行基准测试。

        不要在Transform 对象上更改比例,最好更改您正在使用的图像的大小。规模需要性能。

        FixedUpdate = 物理

        更新 = 游戏逻辑

        留意 TrisVerts,您希望它们尽可能低。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-08
          • 2012-02-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多