Unity: Need to reset a pooled object on return to pool. Perhaps using ScriptableObject?

对着背影说爱祢 提交于 2019-12-06 09:18:11

Note!!

From about 2014, as a rule you do not need to pool in Unity. Unity drastically improved performance so that, for typical game scenarios, it is not necessary.

Note that the OP eliminated the problem simply by removing their hand-pooling attempt.

In recent years Unity drastically improved their

  • garbage collection

  • memory handling

  • pool-like handling triggering heuristics

  • prefab and instantiation processes

Object creation in video games is completely trivial on modern hardware; typical scenarios like "bullets" only amount to a dozen or so items perhaps in a second; and you have a vast amount of luxury time in future quiet frames to do gc, etc. In the early days of Unity, you would have to write pooling by hand to achieve typical game multiple object requirements such as bullets. Thanks to Unity's efforts, this is now totally unnecessary for typical game scenarios (bullets, multiple NPCs etc).

You can pool if for some reason you want to, but it is totally unnecessary performance-wise, for typical video game needs. 2D or 3D.

If you only ever need to reset the object's values whenever it deactivates, couldn't you simply use:

OnEnable()
{
    default = data;
}

OnDisable()
{
    data = default;
}

That would allow you to store / assign default data when it activates, and reset its data back to the default values when it deactivates.

andiwin

How about when you created the object, in the Awake() or Start() save the default value that you want to have into bunch of variables or store it inside dictionary,

after that to reset the value just make a method maybe with name called Reset() and assign all the variables with the default values that you have stored before.

e.g.

// method 1
Dictionary<string, object> defaultValues = new Dictionary<string, object>();
int speed = 10;
List<float> scores = new List<float>() {1.5f, 3.4f};

// method 2
SomeClass something = new SomeClass();
SomeClass defaultSomething = new SomeClass();

// and if the type can use const
string sth = "abc";
const string defaultSth = "abc";

void Awake()
{
    defaultValues.Add("speed", speed); 
    defaultValues.Add("scores", new List<float>(scores)); // new list because it is reference type, 
    //and you dont want to store reference to the list because it will be edited during runtime  

    defaultSomething = something.Clone(); // edit, but you need to implement clone by yourself for that class or do something that will make other instance of the class with same value
}

void Reset()
{
    speed = (int) defaultValues["speed"];
    scores = (List<float>) defaultValues["scores"];

    something = defaultSomething.Clone();
    sth = defaultSth;
}

The downside is every instance will store their own default variables occupying memory, you could change them into static or const if you want later on

The other way is you make 1 instance which is used for just storing default value (dont modify this in runtime) and use C# reflection to copy all members value

C# Using Reflection to copy base class properties

Hope this helps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!