Resetting objects position while in motion and part of a pool.

Hi,

I’m having a bit of trouble and the ways i’ve thought to fix it have come up unsuccessful so far, so I’m asking here.

I have a script where I’m drawing a bunch of objects to the screen, using the mouse button and position to distribute primitives like a cube of sphere, as to be a paint brush in effect. I’ve moved on to use an object pool to try and clean things up so I’m not creating/destroying lots of objects.

The painting objects to the screen and using an object pool works fine, however it’s not the end goal, I have another script which is essentially an LFO for modulating position of the objects, it’s just a sine wave modulating in the z-axis, so the objects once placed animates back and fourth. However when I turn this script on it breaks the functionality of the object pool and i’m not sure why, I’ve tried temporarily disabling the script while trying to steal it’s position to that of the mouse, but the position modulation somehow manages to override the mouse’s position, I’m wondering whether it’s down to the execution of the instruction or whether it’s the default position part in the wavemove script.

If anyone has any ideas i’m all ears and would be greatly appreciated, here’s the two scripts, one for the object pool (PaintBalls.cs) and one for the Wave move, (Auto-Wave Move)

using UnityEngine;
using System.Collections;

public class PaintBalls : MonoBehaviour
{
    public int numberOfRepeats = 3; //Number of copies of paint
    private Vector3 mousePos;
    private Vector3 oldmousePos;
    private Vector3 worldPos;

    public GameObject poolParent;
    private int currentObj = 0;
    private GameObject[] objects = null;
    public GameObject objectsToInstantiate;
    public int poolSize = 333;

    void Start()
    {
        objects = new GameObject[poolSize]; // make a pool of objects
        for (int i = 0; i < poolSize; i++) 
        {
            objects[i] = Instantiate (objectsToInstantiate) as GameObject; // Instantiate/create all the objects we need
            objects[i].transform.parent = poolParent.transform; // Clean them up in hierarchy by attaching them to parent object 
            objects[i].SetActive (false); // set them all to false
        }
    }

    void Update()
    {
        if ( Input.GetMouseButton(0) )
        {
            oldmousePos = mousePos; //Save mouse position for comparison
            mousePos = Input.mousePosition; //Get new mouse position

            //If mouse postion is 'too close', do not draw
            if(oldmousePos.x == mousePos.x && oldmousePos.y == mousePos.y) {
                return;
            } else {

                //else draw!
                mousePos.z = 14f;
                worldPos = Camera.main.ScreenToWorldPoint(mousePos);

                for( int i = 1; i <= numberOfRepeats; i++)
                { 
                    //print("Drawing point "+i);
                    //Draw the object at the point in the world
                    //GameObject drawnPoint = Instantiate(prefab, worldPos, Camera.main.transform.rotation) as GameObject;
                    if (objects[currentObj].activeInHierarchy == false) // check to see if objects are off
                    {
                        objects[currentObj].SetActive (true); // turn current object on
                        objects[currentObj].GetComponent<AutoWaveMove>().enabled = true;
                        objects[currentObj].transform.position = worldPos; // give it the position
                        objects[currentObj].transform.rotation = Camera.main.transform.rotation; // and rotation
                    }
                    //objects[currentObj].GetComponent<AutoWaveMove>().enabled = true;
                    currentObj++; // move the current object on
                    if(currentObj >= poolSize)currentObj = 0; // loop back round to the first in pool when it gets to pool size limit
                    objects [currentObj].SetActive (false);
                }
            } 
        }
    }
}

And this is the one has to go on the prefab that will be used by the object pool:

using UnityEngine;
using System.Collections;

public class AutoWaveMove : MonoBehaviour

{
    public Transform cube;
    public Vector3 moveSpeed = new Vector3 (0,0,4f);
    private Vector3 lastPos;
    public float waveTime = 3f;
    float time = 0;
    Vector3 default_pos;
    // Use this for initialization
    void Start ()
    {
        default_pos = transform.localPosition;
        //default_pos = new Vector3 (0f,0f,0f);
    }

    // Update is called once per frame
    void Update ()
    {
        //lastPos = transform.position;
        time += Time.deltaTime;
        cube.transform.localPosition = default_pos + moveSpeed * Mathf.Sin (Mathf.PI * 2 * (time / waveTime));
    }
}

On line 16 in the second script it looks like you grab the position on Start. It seems that Start will only be called the first time the object is instantiated so it will always use that position. When re-using the object from the pool you need to set that default_pos variable to the new position.

Ahh ace thank you very much for looking at that, I was edging towards a solution like that, the thing that confuses me about it is passing the information from one script to the other, so would I have to pass a variable out of the paint ball script, say the vector position, and then some how read that variable in the wave move and set that as the default position?

Damn I’m messing this up badly.

So i’m able to read the world position variable from the wave move script, but it keeps on breaking the functionality.

This is what I’ve changed it to, still not ideal, I want to hand the variable from one script to another, so each member of the pool gets a unique position from the mouse, and not change all the objects at once, which is what seems to happen if I read the variable from in the update of the wave move script, just effects everything on screen.

using UnityEngine;
using System.Collections;

public class AutoWaveMove : MonoBehaviour

{
    public Transform cube;
    public Vector3 moveSpeed = new Vector3 (0,0,4f);
    private Vector3 lastPos;
    public float waveTime = 3f;
    float time = 0;
    Vector3 default_pos;
    // Use this for initialization
    void Start ()
    {
        //default_pos = transform.localPosition;
        //default_pos = new Vector3 (0f,0f,0f);
    }

    // Update is called once per frame
    void Update ()
    {
        default_pos = GameObject.Find("Hopper").GetComponent<PaintBalls>().worldPos;
        //lastPos = transform.position;
        time += Time.deltaTime;
        cube.transform.localPosition = default_pos + moveSpeed * Mathf.Sin (Mathf.PI * 2 * (time / waveTime));
    }
}

Awesome I worked it out I think, had to set the variable from the other script!

1 Like