Moving sine wave curve 2D
Hi everyone,
I am a Unity beginner. I would like to have a moving sine wave curve in my game which has to be followed with a ring (hot wire game). So far, I just found informations concerning game objects which should move in a sine wave manner. Do I have to do this with the lineRenderer? I would be very happy for some help. Thank you very much.
Answer by Glurth · Mar 07, 2016 at 05:26 PM
The line renderer is used to draw single pixel-wide lines on the screen. If you want to move an object, you will need to change it's position (object.transform.position). You probably want to override the moving objects Update() function (called every frame), and inside there compute the new position and assign it e.g. this.transform.position = new Vector3(t, Mathf.Sin(t),0); //where t is the "angle"
Edit/Update: This version is flexible to show you what I did, and how I did it. You will need to add this script to a game object for the script to start and update:
using UnityEngine;
using System.Collections;
public class FunctionObjectPlotter : MonoBehaviour {
public GameObject plotPointObject;
public int numberOfPoints= 100;
public float animSpeed =1.0f;
public float scaleInputRange = 2*Mathf.PI; // scale number from [0 to 99] to [0 to 2Pi]
public float scaleResult = 10.0f;
public bool animate = true;
GameObject[] plotPoints;
// Use this for initialization
void Start () {
if (plotPointObject == null) //if user did not fill in a game object to use for the plot points
plotPointObject = GameObject.CreatePrimitive(PrimitiveType.Sphere); //create a sphere
plotPoints = new GameObject[numberOfPoints]; //creat an array of 100 points.
for (int i = 0; i < numberOfPoints; i++)
{
plotPoints[i] = (GameObject)GameObject.Instantiate(plotPointObject, new Vector3(i - (numberOfPoints/2), 0, 0), Quaternion.identity); //this specifies what object to create, where to place it and how to orient it
}
//we now have an array of 100 points- your should see them in the hierarchy when you hit play
plotPointObject.SetActive(false); //hide the original
}
// Update is called once per frame
void Update()
{
for (int i = 0; i < numberOfPoints; i++)
{
float functionXvalue = i * scaleInputRange / numberOfPoints; // scale number from [0 to 99] to [0 to 2Pi]
if (animate)
{
functionXvalue += Time.time * animSpeed;
}
plotPoints[i].transform.position = new Vector3(i - (numberOfPoints/2), ComputeFunction(functionXvalue) * scaleResult, 0);
}
}
float ComputeFunction(float x)
{
return Mathf.Sin(x);
}
}
Thank you for your message. I worked today the whole day on that problem without success=( I would be very happy to get an example (script). So far I found this:
1) http://answers.unity3d.com/questions/305484/sine-movement.html
--> But I could not change the direction of the sine wave to horizontal (ins$$anonymous$$d of tangential).
$$anonymous$$y game should look exactly like this:
https://processing.org/examples/sinewave.html
--> This is a js code which I also tried. However I get always an error " UCE0001:; expected. Insert a semicolon at the end?" whereas there is a semicolon after every line...
I have started using Unity a few weeks ago...so that I need really help to proceed... Thank you very much!
Wow amazing! Thank you for this piece of code. I tried it. However, in my game view the curves are too big so that I do even not see the whole amplitude of the sine wave. Is that normal? How could I change that? Is it correct, that I have to add that script to an empty game object? Because first I added it to a sphere I have created but the sphere was not moving... sorry for asking all this questions... but my level of program$$anonymous$$g knowledge is too low to understand all that to be able to code that on my own=( Thank you so much!
curves too big: you can use the scaleResult value to change the Y-coordinate the result plots to. notice: we mutiply the result of our function (sin), by sclaeResult to compute the Y coordinate of the position, on this line:
plotPoints[i].transform.position = new Vector3(i - (numberOfPoints/2), ComputeFunction(functionXvalue) * scaleResult, 0);
It doesn't actually matter what object you attach the script to, since it doesn't actually do anything to itself. It only effects the position of the GamesObject's stored in the plotPoints array, which were created in Start();
I suggest you play around with that code, and see what happens. Take out a line, run to see results, then put it back. Change a number used, run to see results, etc...
$$anonymous$$nowledge of c# is pretty critical in unity, but Unity is also a good tool to learn it. Once you have a good grasp on c#(sorry I have no recommendations on that), I suggest going through all the unity tutorial videos, very useful. By the time you're done, something like this will be trivial for you. Good luck!
Hi, Thank you for your speedy reply. Concerning the scaleResult: That's what I tried... I changed it but nothing happened... I already realized that for other scripts... why does nothing happen when I change the initialized values at the beginning of a script? Like in this case: scaleResult...
Where in the code I see the amplitude and the frequency of the sine wave?
Thank you for the hints concerning Unity. Indeed, C# knowledge would be very helpful. So far, I have just experience with $$anonymous$$atlab. But I am willing to learn it!
Please post replies as comments, rather than answers (I've been converting them for you), Also, if you like it, please select my answer as "accepted".
Note sure why changing the values has no effect. Sounds like you may want to ask a second question about that.
The amplitude is defined by the scaleResult variable we discussed before. The frequency is deter$$anonymous$$ed by the scaleInputRange
variable, when we compute the functionXvalue
, which is the value we pass to the Sin function.
I hope I write you now in the right context (comment) =)
First of all concerning why nothing changes even if I have changed the values I have found the reason:
http://answers.unity3d.com/questions/621684/inspector-not-updating-value-changes.html
Therefore I changed my variables to private and then it worked, yeah!
I also achieved to change the size of the sphere using the following code: //change the scale of the spheres plotPointObject.transform.localScale = Vector3.one * 0.5f ;
Unfortunately, after that there is a big gap between the spheres. $$anonymous$$y aim would be to have small spheres and that these spheres would be localized very close together. So do you know how and where I have to adapt the code to achieve this?
Thank you already in advance for your help!
based on this line:
plotPoints[i].transform.position = new Vector3(i - (numberOfPoints/2), ComputeFunction(functionXvalue) * scaleResult, 0);
We can see that, given a plotPoint[i], it is always drawn to the x coordinate i - (numberOfPoints/2)
Note: this part of the computation: -(numberOfPoints/2), offsets the x axis such that the $$anonymous$$IDDLE sphere is at x=0. And adding the i offsets it by the sphere's index number. So, if you multiple by some scaling number(you'll need to add that to the code yourself!), you will be able to adjust the space between the sphere centers: e.g. (i - (numberOfPoints/2)) * sphereSize
Regarding the value changes not working: I see my mistake now, the Start() function should ACTUALLY be named Awake() ! Also, change 'em back to public: this will allow you to alter their values in the editor/inspector of the object.
Edit: Don't forget, you can also change the position and angle of the camera, in order to get everything into view.
Hi, Thank you for your help. You have really saved my live with your help! I adapted the code (see what I adapted in Start function (see code below). Just applying the Start function leads to what I want to have... that all spheres are near together without any gap. However, as soon as I add the animation of the sine wave there is still this gap even if I multiply by the size of the sphere. I do not see why... =(
Here my code:
using UnityEngine;
using System.Collections;
public class SineWaveSpheres : $$anonymous$$onoBehaviour {
public GameObject plotPointObject;
public int numberOfPoints= 100;
private float animSpeed =1.0f;
public float scaleInputRange = 8*$$anonymous$$athf.PI; // scale number from [0 to 99] to [0 to 2Pi] //Zahl vor $$anonymous$$athf, Anzahl Bön
public float scaleResult = 2.5f; // Y Achse Range
public bool animate = true;
public Vector3 posSphere;
public Vector3 sizeSphere;
public Vector3 newpos;
GameObject[] plotPoints;
// Use this for initialization
void Start () {
if (plotPointObject == null) //if user did not fill in a game object to use for the plot points
plotPointObject = GameObject.CreatePrimitive (PrimitiveType.Sphere); //create a sphere
//add $$anonymous$$aterial to the spheres , load material in the folder Resources/$$anonymous$$aterials
$$anonymous$$aterial my$$anonymous$$aterial = Resources.Load ("$$anonymous$$aterials/green", typeof($$anonymous$$aterial)) as $$anonymous$$aterial;
plotPointObject.GetComponent<$$anonymous$$eshRenderer> ().material = my$$anonymous$$aterial;
//change the scale of the spheres
plotPointObject.transform.localScale = Vector3.one * 0.4f;
plotPoints = new GameObject[numberOfPoints]; //creat an array of 100 points.
//plotPointObject.GetComponent<$$anonymous$$eshRenderer> ().material =$$anonymous$$aterial.Load("blue") as $$anonymous$$aterial
//plotPointObject.transform.localScale -= new Vector3 (0.5F, 0.5F, 0.5F); //neu: change the scale of the spheres
for (int i = 0; i < numberOfPoints; i++) {
int initialposition = 0;
float distanceFromEachOther = plotPointObject.GetComponent<$$anonymous$$eshRenderer> ().bounds.size.x;
//print (distanceFromEachOther);
newpos = new Vector3 (initialposition + (i * distanceFromEachOther), 0, 0);
plotPoints [i] = (GameObject)GameObject.Instantiate (plotPointObject, newpos, Quaternion.identity);
}
//we now have an array of 100 points- your should see them in the hierarchy when you hit play
plotPointObject.SetActive (false); //hide the original
}
Answer by sportente · Mar 09, 2016 at 04:33 PM
I would be very happy to get some help... I worked the whole day on that problem... without any success=(
When I change the scale of the spheres there is a gap between (see screenshot). How can I adapt the code that even if the spheres are small that the are all aligned?
Thank you for your help!
Your answer
Follow this Question
Related Questions
How to move object after set it to certain position? [VR Rift] 0 Answers
Moving an array of Vector3 with the GameObject (Path-System) 0 Answers
Problem with decrement 0 Answers
Get Vector3s in range 1 Answer