- Home /
Im misunderstanding arrays.
basic question:
How can I use arrays, to keep gameobjects, and then another array for the rigidbody.velocity of those gameobjects, and then use that second array to 'restore' the rigidbody velocity after returning from pause(doing rigidbody.sleep() then wakeup() )?
UPDATE:
ok here is where im at now.
Here is my new code:
void Update() {
guiText.text = ("testbool: ") + GameLogicScript.TestBool; // well time for debugging...
// find player
player = GameObject.FindGameObjectWithTag("Player");
asteroids = GameObject.FindGameObjectsWithTag("Asteroid");
savedAsteroidVelocity = new Vector3[asteroids.Length];
// save player velocity and position if were pausing
if(GameLogicScript.GamePaused)
{
// avoid nullref by checking that player is not dead or something...
if(player != null)
{
// save player if we havent yet
if(!saved)
{
savedPlayerVelocity = player.rigidbody.velocity;
saved = true;
loaded = false;
player.rigidbody.Sleep(); // sleep my precious...
}
// Save asteroids if we havent yet
if(!asteroidSaved)
{
for(int i = 0; i < asteroids.Length; i++)
{
asteroidSaved = true;
savedAsteroidVelocity[i] = asteroids[i].rigidbody.velocity;
asteroidLoaded = false;
asteroids[i].rigidbody.Sleep();
WrappingEnabled = false;
GameLogicScript.SwitchCamPause();
}
}
}
}
// if game not paused anymore load velocity's and position's
if(!GameLogicScript.GamePaused)
{
// dont worry about player if were not out of wave 0
if(GameLogicScript.wave > 0)
{
if(player != null)
{
if(!loaded)
{
player.rigidbody.WakeUp();
player.rigidbody.velocity = savedPlayerVelocity;
//player.transform.position = savedPlayerPos;
saved = false;
loaded = true;
}
}
if(!asteroidLoaded)
{
for(int i = 0; i < asteroids.Length; i++)
{
asteroidLoaded = true;
asteroids[i].rigidbody.WakeUp();
asteroids[i].rigidbody.velocity = Vector3.left; //savedAsteroidVelocity[i];
// savedAsteroidPosition[i] = asteroid.rigidbody.position;
asteroidSaved = false;
}
}
}
WrappingEnabled = true;
}
}
Now what is going wrong this time, is the "asteroids" aka "enemyObjects" before... they are getting ALL the same velocity on resume...they dont take back the unique velocity they had before (random directions) and instead all float off in the exact same direction...
you know, reading this now that I posted it, seems like rechecking saved asteroid velocity every frame...does that reset the like...yaknow...velocity??? hmm
I have made serious progress thanks entirely to hijinxbassist! thanks a ton! Hopefully you can see some flaws in what im doing...
PS the asteroids array is gameobjects, and the savedasteroidvelocity array is vector3's
@$$anonymous$$DReptile
The for loop should look like this
for(var i:int=0;i<enemyObjects.Length;i++)
It may be possible that you capitalized the i in int
Also, you should be getting each of the objects, not just the one the script is on
savedVelocity[i] = go.rigidbody.velocity;
should be
savedVelocity[i] = enemyObjects[i].rigidbody.velocity;
same with the other arrays you have
ill try that right now. Since im using C# this is how I changed it up:
for(int i = 0; i < enemyObjects.Length; i++)
and now that seems correct, next problem is the saving and restoring of the velocity on those rigidbodies...which is what im going for with the "iteration" through the objects, is to both get the velocity before I set rigidbody.sleep() up, and then after using rigidbody.wakeup(), I want to apply that velocity back onto the rigidbodies when returning from pause.
PS I sure wish unity had like, rigidbody.pause() yaknow, that would make my life super easier right... anyway what I tested with, is a vector3 array, for velocity, or "savedVelocity" that I take before sleeping, then I want to go through and re-apply the saved velocity back... I hope this is making sense :)
oh right the savedVelocity[i] = enemyObjects[i] part....just what I needed! im gonna try and get this going now, I think you might have answered my question. I had been thinking just using go and findinggameobjectswithtag() would work, now it all makes sense though!
im guessing that it would be very costly to have rigidbody pause.. but maybe not, this might be something to bring to their attention if it isnt to costly.
I think you have the right idea tho, im not sure what "go" is in your script. If all of the enemies are in the enemyObjects array, use the method i suggested, it should work as you expect it to.
well go was set earlier on, before I was thinking of a different way to handle it using gameobjectfind, and a single go - it didnt work, and somehow it got mixed into the array in my $$anonymous$$d haha, thats fixed in updated answer
Yeah, it happens to the best of us at some time or another. You should be set, ill check back in a little bit to see if your prob is solved.
Answer by hijinxbassist · May 17, 2012 at 06:04 AM
Ok, so here is what the code will resemble (sry, i type unity-javascript)
public var enemyObjects:Rigidbody[];
public var savedAsteroidVelocity:Vector3[];
public var timeScale:float;
public var paused:boolean;
function Start()
{
enemyObjects=GameObject.FindGameObjectsWithTag("Asteroid")as Rigidbody[];
savedAsteroidVelocity=new Vector3[enemyObjects.Length];
}
function Update()
{
if(Input.GetButtonUp("p"))
{
if(paused)Time.timeScale=timeScale;
else
{
timeScale=Time.timeScale;
Time.timeScale=0;
}
}
if(Time.timeScale==0)
{
if(!paused)
{
paused=true;
for(var i:int=0;i<enemyObjects.Length;i++)
{
savedAsteroidVelocity[i] = enemyObjects[i].velocity;
}
}
}
else if(paused)
{
paused=false;
for(var i:int=0;i<enemyObjects.Length;i++)
{
enemyObjects[i].velocity=savedAsteroidVelocity[i];
}
}
}
This will pause the game when the button "p" is released. If the game is already paused, it will reset the time scale. This code relies on
1) Game is paused using Time.timeScale
2) No new asteroids are added while playing (After Start() is called)
@hijinxbassist Cool I'll check this out, thanks for all the help so far!
Update: okay everything is almost sort of working...haha
I have changed my script to resemble yours more, but im doing things probably wrong, because I dont rely on timescale to control my pause, and rather just the rigidbody.sleep() and wakeup() stuff, being that all the moving stuff is rigidbodies...
and what happens now, which is darn near what im going for...is all the rigidbodies DO stop moving, and then, when "resu$$anonymous$$g" the game, the rigidbodies actually ALL take a single direction of motion (velocity), they dont get their 'unique' motion back...
here let me update the first post with whats happening...
@$$anonymous$$DReptile Oh wow, i didnt think of that but it makes complete sense. You need to get their movement direction as well... Lemme think about it for a few, hopefully i can think of a reasonable solution.
@$$anonymous$$DReptile Ok, i think this may be what you need. Ins$$anonymous$$d of getting the velocity of the rigidbody, you can get the http://unity3d.com/support/documentation/ScriptReference/Rigidbody-angularVelocity.html>Angular velocity of the RB. You can literally just change rigidbody.velocity to rigidbody.angularVelocity
I thought that maybe because EVERY update im re-assigning the arrays it could be a problem...like this:
asteroids = GameObject.FindGameObjectsWithTag("Asteroid");
savedAsteroidVelocity = new Vector3[asteroids.Length];
$$anonymous$$ore info:
tried changing the velocity to angularvelocity, and noticed they were all moving one direction....left...as in Vector3.left haha, I forgot to change that out when debugging, anyway when I set to to velocity, and tried just velocity, I put debug code to show what the saved bit was, always 0,0,0 with angularvelocity, tried velocity again...that way shows the saved velocity just after setting it, (with 5 asteroids on screen) all showing unique...apparently correct values...I will keep testing
using this "load" code...this is all putting out 0,0,0 as the "savedAsteroidVelocity[i]"...hmm...here is the code:
// if game not paused anymore load velocity's
if(!GameLogicScript.GamePaused)
{
// dont worry about player if were not out of wave 0
if(GameLogicScript.wave > 0)
{
if(player != null)
{
if(!loaded)
{
player.rigidbody.WakeUp();
player.rigidbody.velocity = savedPlayerVelocity;
//player.transform.position = savedPlayerPos; nvm this...
saved = false;
loaded = true;
}
}
if(!asteroidLoaded)
{
for(int i = 0; i < asteroids.Length; i++)
{
asteroidLoaded = true;
asteroids[i].rigidbody.WakeUp();
asteroids[i].rigidbody.velocity = savedAsteroidVelocity[i];
Debug.Log("lv: " + savedAsteroidVelocity[i]);
// savedAsteroidPosition[i] = asteroid.rigidbody.position;
asteroidSaved = false;
}
}
}
//WrappingEnabled = true; ignore this
}
}
}
Crazy question... does the logic on "i" mean, it starts with savedAsteroidVelocity[0] or [1]? wouldnt that be a problem if it did?
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx New update:
Awwww I figured it out...worked flawlessly...I was doing the part where it finds asteroids, and then the next line, was indeed resetting the whole deal every frame, even like a frame or two after saving... casuing it to stay zero for velocity...
this part:
asteroids = GameObject.FindGameObjectsWithTag("Asteroid"); savedAsteroidVelocity = new Vector3[asteroids.Length];
had to use a bool like, foundStuff to make sure it only looked once...once per pause anyway :) works like a charm! ill mark your answer as correct, with some adjustments on my own logic anyway
Thanks a ton, you were extremely helpful!
excellent, glad we got it resolved. Glad to be of help, im sure our paths will cross again one way or another. For now, Cheers : )