I created a object in unity
GameObject monsterclone =
(GameObject)Instantiate(monsterPrefab, floorPosition, Quaternion.identity);
This object should move in a wave style from a limit1 to limit2.
Then move back from limit2 to limit1.
Y position as well x position have to change in a specific way.
Vector3 nPos = mfloorPos + new Vector3(2f, 0f, 0f);
Vector3 oPos = mfloorPos + new Vector3(-2f, 0f, 0f);
How can I do it?
I can't exactly write the code without knowing more specific but i think this question is already asked any this link will help you out MOVE OBJECT as wave
EDIT:
I think the flat up and float down functionality will work for you for moving one point to another
example:
var floatup;
function Start(){
floatup = false;
}
function Update(){
if(floatup)
floatingup();
else if(!floatup)
floatingdown();
}
function floatingup(){
transform.position.y += 0.3 * Time.deltaTime;
yield WaitForSeconds(1);
floatup = false;
}
function floatingdown(){
transform.position.y -= 0.3 * Time.deltaTime;;
yield WaitForSeconds(1);
floatup = true;
}
example taken from
float amplitudeX = -25.0f;
float amplitudeY = 5.0f;
float omegaX = 0.5f;
float omegaY = 4.0f;
float index;
void Update () {
index += Time.deltaTime;
float x = amplitudeX*Mathf.Cos (omegaX*index);
float y = Mathf.Abs (amplitudeY*Mathf.Sin (omegaY*index));
if(transform.position.x > 24){
transform.eulerAngles = new Vector3(270, -90, 0);
}
if(transform.position.x < -24){
transform.eulerAngles = new Vector3(270, 90, 0);
}
transform.localPosition= new Vector3(x,y,20);
}
If this is a consitant wave and not dependant on speed I would use an animation to create a literal wave curve of the Position.Y value (much in the same principle as Ravindra Shekhawat has explained.) you can find out more about animation here.
Here is some code (untested) that you could go off. It is in c# so I hope it proves no issue with putting in to JavaScript.
bool monsterMoving = false;
void Update(){
//check monster moving to start updating position
if(monsterMoving == true){
//moving animation controls up and down "wave" movement
animation.CrossFade('moving');
//Lerp changes position
Transform.Lerp(transform.Position, oPos, Time.deltaTime);
if (transform.Position == oPos) {
//We are at destination, stop movement
monsterMoving = false;
}
} else {
// if monster stopped moving, return to idle animation (staying still)
animation.CrossFade('idle');
}
}
// function to send a new position to the monster object
void MoveTo(Vector3 newPos){
oPos = newPos;
monsterMoving = true;
}
Related
Rotating an object around the same pivot gives different results
So I'm trying to make a door that opens when clicked on, and I have a door that works good as is, but for some reason when I try to make it work for another door using RotateAround, it moves along the Z axis when closing. The code is identical to the other door that works and works when opening this door, so I have no clue as to why it's having trouble closing for this one. The code I'm using to rotate them is as follows
IEnumerator CloseDoor()
{
float timer = 1f;
float speed = 30f;
Vector3 pivot = new Vector3(door.transform.position.x, door.transform.position.y,
door.transform.position.z + 1);
while (timer > 0)
{
door.transform.RotateAround(pivot, Vector3.down, speed * Time.deltaTime);
yield return new WaitForSeconds(0.001f);
timer -= Time.deltaTime;
}
}
IEnumerator OpenDoor()
{
float timer = 1f;
float speed = 30f;
Vector3 pivot = new Vector3(door.transform.position.x, door.transform.position.y,
door.transform.position.z + 1);
while (timer > 0)
{
door.transform.RotateAround(pivot, Vector3.up, speed * Time.deltaTime);
yield return new WaitForSeconds(0.001f);
timer -= Time.deltaTime;
}
}
I'll start with some overall advices, regarding your code.
Don't use Time.deltaTime with new WaitForSeconds(...). Time.deltaTime is an amout of time, that passed between Update() calls. But your logic is not inside Update(). You use own time inervals with new WaitForSecons(...), but if the specified amout of time is less then Time.deltaTime, then it will be executed every Time.deltaTime after all Update() calls. It works good for you only because your time interval 0.001f is low enough to be executed every Update(). When your argument in new WaitForSeconts(...) becomes more them Time.deltaTime, the rotation speed of the door becomes too low to door be opened completely. To made your code more clear and safe, return null with yield instruction. In this case, you can be shure, that coroutine will be executed every Update(). More info here.
Your code works with transform positioning, and probably you have physics in your game. All changes with physical object supposed to be done in the FixedUpdate(). In your case your cant return new WaitForFixedUpdate() in yield instruction and use Time.fixedDeltaTime with it.
So speaking about main question. In your code, you are doing pretty unclear and unsafe thing, like hardcoding pivot with global position offset here:
Vector3 pivot = new Vector3(door.transform.position.x, door.transform.position.y,
door.transform.position.z + 1);
Probably, not all doors will have same rotation, and for some of them offset, just with z coordinate will be wrong. Also it becomes wrong after door opening, because the position and rotation of the door changed when you rotating it around some point, that is not the center of the door. So you should base on local transform point, like this:
public class Door : MonoBehaviour
{
private bool _doorOpened = false;
private bool _doorOpening = false;
[SerializeField] // to see in the inspector.
private Vector3 _localDoorRotatePoint = new Vector3(0.5f, 0f, 0f);
// Update is called once per frame
void Update()
{
if (!_doorOpening && Input.GetKeyDown(KeyCode.E))
{
if (!_doorOpened)
{
StartCoroutine(OpenDoor());
}
else
{
StartCoroutine(CloseDoor());
}
}
}
IEnumerator CloseDoor()
{
_doorOpening = true;
var timer = 1f;
var speed = 30f;
// in my case _localDoorRotate point is (0.5f, 0f, 0). In your case it will be like (0, 0, 1f) or something like this.
// remember, that this point is in local transform coordinates, and in scales with this transform scale vector.
var pivot = transform.TransformPoint(_localDoorRotatePoint);
while (timer > 0)
{
transform.RotateAround(pivot, Vector3.down, speed * Time.fixedDeltaTime);
yield return new WaitForFixedUpdate();
timer -= Time.fixedDeltaTime;
}
_doorOpening = false;
_doorOpened = false;
}
IEnumerator OpenDoor()
{
_doorOpening = true;
var timer = 1f;
var speed = 30f;
// in my case _localDoorRotate point is (0.5f, 0f, 0f). In your case it will be like (0f, 0f, 1f) or something like this.
// remember, that this point is in local transform coordinates, and in scales with this transform scale vector.
var pivot = transform.TransformPoint(_localDoorRotatePoint);
while (timer > 0)
{
transform.RotateAround(pivot, Vector3.up, speed * Time.fixedDeltaTime);
yield return new WaitForFixedUpdate();
timer -= Time.fixedDeltaTime;
}
_doorOpening = false;
_doorOpened = true;
}
}
Helpfull links, that can help you with understanding this code:
Transform.TransformPoint
Transform.up
I'm trying to create a bird moving across screen along x axis.
bird.transform.position = Vector3.Lerp (pos1, pos2, (Mathf.Abs(speed * Time.time) + 1.0f) / 2.0f);
Using this in Update() the bird flies only once. I want that after it flies to the right, it should wait 2-3 seconds and then fly back with a different sprite.
transform.translate doesn't work like this. Any help will be appreciated.
you would need to put in another LERP for going the other direction and have a variable for which way the bird is flying so roughly:
bool goleft;
if(goleft)
{
if(transform.position != pos2)
{
transform.position = Vector3.Lerp (pos1, pos2, (Mathf.Abs(speed * Time.time) + 1.0f) / 2.0f);
}
else
{
goleft = false;
//change the direction the bird is facing here
}
}
else
{
if(transform.position != pos1)
{
transform.position = Vector3.Lerp (pos2, pos1, (Mathf.Abs(speed * Time.time) + 1.0f) / 2.0f);
}
else
{
goleft = true;
//change the direction the bird is facing here
}
}
Hope that helps
Not tested but i would start here:
Vector3[] posts;
int current = 0;
float speed = 5.0f;
float threshold = Single.Epsilon;
float delay = 2.0f;
public void Update() {
if(!waiting && posts.Length > 0)
{
if(!Mathf.Approximately((posts[current].position - transform.position).sqrMagnitude, threshold)
{
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, posts[current].position, step);
}
else StartCoroutine("Next");
}
}
IEnumerator Next() {
waiting = true;
yield return new WaitForSeconds(delay);
current = (current + 1) % posts.Length;
waiting = false;
}
This will also allow you to have as many posts as you want to have, and all your movement dynamics can be handled in Next(), whereas, if you want him to go from post 0...1...2...3...0...1.. or 0...1...2...3...2...1...
If you want the latter you just change current = (current + 1) % posts.Length; to Mathf.PingPong(current + 1, posts.Length);
I'd go a bit like this:
float flipCooldown
float defaultFlipCooldown = 2.0f;
bool isGoingRight;
Vector2 pos1;
Vector2 pos2;
void Start() {
flipCooldown = defaultFlipCooldown;
isGoingRight = true;
pos1 = new Vector2(0, 0);
pos2 = new Vector2(5, 0); // whatever floats your boat
}
void Update()
{
Vector2 initialPosition = null;
Vector2 finalPosition = null;
if (flipCooldown <= 0) {
isGoingRight = !isGoingRight
flipCooldown = defaultFlipCooldown;
ChangeSprite();
}
if (isGoingRight) {
initialPos = pos1;
finalPos = pos2;
} else {
initialPos = pos2;
finalPos = pos1;
}
bird.transform.position = Vector3.Lerp (initialPos, finalPos, (Mathf.Abs(speed * Time.time) + 1.0f) / 2.0f);
flipCooldown -= Time.deltaTime;
}
What you want to get is that the Time.deltaTime is decreasing the cooldown for the bird to turn. You can easily change the cooldown in the defaultFlipCooldown variable. When it's done going one way, it'll just flip the position and the Lerp function will do the rest of the work. The ChangeSprite function will be just a GetComponent<SpriteRenderer>().sprite change.
If you don't want fix positions, you can calculate how much it'll fly, define the final position and just change the pos1 and pos2.
It's also important to note that WaitForSeconds will just work with Coroutines that is a concept for working with threads, never in a method like Update. You can learn more about Coroutines in Unity's manual: http://docs.unity3d.com/Manual/Coroutines.html
I'm working on a game right now (first 3D styled game), and I have a problem with my character colliding. I have a Player object, which has another object(s) as the real moveable characters (now I have only one). I have rigidbody and box collider too attached to my character. I have made a level (with hand-placed platforms), and I would like avoid my character of falling of the platforms, while the user control it. I have tried to place a cube on the side of the platform(s), with box collider attached to it, but the character not detect the colliding for some reasons. I would like my character to be stopped by the collider "cube", but it doesn't happen.
I use this script to move my object (attached to my character Player object) :
public class Bounce : MonoBehaviour {
float lerpTime;
float currentLerpTime;
float perc = 1;
Vector3 startPos;
Vector3 endPos;
bool firstInput;
public bool justJump;
public GameObject player;
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("up") || Input.GetButtonDown("down") || Input.GetButtonDown("left") || Input.GetButtonDown("right")) {
if (perc == 1) {
lerpTime = 1;
currentLerpTime = 0;
firstInput = true;
justJump = true;
}
}
startPos = gameObject.transform.position;
if (Input.GetButtonDown("up") && gameObject.transform.position == endPos) {
endPos = transform.position + player.transform.rotation * (new Vector3(0, 0, 1f));
}
if (Input.GetButtonDown("down") && gameObject.transform.position == endPos) {
endPos = transform.position + player.transform.rotation * (new Vector3(0, 0, -1f));
}
if (firstInput == true) {
currentLerpTime += Time.deltaTime * 5;
perc = currentLerpTime / lerpTime;
gameObject.transform.position = Vector3.Lerp(startPos, endPos, perc);
if (perc > 0.8f) {
perc = 1;
}
if (Mathf.Round(perc) == 1) {
justJump = false;
}
}
}
void OnCollisionEnter(Collision collision) {
Debug.Log("!!!!!!!");
}
}
And I use this script on the character itself: (to rotate and animate it)
Code (csharp):
public class AnimationController : MonoBehaviour {
Animator anim;
public GameObject thePlayer;
// Use this for initialization
void Start () {
anim = gameObject.GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
Bounce bounceScript = thePlayer.GetComponent<Bounce>();
if (bounceScript.justJump == true) {
anim.SetBool("Jump", true);
}
else {
anim.SetBool("Jump", false);
}
if (Input.GetButtonDown("right")) {
//transform.rotation *= Quaternion.Euler(0,30,0);
transform.RotateAround(transform.position, Vector3.up, 90);
}
if (Input.GetButtonDown("left")) {
transform.Rotate (0, -90, 0, 0);
}
}
}
It's only colliding when the cube not isKinematic, but it doesn't stop my player from getting through the cube for some reason.
I have read some sites about problems like this, but nothing helped yet.
It would be great if you can give me any code improvements :)
EDIT1:
Sorry, for answering so late, I couldn't do anything with my game in the last few days. Today I have tried to do something with raycasts, you can see my code, for my first try just in the update method:
void Update () {
if (Input.GetButtonDown("up") || Input.GetButtonDown("down") || Input.GetButtonDown("left") || Input.GetButtonDown("right")) {
if (perc == 1) {
lerpTime = 1;
currentLerpTime = 0;
firstInput = true;
justJump = true;
}
}
startPos = gameObject.transform.position;
/* if (Input.GetButtonDown("right") && gameObject.transform.position == endPos) {
//endPos = new Vector3(transform.position.x + 0.5f, transform.position.y, transform.position.z);
}
if (Input.GetButtonDown("left") && gameObject.transform.position == endPos) {
endPos = new Vector3(transform.position.x - 0.5f, transform.position.y, transform.position.z);
}*/
Vector3 fwd = player.transform.TransformDirection(Vector3.forward);
RaycastHit objectHit;
if (Physics.Raycast(player.transform.position, fwd, out objectHit, 2)) {
if (objectHit.collider.tag == "Wall") {
Debug.Log("WALL RAYCAST HIT!");
}
}
if (Input.GetButtonDown("up") && gameObject.transform.position == endPos) {
endPos = transform.position + player.transform.rotation * (new Vector3(0, 0, 1f));
}
if (Input.GetButtonDown("down") && gameObject.transform.position == endPos) {
//endPos = transform.position + player.transform.rotation * (new Vector3(0, 0, -1f));
}
if (firstInput == true) {
currentLerpTime += Time.deltaTime * 5;
perc = currentLerpTime / lerpTime;
gameObject.transform.position = Vector3.Lerp(startPos, endPos, perc);
if (perc > 0.8f) {
perc = 1;
}
if (Mathf.Round(perc) == 1) {
justJump = false;
}
}
}
With this I can get the Debug Log WALL RAYCAST HIT 2-3 times at a time, but only once. As I move the character it won't appear again, for some reason (I think it should because the update method is called in every frame).
Although when I place it in the Input.GetButtonDown("up") method, it won't log anything:
if (Input.GetButtonDown("up") && gameObject.transform.position == endPos) {
fwd = player.transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(player.transform.position, fwd, out objectHit, 2)) {
if (objectHit.collider.tag == "Wall") {
Debug.Log("WALL RAYCAST HIT!");
}
}
endPos = transform.position + player.transform.rotation * (new Vector3(0, 0, 1f));
}
When you update the transform.position you actually "teleport" yout object to the new position. Even when you do this smoothly, using something like the Lerp function, as you do on your move script, Unity understands that you are teleporting your object to a new coordinate.
This is not wrong, All games work like that. Functions like Lerp just create the ilusion of movement, so the player fell like the character actually moved from one point to another.
What is happening is that your script keeps telling the character to move to a new position, despite any objects on its path. The collision happens, but your Update function still places the character on ints new position.
I can think of two possible ways for you to solve this:
Create an OnCollisionEnter() function for your Move script that somehow stops your movement. By creating a flag like you did with the firstInput you could achieve this.
Instead of updating your transform.position you could use a rigidbody to handle the movement and collisions for your. This way, everytime you need to move your character you will need to add some velocity to the character rigidbody, instead of directly updating the transform.position.
Since your character doesn't move in a constant way, but in a "one step at a time" way, I think the first solution is a better suitted for you.
The code will be something like this
void OnCollisionenter(Collision collision)
{
collided = true;
}
and the end of your Move script should be updated to
if(!collided)
{
if (firstInput == true) {
currentLerpTime += Time.deltaTime * 5;
perc = currentLerpTime / lerpTime;
transform.position = Vector3.Lerp(startPos, endPos, perc);
if (perc > 0.8f) {
perc = 1;
}
if (Mathf.Round(perc) == 1) {
justJump = false;
}
}
}
else
{
// Remember to reset this when you stop your character
endPos = transform.position;
collided = false;
}
This time I couldn't test the code before writting it here, so you may need to do some changes before it works.
ps: I don't think you need your firstInput variable. Once it is set to true, you never set it to false again. Also, the Input.GetButtonDown() function will only return true on the first frame a button is pressed wich is what I guess you intended when you created firstInput.
ps2: My solution added a collided boolean attribute to your class, so don't forget to add a line private bool collided; with your other class attributes. Also, read that chapter about the state machine pattern I recommended you on your other question. Creating this kind of control attribute suach as the collided boolean is not a good practice and if you had implemented a state machine this could be avoided.
Hey I had a similar problem i was using an animated model from Mixamo.com and I notices that for some strange reason the character didn't collide with boundaries despite having collider, for some reason it didn't work until i added a CharacterController to my model instead of a collider just search for the CharacterController and add it as you would add any script or rigid body to your game object.
Hope it Works XD Greetings
As you can see in the topic - I have a camera problem. I use a script (you can see below) and I have something like this - http://rapidgamesstudio.com/games/diggermachines/
What I want to achieve is a smooth following camera to player.
I've tried everything. I have about 50-60 fps and still this bug occures.
This is my camera code:
void Update() {
if(!player)
return;
//if(!isDiggableCamera) {
Vector3 point = Camera.main.WorldToViewportPoint(player.transform.position);
Vector3 delta = player.transform.position - Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, point.z)); //(new Vector3(0.5, 0.5, point.z));
Vector3 destination = transform.position + delta;
destination.z = transform.position.z;
transform.position = Vector3.SmoothDamp(transform.position, destination, ref velocity, dampTime);
//Vector3 destination = new Vector3(player.transform.position.x, player.transform.position.y, transform.position.z);
//transform.position = Vector3.SmoothDamp(transform.position, destination, ref velocity, dampTime);
//} else {
// startDigging(0, 0, 0);
//}
leftSite.position = new Vector3(leftSite.position.x, player.position.y, leftSite.position.z);
rightSite.position = new Vector3(rightSite.position.x,
player.position.y, rightSite.position.z);
}
I tried execute this code in Update(), FixedUpdate(), LateUpdate() even with all three - and still is the same problem.
Below code for updating player position:
//move player
float changableSpeedX = 5000.0f;
float changableSpeedY = 6000.0f;
Vector2 speed = new Vector2(x * Time.deltaTime * changableSpeedX,
y * Time.deltaTime * changableSpeedY);
//if(playerRigidbody.velocity.y + speed.y >= Game.game().activeMaxVelY)
// speed.y = Game.game().activeMaxVelY - playerRigidbody.velocity.y;
playerRigidbody.AddForce(speed);
//AddForce(speed);
//and checking max speed
protected void checkSpeed()
{
if(playerRigidbody.velocity.x > Game.game().activeMaxVelX)
playerRigidbody.velocity = new Vector2(Game.game().activeMaxVelX, playerRigidbody.velocity.y);
if(playerRigidbody.velocity.x < -Game.game().activeMaxVelX)
playerRigidbody.velocity = new Vector2(-Game.game().activeMaxVelX, playerRigidbody.velocity.y);
if(playerRigidbody.velocity.y > Game.game().activeMaxVelY)
playerRigidbody.velocity = new Vector2(playerRigidbody.velocity.x, Game.game().activeMaxVelY);
if(playerRigidbody.velocity.y < maxSpeedYGravity)
playerRigidbody.velocity = new Vector2(playerRigidbody.velocity.x, maxSpeedYGravity);
}
Could anyone help me?
If you need more code please let me know which part (because I don't want to add too much unnecessary code)
Might i suggest a lerp sir , in the update function use this
maincamera.transform.position = new vector3(maincamera.transform.position,player.transform.poistion,speed*Time.deltaTime);
Try This One !!!
private float xMax;
[SerializeField]
private float yMax;
[SerializeField]
private float xMin;
[SerializeField]
private float yMin;
private Transform target;
// Use this for initialization
void Start () {
target = GameObject.Find("Player").transform;
}
// Update is called once per frame
void LateUpdate () {
transform.position = new Vector3(Mathf.Clamp(target.position.x, xMin, xMax), Mathf.Clamp(target.position.y, yMin, yMax),transform.position.z);
}
}
(Using unity3d 4.3 2d, it uses box2d like physics).
I have problems with predicting trajectory
I'm using:
Vector2 startPos;
float power = 10.0f;
float interval = 1/30.0f;
GameObject[] ind;
void Start (){
transform.rigidbody2D.isKinematic = true;
ind = new GameObject[dots];
for(int i = 0; i<dots; i++){
GameObject dot = (GameObject)Instantiate(Dot);
dot.renderer.enabled = false;
ind[i] = dot;
}
}
void Update (){
if(shot) return;
if(Input.GetAxis("Fire1") == 1){
if(!aiming){
aiming = true;
startPos = Input.mousePosition;
ShowPath();
}
else{
CalculatePath();
}
}
else if(aiming && !shot){
transform.rigidbody2D.isKinematic = false;
transform.rigidbody2D.AddForce(GetForce(Input.mous ePosition));
shot = true;
aiming = false;
HidePath();
}
}
Vector2 GetForce(Vector3 mouse){
return (new Vector2(startPos.x, startPos.y)- new Vector2(mouse.x, mouse.y))*power;
}
void CalculatePath(){
ind[0].transform.position = transform.position; //set frist dot to ball position
Vector2 vel = GetForce(Input.mousePosition); //get velocity
for(int i = 1; i < dots; i++){
ind[i].renderer.enabled = true; //make them visible
Vector3 point = PathPoint(transform.position, vel, i); //get position of the dot
point.z = -1.0f;
ind[i].transform.position = point;
}
}
Vector2 PathPoint(Vector2 startP, Vector2 startVel, int n){
//Standard formula for trajectory prediction
float t = interval;
Vector2 stepVelocity = t*startVel;
Vector2 StepGravity = t*t*Physics.gravity;
Vector2 whattoreturn = ((startP + (n * stepVelocity)+(n*n+n)*StepGravity) * 0.5f);
return whattoreturn;
}
Using this, I get wrong trajectory.
1. It's like gravity doesn't drag trajectory down at all, and yes i know that gravity is weak because:
t*t*Physics.gravity = 0.03^2 * vector2(0, -9.8) = vector2(0, -0.00882)
But that is the formula :S
2. Since gravity is low, velocity is too strong.
Here is the video:
http://tinypic.com/player.php?v=1z50w3m&s=5
Trajectory formula form:
http://www.iforce2d.net/b2dtut/projected-trajectory
What should I do?
I found that if I set
StepGravity to something stronger like (0, -0.1)
and devide startVel by 8
I get nearly right trajectory, but i don't want that, I need true trajectory path.
Users from answer.unity3d.com said I should ask here, because here is a bigger group of mathematical coders.
And I searched a lot about this problem (that how I found that formula).
you're only calculating the effect of gravity over 1/30th of a second for each step - you need to do it cumulatively. Step 1 should end with a velocity of 0.09G, Step 2 with .18G, step3 with .27G etc.
Here's a very simple example that draws the ballistic trajectory based on start velocity and a supplied time:
using UnityEngine;
using System.Collections;
public class grav : MonoBehaviour {
public Vector3 StartVelocity;
public float PredictionTime;
private Vector3 G;
void OnDrawGizmos()
{
if (G == Vector3.zero)
{
// a hacky way of making sure this gets initialized in editor too...
// this assumes 60 samples / sec
G = new Vector3(0,-9.8f,0) / 360f;
}
Vector3 momentum = StartVelocity;
Vector3 pos = gameObject.transform.position;
Vector3 last = gameObject.transform.position;
for (int i = 0; i < (int) (PredictionTime * 60); i++)
{
momentum += G;
pos += momentum;
Gizmos.DrawLine(last, pos);
last = pos;
}
}
}
In you version you'd want draw your dots where I'm drawing the Gizmo, but it's the same idea unless I'm misunderstanding your problem.