Search Unity

What's wrong with this code?

Discussion in 'Scripting' started by vimvq1987, Sep 22, 2009.

  1. vimvq1987

    vimvq1987

    Joined:
    Sep 10, 2009
    Posts:
    40
    Code (csharp):
    1. var pos:Vector3;
    2. var curr:Vector3;
    3. var next:Vector3;
    4. var center:Vector3;
    5.  
    6. function Start() {
    7.     pos = transform.position;
    8.     curr = pos;
    9.     next = CreateNewTarget();
    10. }
    11.  
    12. function Update () {
    13.  
    14.         if(next == transform.position)
    15.         {
    16.         //print("Error");
    17.         curr = transform.position;
    18.         next = CreateNewTarget();
    19.         i++;
    20.  
    21.         }
    22.    
    23.  
    24.     center = (curr + next) * 0.5;
    25.         // move the center a bit downwards to make the arc vertical
    26.     center.y -= 1;
    27.  
    28.         // Interpolate over the arc relative to center
    29.     var currRelCenter = curr - center;
    30.     var nextRelCenter = next - center;
    31.     transform.position = Vector3.Slerp(currRelCenter, nextRelCenter, Time.time * 0.1) + center;
    32.  
    33.  
    34. }
    35.  
    36. function CreateNewTarget() :Vector3
    37. {
    38.     return pos + Random.insideUnitSphere * 5;
    39. }
    40.  
    My idea is: create a new random target, smoothly move the object to it. when it reaches the target, create another one and then continue. But my object only smoothly moves in the first arc. After that, it jumps very quickly. What's wrong with my code?

    Thank you for your help!
     
  2. GargerathSunman

    GargerathSunman

    Joined:
    May 1, 2008
    Posts:
    1,571
    The only thing that could cause that would be a Time.time that's high enough to cause an instant move. As such, you should probably Debug.Log(Time.time.ToString()); to see its values. I believe it increases over time from when the program is created, so that's probably the reason.

    You could try something more like this:
    Code (csharp):
    1. var startTime : float; // Create the variable
    2.  
    3. startTime = Time.time; // Set it equal to the time at the start of the curve
    4.  
    5. transform.position = Vector3.Slerp(currRelCenter, nextRelCenter, (Time.time - startTime) * 0.1) + center; // Slerp it relative to the starting time, not overall time
     
  3. vimvq1987

    vimvq1987

    Joined:
    Sep 10, 2009
    Posts:
    40
    Tt worked! thank you so much :D

    An addition question: the object still flies not very smoothly. Can you help me improve my code to make it smoother?
     
  4. GargerathSunman

    GargerathSunman

    Joined:
    May 1, 2008
    Posts:
    1,571
    Well yes, since you're using linear movement along the curve, that will tend to look a tad jerky. One solution is to move through the curve with a variable you control yourself. Basically, you'd increase that variable's value very slowly at first, get faster, and when you're halfway, slow down to the very slow speed again. You'll end up with a very smooth-looking curve.

    You'll just need two variables, the current position along the curve (somewhere between 0 and 1) and the current acceleration along the curve. You'd change the current acceleration based on the distance along the curve and increase the current position based on that.
     
  5. vimvq1987

    vimvq1987

    Joined:
    Sep 10, 2009
    Posts:
    40
    ...
    Thank you but that's not my real problem. my object is now flying through many curves. It's like that it moves by a curve, and then start a new curve,...It looks a bit terrible. I want to move the object by a smooth, continuous curve. I'm still trying, but it would be great if you can give me a demo code.

    Thank you, once again :D
     
  6. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    OK, I've attached an example script to plot a smooth curve between the points. The code uses Bezier curves, which are a bit complicated, but fortunately you don't need to understand them in order to use the code.

    There are two main functions called SmoothCurvePos and SmoothCurveDirection. You pass both functions your set of points and a value between 0 and 1 - they both work like Vector3.Lerp, except they interpolate along the curve instead of a straight line.
     

    Attached Files:

  7. vimvq1987

    vimvq1987

    Joined:
    Sep 10, 2009
    Posts:
    40
    How can I thank you? :D

    By the way, I've solved this problem. After add the spirit's asset into Unity and test with my old code, it looks quite good :p (with some modifications), not as bad as when I tested with a cube.

    Your code's still helpful for me. I tried to read and understand it, and I learned a lot from it. Thank to you, for all your help you've given to me. I'm new to Unity and I was so confused how to work with it. But now I'm feel much better. Unity is truly wonderful, causes of people like you :D