2

I am recently new to c# and I need some help.

Essentially I have two scripts, one for spawning objects and one for moving an object along a path. I need a way to combine these two mechanics so that when a new object is instantiated it automatically joins the path and follows it.

The path is made using iTween. ![The objects the scripts are attached to] (https://i.stack.imgur.com/QPQn2.png)

I've tried changing the variable m_PlayerObj to the cube prefab and I've tried adding the Path script to the instantiation script but nothing seems to work.

The scripts attached do nkt include these attempts I made as I wanted to make the code very clear.

Spawner script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpawnerScript : MonoBehaviour
{
    public GameObject cubeprefab;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
             Instantiate(cubeprefab, transform.position, Quaternion.identity);

        }
    }
}

Path script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Path : MonoBehaviour
{
    public GameObject m_PlayerObj;
    public Transform[] positionPoint;
    [Range(0, 1)]
    public float value;
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log(iTween.PathLength(positionPoint));
    }
    float tempTime;
    // Update is called once per frame
    void Update()
    {
        if (value < 1)
        {
            value += Time.deltaTime / 10;
        }
        iTween.PutOnPath(m_PlayerObj, positionPoint, value);
    }

    private void OnDrawGizmos()
    {
    iTween.DrawPath(positionPoint,Color.green);
    }
}

As stated above, any help would be greatly appreciated as I am really stuck on this conceot and since I am new to Unity I really can’t see a way around it // how to fix it.

Thrillasel
  • 33
  • 6

1 Answers1

0

Instead of only storing the player object in the Path script, store a collection of objects. That way, the path can keep track of more than one object.

    //public GameObject m_PlayerObj;    // Get rid of this
    public List<GameObject> followers;  // Add this

Then, in your Update loop, you can loop through all of them.

    void Update()
    {
        for (var i = 0; i < followers.Length; ++i)
        {
            if (value < 1)
            {
                value += Time.deltaTime / 10;
            }
            iTween.PutOnPath(m_PlayerObj, positionPoint, value);
        }
    }

Of course, now, you need to make sure you pass your cube instance to the Path GameObject when you spawn it, so the path knows about the cube follower. That means your spawner also needs to know about the path.

public class SpawnerScript : MonoBehaviour
{
    public GameObject cubeprefab;
    public Path path;   // Need to populate this in the Editor, or fetch it during Awake()

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            var cubeInst = Instantiate(cubeprefab, transform.position, Quaternion.identity);
            path.followers.Add(cubeInst);
        }
    }
}

Now a new problem is going to be that each object is going to be at the same position on the path, because the path only stores one value - a better term might be progress. So if they're all the same, like the cube, you won't be able to tell because they'd overlap.

So you have to decide what you want to do instead. Evenly space them? You could do that with some math. Or have them all start from the beginning and keep track of their progress separately? Then you'd need to store progress for each of them. A better place to do that is probably on the cube object, which means you need to add a new script to your cube prefab:

public class PathFollower : MonoBehaviour
{
    [Range(0, 1)]
    public float pathProgress;
}

And, you need to start referring to the prefab by this script, instead of just GameObject:

public class SpawnerScript : MonoBehaviour
{
    public PathFollower pathFollower;
    public Path path;   // Need to populate this in the Editor, or fetch it during Awake()

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            var followerInst = Instantiate(pathFollower, transform.position, Quaternion.identity);
            path.followers.Add(followerInst);
        }
    }
}
public class Path : MonoBehaviour
{
    //public GameObject m_PlayerObj;    // Get rid of this
    public List<PathFollower> followers;  // Add this
//...

Finally, you need to make sure to use the individual progress for each path follower, rather than a single progress value like your old Path script did:

        for (var i = 0; i < followers.Count; ++i)
        {
            if (followers[i].pathProgress < 1)
            {
                followers[i].pathProgress += Time.deltaTime / 10;
            }
            iTween.PutOnPath(followers[i].gameObject, positionPoint, followers[i].pathProgress);
        }

Putting it all together (separate files of course, with their own includes!):

public class SpawnerScript : MonoBehaviour
{
    public PathFollower pathFollower;
    public Path path;   // Need to populate this in the Editor, or fetch it during Awake()

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            var followerInst = Instantiate(pathFollower, transform.position, Quaternion.identity);
            path.followers.Add(followerInst);
        }
    }
}

public class Path : MonoBehaviour
{
    //public GameObject m_PlayerObj;    // Get rid of this
    public List<PathFollower> followers;  // Add this
    public Transform[] positionPoint;
    //[Range(0, 1)]
    //public float value;  // Don't need this anymore either

    // Start is called before the first frame update
    void Start()
    {
        Debug.Log(iTween.PathLength(positionPoint));
    }

    // Update is called once per frame
    void Update()
    {
        for (var i = 0; i < followers.Count; ++i)
        {
            if (followers[i].pathProgress < 1)
            {
                followers[i].pathProgress += Time.deltaTime / 10;
            }
            iTween.PutOnPath(followers[i].gameObject, positionPoint, followers[i].pathProgress);
        }
    }

    private void OnDrawGizmos()
    {
        iTween.DrawPath(positionPoint,Color.green);
    }
}

public class PathFollower : MonoBehaviour
{
    [Range(0, 1)]
    public float pathProgress;
}

Joseph
  • 733
  • 1
  • 4
  • 20
  • Please note that I didn't compile or run this in the Editor, so if you get some compile errors hopefully you can spot where I made a mistake. But comment if you need to, and I will make corrections. – Joseph Nov 03 '22 at 04:13
  • Hello, thank you for replying however I have never heard of the function Awake() before, would you mind telling me how I would use it in this script. I tried looking it up online and it looks fairly simple but I can't find a straight answer. – Thrillasel Nov 03 '22 at 11:36
  • I get this error upon pressing the space bar during runtime: ArgumentException: The Object you want to instantiate is null. UnityEngine.Object.Instantiate (UnityEngine.Object original, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation) (at < 86acb61e0d2b4b36bc20af11093be915>:0) – Thrillasel Nov 03 '22 at 11:48
  • Awake is a basic one that you should be aware of, very common: https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html - it's similar to Start in that it runs toward the beginning of an object's lifecycle, but it's more for setting up references than beginning gameplay. As for your error, the stack trace should tell you in which code file and at which line it occurs. Is it the line where you make `followerInst`? That means you probably didn't hook up `pathFollower` in the Editor to point to your cube prefab with the PathFollower script attached. – Joseph Nov 04 '22 at 19:55
  • You're right, it is that line. I'm terribly sorry mate but I just don't understand what you mean. Could you please give me a more step-by-step? These screenshots should help.https://anyimage.io/storage/uploads/de6998dc6c2951f400f76daa68562029, https://anyimage.io/storage/uploads/bae8b7dcbb53c0c314e37edc8a3b479d, https://anyimage.io/storage/uploads/191f388b5fe3dbf11c384a61bdd5ce97, https://anyimage.io/storage/uploads/eab12ef0db9768ccaf86e0bb9324697a, https://anyimage.io/storage/uploads/87011607f05f4a984baf6b538d74e550, https://anyimage.io/storage/uploads/38c4aff573f45aa4b605aa805df6a86c – Thrillasel Nov 07 '22 at 12:22
  • https://gyazo.com/2bfd964282538aaf4043446ddd9836ca https://gyazo.com/f05c846f7b2e7521919d52818c2185cc https://gyazo.com/75c227c2eb5115a7efd558d84ee165c3 https://gyazo.com/55fc38f33d4d1e3d87374f2dabcdf3b3 https://gyazo.com/7b38acff3cef74741c152e24bfc4601a https://gyazo.com/dbb0555056aca5cf47c113575b0937d9 https://gyazo.com/d6dae4087c0f8df85432fe3496eda7db – Thrillasel Nov 11 '22 at 15:58