Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 Mithosbluefish · Sep 22, 2012 at 02:32 AM · functiondragyieldswipemultitouch

Yield Causing function not to be called on multitouch script

Hi, I've been working on a multitouch swipe script, however i seem to have run into a little snag. It occured when I was going to merge the multitouch with the swipe (both of which worked perfectly on their own). It seems a yield within a while loop I use to track the swipe is causing the entire function it is within to go ignored. This yield wassn't a problem in the original script however now it suddenly won't play nice. :P

The loop in question:

 while (Input.touchCount > 0){
     var ray = mainCamera.ScreenPointToRay(touch.position);
     var thepoint:Vector3 =ray.GetPoint(distance);
     springJoint.transform.position = thepoint;
     yield;
 }


This is contained within a function that is called on each update. The touch position is dependent on a touch manager script (however i have checked that it is indeed recieving coordinates, etc.).

Here's both the update and the DragObject function which contains the loop:

function Update(touch:Touch){

     this.touch = touch;
     isUpdate = true;
         
     
     /*if(!isSelect)
     {*/
         // We need to actually hit an object
         var hit : RaycastHit;
         if (!Physics.Raycast(mainCamera.ScreenPointToRay(touch.position),  hit, 100)) {
             isSelect = false;
             return;
         }
         // We need to hit a rigidbody that is not kinematic
         if (!hit.rigidbody || hit.rigidbody.isKinematic) {
             isSelect = false;
             return;
         }
             
         if (!springJoint)
         {
             var go = new GameObject("Rigidbody dragger");
             var body : Rigidbody = go.AddComponent ("Rigidbody") as Rigidbody;
             springJoint = go.AddComponent ("SpringJoint");
             body.isKinematic = true;
             isSelect = true;
         }
         else 
         {isSelect = true;}
             
         
             
         springJoint.transform.position = hit.point;
             
         springJoint.spring = spring;
         springJoint.damper = damper;
         springJoint.maxDistance = distance;
         springJoint.connectedBody = hit.rigidbody;
             
         
         DragObject(hit.distance, hit.point, touch);
         //}
         
             
 }
 function DragObject(distance : float, hitpoint : Vector3, touch : Touch)
 {   
                
     var startTime = Time.time;
     var oldDrag = springJoint.connectedBody.drag;
     var oldAngularDrag = springJoint.connectedBody.angularDrag;
     springJoint.connectedBody.drag = drag;
     springJoint.connectedBody.angularDrag = angularDrag;
         
     while (Input.touchCount > 0)
     {
         var ray = mainCamera.ScreenPointToRay(touch.position);
         var thepoint:Vector3 =ray.GetPoint(distance);
         springJoint.transform.position = thepoint;
         yield;
     }
 
         
     if (springJoint.connectedBody)
     {
         springJoint.connectedBody.drag = oldDrag;
         springJoint.connectedBody.angularDrag = oldAngularDrag;
         springJoint.connectedBody = null;
             
             
     }
         
         
 }

I have tried using returns instead of the yield but it doesn't seem to result in the same effect. I hope someone can help me out as it would be much appreciated :)

Regards MB

Comment
Add comment · Show 4
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 Mithosbluefish · Sep 22, 2012 at 03:06 PM 0
Share

I've been using "debug.Log" a lot and that's how i found that the function seems to be skipped due to the yield. From what I've found the entire update function works like a charm and all the variables are returning the correct data. However due to the yield it seems to ignore the DragObject class. Like i stated in my original question: I have tested with returns, in which case the function is run, however to the undesired outcome. The drag functioned well when it was on it's own (taking only Input.GetTouch(0)), however when merged with the mul$$anonymous$$ch script the yield suddenly refuses to work (even when only taking info from finger one). I would greatly appreciate it if someone knew what could be causing this.

avatar image whydoidoit · Sep 23, 2012 at 02:48 AM 0
Share

You cannot yield from a function called by Update unless you start it as a coroutine. Basically it never executes anything after the first time it yields.

avatar image Bunny83 · Sep 23, 2012 at 03:19 AM 3
Share

@whydoidoit: But in UnityScript you don't need to call StartCoroutine explicitly. The compiler calls StartCoroutine implicitly when you just "run" a Coroutine / generator (a function that yields). You only have to use StartCoroutine when you want to yield another coroutine.

avatar image whydoidoit · Sep 23, 2012 at 03:20 AM 0
Share

Ah good point!

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Mithosbluefish · Aug 12, 2013 at 12:40 AM

Problem was that if you make a coroutine within a class in UnityScript it will need a StartCoroutine.

Comment
Add comment · Show 3 · 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 Fattie · Aug 12, 2013 at 07:34 AM 0
Share

Note that (as Bunny mentions above) in fact you generally DON'T need a StartCoroutine in Unityscript. It will do it for you automatically. (It even says so in the Unity doco.)

But I will tell you just the problem you're having....

The problem is that your routine DragObject .....

"sometimes" it is a coroutine, and "sometimes" it is NOT a coroutine.

Note that in the code in DragObject, it is not guaranteed to call the yield.

It's the same issue I was having here...

http://answers.unity3d.com/questions/471783/freaky-cant-return-out-of-an-ienumerator.html

The problem is you have two paths, one with yield in it and one with no yield in it.

It just seems to be "too much" for the Javascript to automagically make decisions about, or something.

I completely investigated this Javascript curiosity when it came up - but actually I forget the result!

(None of this will come up in c#)

Among other things you may want to explicitly declare that the function is a coroutine, eg,

function DragObject(distance : float, hitpoint : Vector3, touch : Touch):IEnumerator

The bottom line is you just "shouldn't write code like that" -- in Javascript in an implicit coroutine always call yield -- don't make a "two path" routine.

So: the simple solution .. where you

while (Input.touchCount > 0)

if so, just break away to a different routine (ie, it will be your yielding coroutine) - it's that simple.

avatar image Mithosbluefish · Aug 12, 2013 at 12:33 PM 0
Share

Hey, thanks for the feedback, this problem was actually solved a while ago but i thought i should write how I solved it. The code works fine in C# and UnityScript when it's not in a class, it is only when it is within a class that the function needs to explicitly be called as a coroutine. As for the function it self (on and off coroutining), I based it on a unity tutorial from one of the unity pages, but will definitely revise my technique for next time. Thanks again for the feedback :).

avatar image Fattie · Aug 12, 2013 at 12:53 PM 0
Share

Sounds good. The salient facts are:

(1) In fact in U/S, as Bunny says, you don't need to explicitly call StartCoroutine. (You could possibly say that in a sense, if you DO have to do that there is a problem.)

(2) There is a problem in U/S, relating to coroutines. Since it "automatically" figures out if it is a coroutine (basically, if it contains yield), you can have trouble if there are TWO PATHS within a routine, one of which does and one of which does not contain a yield concept.

Essentially, for anyone reading in the future, just don't do that. IE, type the extra 12 or 13 keystrokes and just make that "path" a separate function.

Hope it helps someone!

avatar image
0

Answer by Mithosbluefish · Sep 23, 2012 at 02:54 AM

I managed to solve it, turns out my mistake was in a part i didn't include here as i thought it wasn't relevant. Turns out it was due to my class not being derived from monodevelop and hence didn't work.

So i added:

  class Coroutiner extends MonoBehaviour
     {
     
     }

and called:

 coroutineRunner.StartCoroutine(DragObject(hit.distance, hit.point, touch);

and not it works perfectly :D

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

12 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

Related Questions

Unity mobile swipe drag control 0 Answers

Calling a function after game over to retry 0 Answers

yield WaitForSeconds don't work 1 Answer

Weirdness.. Why does putting yield in function corrupt commands? 1 Answer

Have a function wait unitl a boolean is false 1 Answer


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