这里与Texture2D有关的内存泄漏在哪里



我有一个内存泄漏的问题,我把它隔离到这个脚本中,我认为这是游戏每帧都制作一个新纹理的问题,但我实际上不知道如何修复它。

我在网上读到,为每一帧创建一个纹理是不好的,因为它是一个引擎管理的资源,所以它不会自动被垃圾收集,我需要发布它,但我不知道在哪里发布。我应该在发布它的地方进行后期更新吗?

public float height = 10f;
public float width = 2f;
public float defaultSpread = 10f;
public Color color = Color.grey;
public bool resizeable = false;
public float resizedSpread = 20f;
public float resizeSpeed = 3f;
[SerializeField]
float velocityMin = 210;
float spread;
bool resizing = false;
CharacterController player;
void Awake()
{
//set spread
spread = defaultSpread;
player = GameObject.FindGameObjectWithTag("Player").GetComponent<CharacterController>();
}
void Update()
{
if (player.velocity.sqrMagnitude > velocityMin) { resizing = true; } else { resizing = false; }
if (resizeable)
{
if (resizing)
{
//increase spread 
spread = Mathf.Lerp(spread, resizedSpread, resizeSpeed * Time.deltaTime);
}
else
{
//decrease spread
spread = Mathf.Lerp(spread, defaultSpread, resizeSpeed * Time.deltaTime);
}
//clamp spread
spread = Mathf.Clamp(spread, defaultSpread, resizedSpread);
}
}
void OnGUI()
{
Texture2D texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, color);
texture.wrapMode = TextureWrapMode.Repeat;
texture.Apply();
//up rect
GUI.DrawTexture(new Rect(Screen.width / 2 - width / 2, (Screen.height / 2 - height / 2) + spread / 2, width, height), texture);
//down rect
GUI.DrawTexture(new Rect(Screen.width / 2 - width / 2, (Screen.height / 2 - height / 2) - spread / 2, width, height), texture);
//left rect
GUI.DrawTexture(new Rect((Screen.width / 2 - height / 2) + spread / 2, Screen.height / 2 - width / 2, height, width), texture);
//right rect
GUI.DrawTexture(new Rect((Screen.width / 2 - height / 2) - spread / 2, Screen.height / 2 - width / 2, height, width), texture);
}
public void SetRisizing(bool state)
{
resizing = state;
}

为什么在onGui函数中运行此代码?https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnGUI.html

您的OnGUI实现可能在每帧中被调用多次(每个事件调用一次(。

来自IMGUI文档:https://docs.unity3d.com/Manual/GUIScriptingGuide.html

IMGUI系统通常不用于玩家可能使用和交互的正常游戏内用户界面。为此,您应该使用Unity的主要基于GameObject的UI系统,该系统提供了一种基于GameObject来编辑和定位UI元素的方法,并且有更好的工具来处理UI的视觉设计和布局。

已解决!正如@Athanasios Kataras所建议的,使变量持久化解决了问题。事实上,我以前曾试图让它持续下去,但没有奏效。我现在才想起来,我实际上并没有保存文件。

这是重新编写的代码:

public float height = 10f;
public float width = 2f;
public float defaultSpread = 10f;
public Color color = Color.grey;
public bool resizeable = false;
public float resizedSpread = 20f;
public float resizeSpeed = 3f;
[SerializeField]
float velocityMin = 210;
float spread = 0;
bool resizing = false;
CharacterController player;
Texture2D texture;
void Awake()
{
//set spread
spread = defaultSpread;
player = GameObject.FindGameObjectWithTag("Player").GetComponent<CharacterController>();
texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, color);
texture.wrapMode = TextureWrapMode.Repeat;
texture.Apply();
}
void Update()
{
if (player.velocity.sqrMagnitude > velocityMin) { resizing = true; } else { resizing = false; }
if (resizeable)
{
if (resizing)
{
//increase spread 
spread = Mathf.Lerp(spread, resizedSpread, resizeSpeed * Time.deltaTime);
}
else
{
//decrease spread
spread = Mathf.Lerp(spread, defaultSpread, resizeSpeed * Time.deltaTime);
}
//clamp spread
spread = Mathf.Clamp(spread, defaultSpread, resizedSpread);
}
}
void OnGUI()
{
//up rect
GUI.DrawTexture(new Rect(Screen.width / 2 - width / 2, (Screen.height / 2 - height / 2) + spread / 2, width, height), texture);
//down rect
GUI.DrawTexture(new Rect(Screen.width / 2 - width / 2, (Screen.height / 2 - height / 2) - spread / 2, width, height), texture);
//left rect
GUI.DrawTexture(new Rect((Screen.width / 2 - height / 2) + spread / 2, Screen.height / 2 - width / 2, height, width), texture);
//right rect
GUI.DrawTexture(new Rect((Screen.width / 2 - height / 2) - spread / 2, Screen.height / 2 - width / 2, height, width), texture);
}

它仍然在OnGUI中运行,因为我使用的是GUI功能,也因为我在运行这款游戏时获得了400帧/秒的速度,我真的不需要花时间来削弱一点点性能。

最新更新