You know how in golf games you can set an arc and move it around with the mouse. How would I go about doing that. I think I will use the line/tube renderer, but I am confused how to convert the 2D mouse space into a moving arc. When you move the cursor down to the bottom of the screen the arc would get closer and higher. when you move it up it would get further and lower. Changing the force (or club if it was a golf game) would change the initial position (how far the arc is is from the player). when the mouse is at the middle of the screen its got a 45 degree trajectory. Any input would be great.
You can use a very simple quadratic Bezier formula (I got it from wikipedia) and it works pretty good for me for controlling arcs ( I use it to draw the arms of a monkey...) Code (csharp): function GetQuadraticCoordinates(t : float) : Vector3 { return Mathf.Pow(1-t,2)*p0 + 2*t*(1-t)*c0 + Mathf.Pow(t,2)*p1 ; } where: p0 - is the start point p1 - is the end point c0 - is the middle point ( controlling the arcness ) t - between 0 and 1 just convert the v input (with some scale ) to the y of c0 to control the height of the arc. and do something like : Code (csharp): function Start(){ GetComponent(LineRenderer).SetVertexCount(sections); } function Plot() { var t : float ; for (var i : int = 0 ; i < sections ; i++ ){ t = i/(sections-1) ; lineRenderer.SetPosition (i ,GetQuadraticCoordinates(t)); } }
I do, Code (csharp): function GetQuadraticCoordinates(t : float) : Vector3 { var mousePos = Input.mousePosition; middle.x = mousePos.x; middle.y = mousePos.y; middle.z = end.position.z - start.position.z; return Mathf.Pow(1-t,2)*start.position + 2*t*(1-t)*middle + Mathf.Pow(t,2)*end.position; } function Plot() { var t : float ; for (var i : int = 0 ; i < 10 ; i++ ){ t = i/(10-1) ; lineRenderer.SetPosition (i ,GetQuadraticCoordinates(t)); } } It kinda draws an arc but nothing happens when I move the mouse up or down.
I attached a project that does that If you need to convert the mouse position to world coordinates , you can use - Camera.ScreenToWorldPoint or Camera.ScreenPointToRay and then find a point on the ray in the distance you want. :wink:
Thanks for that script! I'm having trouble figuring out how to move something along that arc, however? Could you give me a hint as to what to do exactly? I tried using something like: Code (csharp): transform.TransformPoint(0,middle.y,end.z) but no luck..
hi jonyjl, Code (csharp): transform.position = bezier.GetQuadraticCoordinates(Mathf.Lerp(0.0,1.0,Time.time) , start.position , middle.position , end.position ); That will move the transform along the arc in a second, the first value Mathf.Lerp(0.0,1.0,Time.time) is just a number from 0 to 1 that represents how far along the curve you want the coordinate. good luck!
I do try that, however I have: Note: "thePlayer" is the player that moves around. It has 3 children which are empty transforms (gameobjects) that are declared in the code as: start , middle and end. Those determine the angle. Code (csharp): var thePlayer: GameObject; var start: Transform var middle: Transform var end: Transform var canThrow = false; var throwable : GameObject; var clone: GameObject; function Update() { If(Input.GetButtonDown("q")) { clone = Instantiate(throwable,thePlayer.position,thePlayer.rotation); canThrow = true; } If(canThrow) { clone.transform.position = bezier.GetQuadraticCoordinates(Mathf.Lerp(0.0,1.0,Time.time) , start.position , middle.position , end.position ); } } When I push play, and click "q" immediately the throwable starts at "thePlayer" 's position and rotation as expected. But say I wait 2 seconds after I push play to click "q": the "throwable" (clone) is instantiated, but it starts further along the arc. If I wait too long and click "q" the instantiated object ends up in the end position. What I think it happening is as time goes by, the bezier.GetQuadraticCoordinates returns a higher value with the variables passed to it (maybe a Time.time issue) I've tried dividing Time.time/20 etc but that just delays the same thing... what's goin on?
Time.time - is the time of the scene in the beginning of the scene it’s 0.0 and after one sec it’s 1.0 when the value is 1.0 the object is at the end of the arc. have some offset time for when “q” was first clicked - Code (csharp): offsetTime = Time.time; then when you use the lerp do: Code (csharp): Mathf.Lerp(0.0,1.0,Time.time-offsetTime) that way the second is counted from when you first pressed “q” and not form the beginning of the scene. to slow down the flight like you said just divide the (Time.time-offsetTime) with some number. I would move the fly code to the clone object if you want to have several item to fly at the same time but I don’t know if that’s actually what you need.
PERFECT! Thanks I actually had that set up but I had too much thought in it.. I had an "endTime" too but the end time IS Time.time - offsetTime Thanks a lot all of this makes much sense I just couldn't get it out of my brain haha
An issue with the line renderer is that the polys always face the camera. So it's going to cause a twist in the ARC at the peak. how do I fix this? I want to add an animated texture on the line renderer to have a nice little aiming system.. Thanks again guys.
I don't think there is any way around this with the line renderer. You may be able to fall back on the Mesh API but the "line" will be rendered in perspective if you use that approach.
Have you seen this ? http://starscenesoftware.com/vectrosity.html There is a forum topic describing it here http://forum.unity3d.com/viewtopic.php?t=53268&postdays=0&postorder=asc&start=0
woops, spoke too soon "Then make a VectorLine object, giving it a name, the points, a material, the line width in pixels, and an end cap length:" var myLine = new VectorLine ("Line", linePoints, lineMaterial, 2, 0); lol