x


Instantiate for storage -- don't display

Hey everyone,

I'm doing some basic experimentation with the engine for a possible future game that would involve some time-warping aspects (e.g. Prince of Persia). Essentially, I want to be able to save the state of a Game Object (in this case, the Player), store it, and then recall it if needed.

I seem to be able to do this with

var Copy_of_Player = Instantiate(Player_Object)

However, the one problem with this is that as soon as the object is Instantiated, it is activated (all the scripts begin to run) and rendered. I seem to be able to do:

Copy_of_Player.active = false;

To stop the scripts/movement/etc. However, when I also try to do:

Copy_of_Player.renderer.enabled = false;

I get an error that there is no renderer attached to Copy_of_Player. (Actually, the exact Debug message says "No renderer attached to Player(Clone)")

This is a top-level Game Object in the hierarchy...it has scripts as well as several meshes. What am I doing wrong?

In addition, if anyone can point out a better way to save the state of a Game Object for later use (I basically want to be able to put all the main components of a level that are within range back to the way they were 5 seconds ago), that would be greatly appreciated.

Thanks!

more ▼

asked Aug 05 '10 at 01:15 PM

Riley D. gravatar image

Riley D.
64 3 4 8

(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

A naive brute force approach that should work is to create a Memento object (class, struct or even array if you like) that stores just the variables in question.

Something like memento.storeState(Player_Object); and then memento.applyState(Player_Object). If you add more variables that you want saved, you'd have to add them to the memento and its functions, but this should work.

Unity js

class Memento
{
    var foo : Type1;
    var bar : Type2;

    function storeState(player_Object : GameObject)
    {
        var script : ScriptName = player_Object.GetComponent(ScriptName);
        foo = script.foo;
        bar = script.bar;
    }

    function applyState(player_Object : GameObject)
    {
        var script : ScriptName = player_Object.GetComponent(ScriptName);
        script.foo = foo;
        script.bar = bar;
    }
}

Unity mono

class Memento
{
    Type1 foo;
    Type2 bar;

    void storeState(GameObject player_Object)
    {
        ScriptName script = player_Object.GetComponent<ScriptName>();
        foo = script.foo;
        bar = script.bar;
    }

    void applyState(GameObject player_Object)
    {
        ScriptName script = player_Object.GetComponent<ScriptName>();
        script.foo = foo;
        script.bar = bar;
    }
}

Obviously if you wanted to access variables stored in the transform or anywhere else in the object, you could do that too.

To implement an actual memento pattern, you would in stead have a class representing the state and you would then apply that rather than directly tweaking each variable. The Player_Object would contain an instance of this state as would the memento and the memento's functions would never change they'd just be state = script.state and script.state = state. Then, whenever you wanted to add variables to the state, you would simply add them to the state class and the memento would just work without changes. But with this implementation, you could also cut out the Memento completely and just store an instance of the state class. I don't recall off the top of my head whether the Unity js treats user-defined classes as reference types and if it does, this implementation may require you to implement a deep copy function (clone, assignment operator overload, etc.)

more ▼

answered Aug 05 '10 at 02:31 PM

skovacs1 gravatar image

skovacs1
10k 11 25 91

Thanks for the tip, a Momento class certainly makes sense, especially if I could make it generic enough for all of the enemies as well.

Any thoughts on the Object.renderer.enabled = false business?

Aug 05 '10 at 02:35 PM Riley D.

Also, this might be a bit less memory consuming than re-instantiating your player and activating all of its scripts, renderers, etc. depending on how much you actually care to store.

Aug 05 '10 at 02:43 PM skovacs1

Still looking into it. When you deactivate the object, without disabling the renderer, is it actually being rendered?

Aug 05 '10 at 02:44 PM skovacs1

Yes. I have tried a couple of things... setting active = false still renders the full object (all parts), but it just stays motionless. I wrote a recursive renderer function that checks each transform for a renderer and disables it if found. This seems to work correctly, but it's missing things like projectors and point lights. Memory-wise, though, it really doesn't seem too terrible. Saving the state does take quite a bit of CPU power, though (drops the framerate about in half to save the state every 0.03 seconds (30 times per second)).

Aug 05 '10 at 03:16 PM Riley D.

I'm surprised there isn't some sort of "create off stage" function, to prepare an object then bring it into play when needed. I suppose I could just move the object 500 units upward and then 500 back downward when I wanted to use it, but that seems a little hacky. My only concern with the Momento class is that I'd essentially be hoping the game plays out the exact same over those 5 seconds...what I'm doing now is more akin to freezing the object and then popping them in and out really quickly so it looks like it's moving, but really it's just a series of frozen states. Does that make sense?

Aug 05 '10 at 03:18 PM Riley D.
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x2086
x1672
x2

asked: Aug 05 '10 at 01:15 PM

Seen: 626 times

Last Updated: Aug 05 '10 at 01:15 PM