Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  How to Save / Load Obi Actors in 5.0
#5
Hi Bill,

What you're doing in Load is:
- Removing the actor from the solver (which unloads the current blueprint automatically)
- Assigning a new  blueprint (this unloads the current blueprint if it is loaded in the solver, and loads the new one if a solver is present).
- Calling LoadBlueprint() again a second time manually, without re-adding the actor to the solver first. This is very dangerous, as it will write data outside the solver's data arrays -which are raw C pointers- and will likely cause a crash. (LoadBlueprint is public only because it needs to be callable by ObiSolver, but it's not supposed to be called manually. Now I realize I should probably guard against manual calls somehow.)

As you can see there's a lot of redundant stuff happening there, and some things that should happen (like having the rope added to its solver at the end) aren't happening.

Getting this to work is way simpler than it looks. No need to remove the actor from the solver manually, load blueprints yourself or anything. Simply set ropeBlueprint to its new value when you need to use a different blueprint, that's it.

The following example does this, with a caveat: since I'm reusing the same blueprint to store the state over and over again, and I want to force a reload of the blueprint everytime (despite being the same blueprint, it might contain different data), I set it to null first.

Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Obi;

public class StateStoreLoad : MonoBehaviour
{
public ObiRope actor;
   private ObiActorBlueprint state;

   public void Update()
{
if (Input.GetKeyDown(KeyCode.I))
Store();
else if (Input.GetKeyDown(KeyCode.O))
Load();
}

public void Store()
{
       // Only create the state blueprint if we haven't created one yet.
       if (state == null)
           state = Instantiate(actor.blueprint);

       // Store particle positions/velocities to the state blueprint.
actor.SaveStateToBlueprint(state);
}

public void Load()
{
       // If we have no state to load, bail out.
if (state == null)
return;

       // we need this to force a blueprint reload, because we are reusing the same one. Setting the exact same blueprint the actor currently uses will have no effect.
       // we could also destroy "state" after loading it, and re-create it in Store(). Then it would not be necessary to set the rope's blueprint to null before reassigning it.
       actor.ropeBlueprint = null;
actor.ropeBlueprint = (ObiRopeBlueprint)state;
}
}

Hope this makes sense! Do not hesitate to reach out if you need further details.
Reply


Messages In This Thread
RE: How to Save / Load Obi Actors in 5.0 - by josemendez - 26-11-2019, 05:27 PM