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

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

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

Joined:
Jan 14, 2011
Posts:
9,835
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);

Joined:
Oct 11, 2012
Posts:
18,915
5. 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

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

7. Xenoun

Joined:
Sep 2, 2015
Posts:
201

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

Joined:
Jan 14, 2011
Posts:
9,835
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

Joined:
Oct 11, 2012
Posts:
18,915
@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

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

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

Joined:
Oct 11, 2012
Posts:
18,915
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

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

Joined:
Oct 11, 2012
Posts:
18,915
You were given the formula...

15. 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

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

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

18. JoeStrout

Joined:
Jan 14, 2011
Posts:
9,835
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

Joined:
Jan 14, 2011
Posts:
9,835
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

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

21. 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.