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 /
  • Help Room /
avatar image
1
Question by ComicGirl · Sep 12, 2016 at 02:21 AM · c#2d

Move GameObject to Position, Waiting, and then Moving to Another Position

Greetings, I have been playing around with WaitForSeconds and I can't seem to get this right. The script I'm trying to create is for a simple simulation game. This particular script is for a customer. The outcome I am trying to get is for an object to go to a certain object, stop and wait for 30 seconds and then go to another position. Right now the object does not move at all. Could I get some pointers about where I'm going wrong. Perhaps there is a better solution for what I am trying to achieve?

{ public Transform target; public Transform target2; public float speed;

 void Start()
 {
     float step = speed * Time.deltaTime;
     transform.position = Vector3.MoveTowards(transform.position, target.position, step);
     StartCoroutine(WaitAndGo());
 }

 IEnumerator WaitAndGo()
 {
     yield return new WaitForSeconds(30);
     float step = speed * Time.deltaTime;
     transform.position = Vector3.MoveTowards(transform.position, target2.position, step);
 }

}

Comment
Add comment · Show 2
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 Alverik · Sep 13, 2016 at 11:16 PM 0
Share

Hi, about the [SerializeField] tag. Basically you use it when you are going to declare a private variable at the class level (can't do it inside functions). What it does is 1. exposes a private variable in the inspector, and 2. Ensures that the information of the variable will be remembered by the inspector (there's some times where you'll need to Serialize variables just for that if you are making custom editors). You basically use it like this:

 [SerializeField]
 private bool mySwitch;

You can also safely put that in one line if you feel like it:

 [SerializeField]private bool mySwitch;

If for some reason you are having trouble you can just use public variables, they have the same effect (they are serialized by default), but as I mentioned they are visible by other scripts. It's usually bad practice to make every variable public because 1. when you then try to access the script from the outside and you use intellisense you'll get a huge list full of variables and methods, many of which you don't want others to run from the outside, and 2. To make sure there are no duplicated names which may clash later on, specially if you have many third party assets and you have not created your own namespace.

Edit: you can read more about it here http://forum.unity3d.com/threads/serialization-best-practices-megapost.155352/

avatar image ComicGirl Alverik · Sep 19, 2016 at 08:17 PM 0
Share

Thank you! Between your explanation and the link you provided, I am pretty sure I understand. I'm going to have to play with it a bit more before I'm able to get it to work as intended, but I am better off and more on track now. Thank you for your time!

5 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by 3tai · Sep 12, 2016 at 02:36 AM

You have nothing indicating when the transform has arrived and so the movement functions are only moving for single frames. It will move for a single frame when Start() is called, starts the coroutine, wait for 30 seconds, them take another step towards target2.position. The Vector3.MoveTowards needs to be in Update() or a looped Coroutine for it to be run every frame, and you'll need to add in a way to detect whether the transform has arrived so that it knows when to stop Vector3.MoveTowards.

Comment
Add comment · Show 1 · 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 3tai · Sep 12, 2016 at 02:42 AM 0
Share

the following code is probably full of errors but it'll give the general idea of what you need to do:

 public IEnumerator $$anonymous$$ovementCoroutine() {
 bool arrived = false;
 while(!arrived)
 {
     Vector3.$$anonymous$$ovetowards(thing1, thing2, step)
     if(Vector3.Distance(thing1, thing2) == 0) arrived = true;
     yield return null;
 }
 if(arrived)
 {
     //do something when it arrives
 }

 }
avatar image
0

Answer by ComicGirl · Sep 12, 2016 at 03:14 AM

Okay, this is great! But I am running into an error that says "Argument 1: Cannot Convert from 'unityEngine.Transform to "UnityEngine Vector 3"

You'll have to bear with me for I am very new and am still looking over the Scripting API. This is like taking a foreign language haha. Thank you for your time and patience thus far.

Comment
Add comment · Show 4 · 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 ComicGirl · Sep 12, 2016 at 03:32 AM 0
Share

Okay, so I got rid of the errors by adding in ".position" to the targets. The script no longer has errors, but the object is not moving.

I kinda tinkered with the script but I don't think this is right.

{ public float speed; public Transform target1; public Transform target2; void Start() {

 }
 public IEnumerator $$anonymous$$ovementCoroutine()
 {

     float step = speed * Time.deltaTime;
     bool arrived = false;
     while (!arrived)
     {
         Vector3.$$anonymous$$oveTowards(transform.position, target1.position, step);
         if (Vector3.Distance(transform.position, target1.position) == 0) arrived = true;
         yield return null;
     }


     if (arrived)
     {
         yield return new WaitForSeconds(5);
         Vector3.$$anonymous$$oveTowards(transform.position, target2.position, step);
     }
 }

}

avatar image 3tai · Sep 12, 2016 at 03:41 AM 0
Share

Have you verified that the $$anonymous$$ovementCoroutine() started? the logic looks good to me. Double check all the other variables involved too (e.g. is speed set to 0?) add some debug logs like Debug.Logs("$$anonymous$$ovementCoroutine() started main while loop!"); here and there and that'll help you figure out how far your scripts have run to. (the messages show up in the console)

The second part of the movement coroutine will do the thing as your first snippet of code where it only goes for one frame, because it's outside of a while() loop. You'll have to reset arrived to false and have another while(!arrived) loop. Later on as you develop your code you'll probably set up something like public bool IEnumerator $$anonymous$$ovementCoroutine(GameObject targetObject) that returns true only when the object has arrived, so you can use a second Coroutine to easily set up multiple destinations.

avatar image 3tai · Sep 12, 2016 at 03:45 AM 0
Share

oh, I incorreclty used Vector3.$$anonymous$$oveTowards() in my sample code.

It should be transform.position = Vector3.$$anonymous$$oveTowards(param1, param2, param3)

avatar image ComicGirl 3tai · Sep 12, 2016 at 06:25 AM 0
Share

Brilliant! The object is moving again. Okay so I have updated the script. This is what I have thus far-

void Start () { StartCoroutine($$anonymous$$ovementCoroutine()); } public IEnumerator $$anonymous$$ovementCoroutine() {

     float step = speed * Time.deltaTime;
     bool arrived = false;
     Debug.Log("$$anonymous$$ovementCoroutine() started main while loop!");
     while (!arrived)
     {
        transform.position = Vector3.$$anonymous$$oveTowards(transform.position, target1.position, step);
         if (Vector3.Distance(transform.position, target1.position) == 0) arrived = true;
         yield return null;
     }


     if (arrived)
     {
         yield return new WaitForSeconds(5);
        transform.position = Vector3.$$anonymous$$oveTowards(transform.position, target2.position, step);
     }
 

So we have the object going to the target1 position, but it is still not going to the next. I believe this is because as you said it is still in "void Start()" so it is only calling it one time. I can see the object move for a split second and then it stops. How would I incorporate a "void Update()" to make it happen every frame? I attempted some tinkering but had no success.

Again thank you for your time, this has already been a tremendous help!

avatar image
0

Answer by Alverik · Sep 12, 2016 at 10:08 AM

Looking at your latest attempt, I notice you are trying to verify if a float distance equals to 0. That has a lot of chances for failing. It may be that the number never gets to a perfect 0 (could end up 0.011111, etc), so the loop never ends. This is the kind of place where you would put a debug.log inside the loop to verify if it's still running, and if needed find a better condition for exiting the loop (you could compare if both transform.positions are the same or you could check if the current value is less than <0.1f instead). Now the second movement is just wrong anyways. If you are planning to have the same kind of operation it stands to reason that you'd need another while loop for moving the second time (just like the first one), just an if conditional won't do. As it is now, the system will wait 5f seconds then move the object a tiny, tiny bit and the coroutine will finalize, stopping forever.

Comment
Add comment · Show 4 · 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 Alverik · Sep 12, 2016 at 01:41 PM 0
Share

Also, seeing how you'd repeat the code for the other segment I would just ins$$anonymous$$d create a single method which takes a public array of gameobjects. And use a foreach to get the current object to move to the targets (the foreach would have the same while loop inside, and when it's finished it would just repeat for the next game object). That way the user would just need to change the number of objects to use as markers and place them in the world. Something along the lines of:

 /// <summary>
         /// $$anonymous$$oves an object to an specified set of targets.
         /// </summary>
         /// <param name="markers">the objects to be used as markers.</param>
         /// <param name="durations">the movement duration for each marker.</param>
         /// <param name="waitTime">the wait time before moving to the next marker.</param>
         /// <returns></returns>
         public IEnumerator<float> $$anonymous$$oveTo$$anonymous$$arker(GameObject[] markers, float[] durations, float[] waitTime)
         {
             //for each target
             foreach (var target in markers)
             {
                 //ready the vars for current target's loop
                 bool shouldContinue = true;
                 int i = 0;
                 //start moving the object
                 do
                 {
                     transform.position = Vector3.$$anonymous$$oveTowards(transform.position, target.transform.position, durations[i]);
                     if (transform.position == target.transform.position || Vector3.Distance(transform.position, target.transform.position) <= 0.1f) shouldContinue = false;
                     //release control for a frame
                     yield return 0f;
 
                 } while (shouldContinue);
 
                 //release control for a frame
                 yield return Ti$$anonymous$$g.WaitForSeconds(waitTime[i]);
             }
         }

You'll have to change the yields and the coroutine declaration a bit to test it, because I use $$anonymous$$EC coroutines (Or just get $$anonymous$$ore Efficient Coroutines in the asset store. It's free).

avatar image ComicGirl Alverik · Sep 12, 2016 at 07:51 PM 0
Share

Thank you for your reply. So if I understand correctly use a public array of objects rather than what I was using before? I'm attempting to read the code above but I'm having some difficulty in understanding a few things. In attempting to understand I duplicated your work in a script. The only error the script is reporting is in the last line

 yield return Ti$$anonymous$$g.WaitforSeconds(waitTime[I]);

the error is saying that Ti$$anonymous$$g does not exist in the current context.

I think I understand how this will be more effective in what I'm trying to do. That this will enable me to have an object move to multiple positions and better organize where those positions are correct? Thank you again for your time :)

avatar image Alverik ComicGirl · Sep 12, 2016 at 10:06 PM 0
Share

Hi, sorry for taking a while to respond. Yes, as I mentioned in my previous post I had $$anonymous$$EC coroutines in $$anonymous$$d when I wrote that up (sorry, I just use it so much). The Ti$$anonymous$$g class is part of $$anonymous$$EC coroutines. If I remember correctly, you need to use yield return new WaitForSeconds(); for unity coroutines ins$$anonymous$$d. Also, $$anonymous$$EC coroutines need the IEnumerator to return a float, so you may not need to have IEnumerator <float> but just IEnumerator. For examples regarding Unity coroutines and the yields you can use on them you can check this page: https://docs.unity3d.com/$$anonymous$$anual/Coroutines.html

Edit: For the same reason (about unity coroutines having no need to return floats) the yield return statements can simple be turned into yield return null; Edit 2: And yes, having arrays will allow you to have as many targets as you need. Just remember to expose the arrays in the inspector either using the [SerializeField] tag above or right before a private variable or by making the variable public (Just try to bear in $$anonymous$$d, that making a variable public is best left for times when you are planing to access or modify said variable from other scripts, if you are not going to do that, then just make it private and tag it to expose it on the inspector)

Show more comments
avatar image
0

Answer by dmit99_ · Dec 10, 2019 at 02:40 PM

Did you try: this.gameobject.transform.position?

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 guinoalaskapp · Jun 08, 2021 at 11:49 PM

Hello, Similar Isue, i have a code to change GameObject.transform.position to another position after counting. The isue is when I run the code, it changes the position first even when the WaitForSeconds() is before it.

here is the code of my IEnumerator():

 IEnumerator MyCoroutine(){
         yield return new WaitForSeconds(5);
     transform.position = Other.position;
 }
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

254 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 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

After Rotating a Prefab, Transform.Position of children is inaccurate 1 Answer

Pipe Game Water Flow 0 Answers

KillPlayer, Null Reference Exception. 2 Answers

HLAPI simple 2 player game 1 Answer

He wants to write a script on a page change gait from right to left or vice versa 0 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