Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by mauriciomb · Jun 25, 2018 at 03:14 PM · instantiateprefablistsmovetowards

Transform List not updating position of prefab.

my code is supposed to spawn prefab objects every couple of seconds. Those spawned prefabs are then to move towards different prefab objects (endPoints) already in the world. those endPoint objects are slowing moving and that is where the problem arises. The spawned prefabs do not update the position of the endPoints, so they end up traveling towards the starting position of the endPoints. The problem might be my poor understanding of lists because I have an enemy prefab that uses the same moveTowards code as the one located on the neutralAIMovement script to follow my player prefab without any issue.

I am using a for loop to iterate through each element in the factionRelationship list while at the same time passing the i value to the index variable listNumber located on the neutralAIMovement script.

One thing I did try is to start my scene with the prefab that will travel towards endPoint already in the world as opposed to instantiating it every couple of seconds. This gave the same result. Any help would be appreciated. Thanks in advance.

 public class TradingAndTradeShips : MonoBehaviour
 {
     public List<float> factionRelationship = new List<float>();
     public NeutralAIMovement tradeShipScript;
     public GameObject tradeShip;
     public float waitToSpawn;
     public int factionNumber;
     private bool continueLoop;
 
     void Start()
     {
         continueLoop = true;
         StartCoroutine(SpawnTradeShip());
     }
     IEnumerator SpawnTradeShip()
     {
         
         while (continueLoop)
         {
             for (int i = 0; i < factionRelationship.Count; i++)
             {
                 if (factionRelationship[i] >= 50f)
                 {
                     tradeShipScript.listNumber = i;
                     GameObject tradeObj = Instantiate(tradeShip, new Vector3(transform.position.x, transform.position.y, tradeShip.transform.position.z), tradeShip.transform.rotation);
                 }
                 yield return new WaitForSeconds(waitToSpawn);
             }
         }
     }
 
 
 
 public class NeutralAIMovement : MonoBehaviour {
     public List<Transform> tradeEndPointList = new List<Transform>();
     public TradingAndTradeShips homeRelationship;
     public int listNumber;
     public float speed, rotationSpeed;
     void Start () {
         
     }
 
     void Update ()
     {
         Debug.Log(tradeEndPointList[listNumber].position);
         transform.position = Vector2.MoveTowards(transform.position, tradeEndPointList[listNumber].position, speed * Time.deltaTime);
 }


Comment
Add comment · Show 6
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Harinezumi · Jun 25, 2018 at 03:48 PM 0
Share

The problem (or one of them) is that you assign i to listNumber of a NeutralAI$$anonymous$$ovement reference that has not been instantiated. You need to get the NeutralAI$$anonymous$$ovement from the tradeShip instance that you call tradeObj like this:

 NeutralAI$$anonymous$$ovement neutralAI$$anonymous$$ovement = tradeObj.GetComponent<NeutralAI$$anonymous$$ovement>();
 if (neutralAI$$anonymous$$ovement != null) { neutralAI$$anonymous$$ovement.listNumber = i; }

However, you also must make sure that tradeEndPointList is initialized and has at least i elements in the prefab reference tradeShip, otherwise you will get an IndexOutOfBoundsException when you are trying to use the position of tradeEndPointList[listNumber].

Do you get any errors in the console? Please share them if you do.

avatar image mauriciomb Harinezumi · Jun 25, 2018 at 03:51 PM 0
Share

No I am not getting any errors.

I set four elements for each of the two lists in the inspector.

avatar image mauriciomb Harinezumi · Jun 25, 2018 at 04:01 PM 0
Share

I tried what you suggested and added your code in the for loop, but the result was the same.

 for (int i = 0; i < factionRelationship.Count; i++)
             {
                 if (factionRelationship[i] >= 50f)
                 {
                     tradeShipScript.listNumber = i;
                     GameObject tradeObj = Instantiate(tradeShip, new Vector3(transform.position.x, transform.position.y, tradeShip.transform.position.z), tradeShip.transform.rotation);
                     NeutralAI$$anonymous$$ovement neutralAI$$anonymous$$ovement = tradeObj.GetComponent<NeutralAI$$anonymous$$ovement>();
                     if (neutralAI$$anonymous$$ovement != null) { neutralAI$$anonymous$$ovement.listNumber = i; }
                 }
                 yield return new WaitForSeconds(waitToSpawn);
             }

avatar image Harinezumi mauriciomb · Jun 26, 2018 at 09:01 AM 0
Share

I would like to help, but I am not sure of how your scene is set up, what objects get instantiated and which are already present in the scene. Could you give a more detailed description, possibly adding some screenshots of the Hierarchy view and Inspector of trade ship prefab?

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by JDelekto · Jun 26, 2018 at 10:00 AM

I think the problem is that the objects whose references are contained in your tradeEndPointList are not having their positions updated.

I would expect that somewhere you would have some code which does something like tradeEndPointList[index].position = someNewPosition; but it is not obvious from the code that you have provided.

If the tradeEndPointList is meant to be a list of prefabs with which to generate endpoints, then consider making a new list of the instantiated endpoint prefabs, but make sure that somewhere you are updating the endpoints.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Harinezumi · Jun 27, 2018 at 03:24 PM

It turned out that the problem was that the NeutralAIMovement component's tradeEndPointList variable was assigned in the prefab, which means they were not the same objects as the ones in the scene. One solution is to group the end point instances under an empty game object, gather them in a script, then get that list from the script and assign it to the NeutralAIMovement when instantiating the tradeShip. In fact TradingAndTradeShips can just get the reference to the script once, and use it whenever instantiating a trade ship.

However, the logic can be greatly cleaned up if we analyse the required functionality. There are 3 main logic elements: instantiating trade ships, keeping track of trade end points, and moving towards your trade end point. Each can be separated from each other, and using references of the correct type, the code will be faster, simpler, and cleaner.

 public class TradeEndPoints : MonoBehaviour {
 
     // you can set up the end points manually on an instance of the script in the scene, or with code - see Awake() method below
     [SerializeField] private List<Transform> tradeEndPoints = new List<Transform>();
     public Transform GetTradeEndPoint (int index) { return i < tradeEndPoints.Count ? tradeEndPoints[i] : null; }
 
     private void Awake () {
         // you can automatically set it up if there is nothing assigned from Editor with this condition
         if (tradeEndPoints.Count == 0) {
             Transform[] childTransforms = GetComponentsInChildren<Transform>();
             if (childTransforms != null) { tradeEndPoints.AddRange(childTransforms); }
         }
     }
 
 }
 
 // it would be better to call this class TradeShipSpawner - because that's what it does
 public class TradingAndTradeShips : MonoBehaviour {
 
     // alternative approach is to set up this list with values in an instance of the script in the scene
     // [SerializeField] private List<Transform> tradeEndPoints = new List<Transform>();
 
     // assign this value in the Editor to an instance of this script
     [SerializeField] private TradeEndPoints tradeEndPoints = null;
 
     [SerializeField] private NeutralAIMovement tradeShipPrefab = null;
     [SerializeField] private float waitToSpawn;
     [SerializeField] private List<float> factionRelationship = new List<float>(); // remember to set up the faction relationships; I suspect that you will need a separate class for this in the future
 
      // public int factionNumber; // I removed factionNumber variable, because you don't use it
      private Coroutine spawnTradeShipsCoroutine;
 
     private void Start () {
         // instead of a bool flag you can use the actual Coroutine object returned from StartCoroutine() and call StopCoroutine() on it when you want to stop it
         spawnTradeShipsCoroutine = StartCoroutine(SpawnTradeShips());
     }
 
     private IEnumerator SpawnTradeShips () {
         while (true) {
             for (int i = 0; i < factionRelationship.Count; ++i) {
                 if (factionRelationShip[i] > 50) {
                     Transform tradeEndPoint = tradeEndPoints.GetTradeEndPoint(i);
                     if (tradeEndPoint != null) { // make sure the trade end point exists
                         // you can instantiate using a component on a prefab and you automatically get a reference to the component! Very useful, and spares you a GetComponent() call
                         NeutralAIMovement tradeShip = Instantiate(tradeShipPrefab); // don't need to specify position and rotation if you want to use the values from the prefab
                         tradeShip.SetTradeEndPoint(tradeEndPoint);
                     }
                 }
             }
             // I think you wanted to check all relationships and then wait, not wait between each check ;)
             yield return new WaitForSeconds(waitToSpawn);
         }
     }
 
 }
 
 public class NeutralAIMovement : MonoBehaviour {

     [SerializeField] private float speed = 0;

     // with the help of storing this variable, you don't need the index nor the list anymore
     private Transform tradeEndPoint;
     public void SetTradeEndPoint (Transform value) { tradeEndPoint = value; }
 
     private void Update () {
         if (tradeEndPoint != null) {
             // slightly more refined debug printout
             Debug.Log("NeutralAIMovement \"" + name + "\" target position: " + tradeEndPoint.position);
             transform.position = Vector2.MoveTowards(transform.position, tradeEndPoint.position, speed * Time.deltaTime);
         }
     }
 
 }



Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

128 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Using Vector3.MoveTowards with each GameObject in a list 2 Answers

Changing LocalScale in code affecting prefab stored in Assets 1 Answer

Do I necessarily need to instantiate a prefab before putting it in List to conserve his variable data? 0 Answers

How do I re-instantiate original prefab after a game object inside has been destroyed? 2 Answers

[C#] How can I destroy instantiated prefabs when many are created with the same name? 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges