Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How do I make this line of code curve instead of go in a straight line?

Discussion in 'Getting Started' started by sr3d, Oct 22, 2015.

  1. sr3d

    sr3d

    Joined:
    Oct 19, 2015
    Posts:
    78
    Code (csharp):
    1.  
    2.  
    3.   public GameObject mySource;
    4.   public GameObject myDestination;
    5.  
    6.   transform.Translate(Vector3.forward * Time.deltaTime * 55f);
    7.   transform.LookAt(myTarget);
    8.  
    The above code causes a projectile to shoot straight at whatever it's facing.

    The problem is the projectile shoots straight like a bullet. I want it to travel up a little then come down like a spear, so imagine a spear being thrown.

    How can I convert the above code to do that? I've tried slerp, lerp and all I'm left with is derp, none of it works except the above code.

    Example of what I need to do:

    Code (csharp):
    1.  
    2.  
    3. projectile.transform.movefrom(mySourceTo, myDestination, CurveAmount, Speed)
    4.  
    5.  
     
    Last edited: Oct 23, 2015
  2. Xenoun

    Xenoun

    Joined:
    Sep 2, 2015
    Posts:
    201
    There's a great resource for questions like these that will save you time waiting for an answer.

    You'll find it here

    Might seem a little harsh but you'll have more success and learn more by looking for things yourself rather than asking a question. If after searching you haven't found the answer then that's when it's a good time to ask for help.
     
  3. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Well, I can think of a few ways to do that. You could use physics, but you'd need to compute an initial velocity to hit the target, like in that blog post you didn't like. Also, it would be hard to make it track a moving target.

    So, maybe a better approach would be to simply add a bit of up/down tilt to the code you already have. You'll need some code to figure out what that tilt should be; for example, you could use an appropriately scaled sine function, or you could just use Mathf.Lerp from like -30 to 30 degrees over the course of the flight.

    Anyway, assuming you have figured the currentTilt you want, then after you do transform.LookAt(target), just add something like:

    Code (CSharp):
    1. transform.Rotate(currentTilt, 0, 0);
     
  4. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,964
  5. sr3d

    sr3d

    Joined:
    Oct 19, 2015
    Posts:
    78
    I've been doing that since yesterday. I've tried so many different ways, but all of them have produced bizarre results.

    As soon as I figure out a simple approach, I'll post it here. I'm surprised I can't find one god damn example of this actually working. This is ridiculous.


    Oh god. I just need to curve a damn path, holy S***.


    This is like all ten other examples I've found, it doesn't work at all.
     
  6. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,964
    Okay. Have fun. If you're unwilling to try our suggestions then I'll stop giving them to you.
     
  7. Xenoun

    Xenoun

    Joined:
    Sep 2, 2015
    Posts:
    201
    Half way down that google search I linked is this: http://gamedev.stackexchange.com/qu...ow-to-make-a-tower-defence-mortar-aim-accurat

    A guy pretty much asking the exact same question as you, except its a motar for tower defence instead of a spear.

    In the replies to his question is this answer:
    This will work. Use the basic maths formula for the arc of a circle instead of a straight line and the projectile will follow the arc.
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    It will work, unless he blindly pastes in code without understanding what he's doing, doesn't take the time to figure it out, claims it produces "bizarre results," and then starts swearing in the forums.

    In that case, he's doomed to fail, and I just hope he will do so quietly rather than filling our forums with vitriol.

    @sr3d, if you really want to make progress, then (1) calm down; (2) try just one approach — probably either the one I described or the one @Xenoun quoted; (3) actually spend a little time understanding it and trying to get it to work; (4) if you still can't get it to work, paste the code you're trying here, along with a calm and detailed explanation of what happens and how that differs from what you wanted/expected.

    Programming requires clear thinking and practice, and yes, sometimes it requires a little math. If that's not for you, that's fine, just find a different activity that you enjoy more.
     
    Ryiah and jhocking like this.
  9. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,964
    @Xenoun: By the way, if you modify the search a tad you'll get a tutorial in your results for curves and splines. It's interesting how some minor changes produce entirely different and sometimes very useful results.
     
    Xenoun likes this.
  10. Xenoun

    Xenoun

    Joined:
    Sep 2, 2015
    Posts:
    201
    That's true, I didn't put much effort into the search though. Was just trying to point out what would turn up if the OP googled his exact problem.
     
    Ryiah likes this.
  11. sr3d

    sr3d

    Joined:
    Oct 19, 2015
    Posts:
    78
    Sorry, I'm not interested in creating things from scratch. I'm looking for Unity to have this problem solved already.

    When I find the code that actually does what I want, I'll share it here and anyone will be able to copy and paste it and have it work perfectly in their game.
     
  12. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,964
    You would have a solution already if you had paid attention to my suggestion. Given your attitude though I doubt you'll be a game developer for very long. You won't find an engine that handles every single task for you.
     
  13. sr3d

    sr3d

    Joined:
    Oct 19, 2015
    Posts:
    78
    Does anyone know how to transform an object from one moving object to another moving object on a curve instead of a straight line?

    Function MoveObjectFrom(HereTo, Here, UsingThisHeight)

    if UsingThisHeight is zero then it goes in a straight line.

    Come on, please don't make me do a math refresher course for something that needs to be a simple part of unity, GOD DAMN IT.
     
  14. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,964
    You were given the formula...
     
  15. sr3d

    sr3d

    Joined:
    Oct 19, 2015
    Posts:
    78
    I found an example of what I need. The guy uses a slerp3 Vector3, but he didn't provide any code.

    FAST FORWARD to 0:45


    Can anyone reproduce how he did that but on the Y? I want it to be in the air not slide on the ground.

    This is my code, for now all it does is slowly move the projectile from mySource to myDest with no curve.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Script_Slerp : MonoBehaviour {
    6.  
    7.   public GameObject mySource;
    8.   public GameObject myDestination;
    9.  
    10.   //suppposedly the projectile should only take three seconds to get to the destination, but this doesn't work
    11.   public float journeyTime = 3.0F;
    12.   //not sure what this is for
    13.   private float startTime;
    14.  
    15.   void Start()
    16.   {
    17.   // move this projectile to it's start position at mySource
    18.   transform.position = mySource.transform.position;
    19.   }
    20.  
    21.   // Update is called once per frame
    22.   void Update()
    23.   {
    24.   // where the projectile starts from
    25.   Vector3 SourcePos = mySource.transform.position;
    26.   // the projectiles destination target
    27.   Vector3 DestPos = myDestination.transform.position;
    28.  
    29.   //find the center
    30.   Vector3 center = (SourcePos + DestPos * 0.5F);
    31.  
    32.   //i have no idea what this is for, changing the values didn't do anything
    33.   center -= new Vector3(0, 1, 0);
    34.  
    35.   //not sure what this is for
    36.   Vector3 SourcePosMinusCenter = SourcePos - center;
    37.   Vector3 DestPosMinusCenter = DestPos - center;
    38.  
    39.   //not sure what this is
    40.   float movementComplete = (Time.time - startTime) / journeyTime;
    41.  
    42.   //all this seems to do is move the object straight from the sourcepos to destpos like a bullet
    43.   transform.position = Vector3.SlerpUnclamped(SourcePosMinusCenter, DestPosMinusCenter, movementComplete);
    44.  
    45.   //not sure what this does
    46.   transform.position += center;
    47.  
    48.   //this is supposed to make the capsule act like a spear where spear tip looks at it's target, but it doesn't work
    49.   Vector3 relativePos = DestPos - transform.position;
    50.   Quaternion rotation = Quaternion.LookRotation(relativePos);
    51.   transform.rotation = Quaternion.Slerp(transform.rotation, rotation, 5.0f);
    52.   }
    53.  
    54.    
    55. }
    56.  
    57.  
     
    Last edited: Oct 23, 2015
  16. sr3d

    sr3d

    Joined:
    Oct 19, 2015
    Posts:
    78
    Code (csharp):
    1.  
    2. //where y is the height
    3. projectile.transform.position;
    4.  
    5. //x is distance to target
    6. Vector3 distance = mySource.transform.position - myDestination.transform.position;
    7.  
    8. //b is the maximum height of the projectile
    9. float maxHeight = 50.0f;
    10.  
    11. //c is the vertical position of the tower
    12. Vector3 vertPosTower = mySource.transform.position;
    13.  
    14. //y = -(x-x/2)^2 + b + c
    15. projectile.transform.position = -(distance  - distance  / 2) ^ 2 + maxHeight + vertPosTower;
    16.  
    Can anyone tell me if this is on the right track?
     
  17. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    813
    You alienate the people here and then expect them to debug your code?
     
  18. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    No kidding. But I will continue to help a while longer... there is a chance we can get sr3d over this initial learning hump, help him see both how to learn and how to get help, and make him a productive addition to the community. :)

    @sr3d, it seems to me you are struggling to understand vectors. A Vector3 is a combination of x, y, and z. Three numbers. It can represent a position, a change in position, a velocity (change in position per second), etc. It does not, in itself, represent something like distance; distance is a scalar (a single number instead of two or more).

    So, saying "Vector3 distance" doesn't make much sense. And you can't square a vector (nor can you square anything with ^ in C-derived languages; use Mathf.Pow instead).

    Similarly, if you want "the vertical position of the tower" then that too should be a float, not a Vector3. You probably want mySource.transform.position.y for that.

    Also, it's not clear where you're putting this code. I wonder if you understand the big picture of how Unity scripts work? You set something up in Start or when something happens (user presses a key or whatever), and then you have to update the object on every frame using the Update method. There are other ways (e.g. coroutines), but I recommend just using Update, especially for beginners.

    This is why your request for a "Function MoveObjectFrom(HereTo, Here, UsingThisHeight)" is mostly nonsense. A function can't move something over time, except maybe by using coroutines, but that will only confuse you more. A function could provide the information you need to move it (perhaps taking a fourth 't' parameter for the interpolation), but it'd still be up to you to properly put it to use.

    If all this is news to you, then I really recommend you put aside your specific goal of curvy spears in your tower defense game, and focus on doing more tutorials for a few weeks (or months). You will learn all this and much more, and then when you go back to your own game, you will find that you know how to do most of what you need to know. You won't waste days getting stuck on trivial stuff, which is very frustrating.
     
    ml785 and Ryiah like this.
  19. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    OK, I spent some time coding up a solution for you. This uses exactly the technique I suggested above.

    First, let's start with the straight (non-arcing) projectile. Here's a complete script.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class ArcingProjectile : MonoBehaviour {
    4.     public Transform target;
    5.     public float speed = 5;
    6.  
    7.     float startDist;
    8.  
    9.     void Start() {
    10.      }
    11.    
    12.     void Update() {
    13.         // Look at the target, so we continue to seek it out
    14.         transform.LookAt(target);
    15.  
    16.        // Move forward
    17.         transform.Translate(Vector3.forward * speed * Time.deltaTime);
    18.     }
    19. }
    So, we look at the target, and move forward. You had this much already, though you never posted a complete script. Now let's modify it to, as I suggested, compute an arc based on how far along the path we are. I'm using Lerp (actually LerpAngle) here because it's probably the easiest to understand and tweak.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class ArcingProjectile : MonoBehaviour {
    4.     public Transform target;
    5.     public float speed = 5;
    6.  
    7.     float startDist;
    8.  
    9.     void Start() {
    10.         // Find the initial distance to the target
    11.         startDist = (target.transform.position - transform.position).magnitude;
    12.     }
    13.    
    14.     void Update() {
    15.         // Look at the target, so we continue to seek it out
    16.         transform.LookAt(target);
    17.  
    18.         // Compute the distance to the target
    19.         float dist = (target.transform.position - transform.position).magnitude;
    20.         // ...and the fraction (t) of how far we are along the path
    21.         float t = Mathf.Clamp01(1 - (dist / startDist));
    22.         // Use this to arc (rotate up) the projectile
    23.         float arc = Mathf.LerpAngle(-30, 0, t);
    24.         transform.Rotate(arc, 0, 0);
    25.  
    26.         // Move forward
    27.         transform.Translate(Vector3.forward * speed * Time.deltaTime);
    28.     }
    29.  
    30. }
    I've tested this and it works great for me. If it doesn't work great for you, please post a detailed description of what you did, what happened, and how that differed from what you wanted.

    And finally, please take note of what sort of community we have here. Unlike most forums on the Internet, the Unity forums are a very friendly place. We don't swear at each other; we don't do personal attacks; we give support and encouragement as much as we can, and thoughtful criticism when it is asked for. Most of us are professionals who have our own projects we should be working on; we hang out here to be part of the community and help newbies to repay the karma from those who helped us.

    If you're struggling with something, and observe lots of people making suggestions and you can't get them to work, consider that you probably don't have the necessary background to make them work, or your basic assumptions are somehow flawed. Getting angry and antangonizing those who try to help you is not productive. Asking more questions is, if you ask calmly, include lots of detail, and show a willingness to try what is suggested.

    OK, enough soapboxing from me... I hope this is helpful, and I look forward to seeing the amazing games you create someday!
     
  20. sr3d

    sr3d

    Joined:
    Oct 19, 2015
    Posts:
    78
    Thank you . This needs to find its way into the official unity tutorial.
     
  21. sr3d

    sr3d

    Joined:
    Oct 19, 2015
    Posts:
    78
    I decided to contribute as well, I uploaded my RTS camera script, hopefully it will help other people. Just spreading that karma around.

    http://forum.unity3d.com/threads/mr-generic-rts-camera-movement-script-v1-0a-free.363491/