- Home /
Implement the equation as a code?
Hello devs,
I am trying to create a two dimensional wave movement and I want to create in such a way that a gameobject moves along the x and z axis. Then once a gameobject reaches the target I want it to travel back with similar wave motion. I would like this to be performed as long as I wish. I played around lerp & movetowards, which performed well but they lacked a smoothness or a curve in their motion. I prefer the motion to be in 2 dimensional and not 3 dimensional. I happen to find this formula which might help but at the same time I wondered whether I could get help from you guys.
If you guys tend to find a simpler solution, kindly let me know. I would highly appreciate it.
Thank you,
Karsnen.
Source : http://galileo.phys.virginia.edu/classes/152.mf1i.spring02/Waves2D_3D.htm
perhaps simply use an Animation. a whole animation system is built in to unity. they have good instructional videos.
i thin the formula is almost totally irrelevant. If yo do it with an equation and move it yourself, just use "sin". That will give you the simply wiggly motion you are looking for. Good luck
Answer by Scribe · Jun 13, 2012 at 06:37 PM
Hi, I don't know about using the formula you gave but if I've understood you could do it like this:
var Speed = 1;
var Amplitude = 1;
var TargetPos : Vector3;
function Update () {
transform.position.y = Mathf.Sin(Vector3.Distance(transform.position, TargetPos)*Speed) * Amplitude;
}
The target position could be an object with a transform component depending on your set-up but the same principal applies.
Hope thats useful!
Scribe
EDIT: try this instead, the last version took into account the distance in y which we weren't changing. This hopefully will be correct!
var Speed = 1;
var Amplitude = 1;
var TargetPos : Vector3;
function Update () {
transform.position.y = Mathf.Sin((Mathf.Sqrt((TargetPos.x-transform.position.x)*(TargetPos.x-transform.position.x) + (TargetPos.z-transform.position.z)*(TargetPos.z-transform.position.z)))*Speed) * Amplitude;
}
EDIT2 --------------------------------------------------------------------------------------------------------------------------------------- From your comment your best bet/ the easiest thing would be to go with fattie's suggestion of using an animation. However I was quite bored and like maths so I gave it a go, this is the result:
var Speed = 1.0;
var Amplitude = 1.0;
var Waypoints : Vector3[];
private var WaveLength : float;
private var i = 0;
private var TargetPos : Vector3;
private var StartPos : Vector3;
private var Line1;
private var Grad1 : float;
private var Grad2 : float;
private var k1 : float;
private var k2 : float;
private var MaxDist : float;
private var MedianPos : Vector3;
function Start () {
NextWaypoint();
}
function Update () {
var MedianXPos : float;
var MedianZPos : float;
var CurDist : float;
var Offset : Vector3;
if(Grad1 == 0){
MedianXPos = transform.position.x;
MedianZPos = k1;
CurDist = Vector3.Distance(Vector3(TargetPos.x, 0, TargetPos.z), Vector3(MedianXPos, 0, MedianZPos));
Offset = Vector3(transform.position.x - MedianXPos, 0, transform.position.z - MedianZPos);
}else if(Mathf.Abs(Grad1) == Mathf.Infinity){
MedianXPos = StartPos.x;
MedianZPos = transform.position.z;
CurDist = Vector3.Distance(Vector3(TargetPos.x, 0, TargetPos.z), Vector3(MedianXPos, 0, MedianZPos));
Offset = Vector3(transform.position.x - MedianXPos, 0, transform.position.z - MedianZPos);
}else{
k2 = transform.position.z - (Grad2 * transform.position.x);
MedianXPos = (k1-k2)/(Grad2-Grad1);
MedianZPos = Grad1*MedianXPos + k1;
CurDist = Vector3.Distance(Vector3(TargetPos.x, 0, TargetPos.z), Vector3(MedianXPos, 0, MedianZPos));
Offset = Vector3(transform.position.x - MedianXPos, 0, transform.position.z - MedianZPos);
}
MedianPos = Vector3(Mathf.MoveTowards(MedianXPos, TargetPos.x, Speed * Time.deltaTime), MedianPos.y, Mathf.MoveTowards(MedianZPos, TargetPos.z, Speed * Time.deltaTime));
var SinOffset : Vector3;
if(Grad1 == 0){
SinOffset = Vector3(0, 0, Mathf.Sin(CurDist*WaveLength));
}else if(Mathf.Abs(Grad1) == Mathf.Infinity){
SinOffset = Vector3(Mathf.Sin(CurDist*WaveLength), 0, 0);
}else{
SinOffset = Vector3(Mathf.Sin(CurDist*WaveLength), 0, Grad2*Mathf.Sin(CurDist*WaveLength));
}
transform.position = Vector3(MedianPos.x + (SinOffset.x*Amplitude), transform.position.y, MedianPos.z + (SinOffset.z*Amplitude));
Debug.DrawLine (Vector3(MedianXPos, 0, MedianZPos) + Offset, TargetPos+Offset, Color.red);
if(TargetPos.x == transform.position.x && TargetPos.z == transform.position.z){
if(i < (Waypoints.Length - 1)){
i++;
StartCoroutine("NextWaypoint");
}else{
Debug.Log("Journey finished");
}
}
}
function NextWaypoint () {
TargetPos = Waypoints[i];
StartPos = transform.position;
MedianPos = transform.position;
Line1 = Vector3(TargetPos.x - StartPos.x, 0, TargetPos.z - StartPos.z);
Grad1 = Line1.z/Line1.x;
k1 = StartPos.z - (Grad1 * StartPos.x);
if(Grad1 == 0){
Grad2 = (-1.0)/Grad1;
}else if(Mathf.Abs(Grad1) == Mathf.Infinity){
Grad2 = 0;
}else{
Grad2 = (-1.0)/Grad1;
}
k2 = StartPos.z - (Grad2 * StartPos.x);
MaxDist = Vector3.Distance(Vector3(TargetPos.x, 0, TargetPos.z), Vector3(StartPos.x, 0, StartPos.z));
WaveLength = (2 * Mathf.PI)/MaxDist;
StopCoroutine("NextWaypoint");
}
There are probably lots of better ways to do the same thing but this is what I came up with, it seems to work at least!
Scribe
Speed is probably better described as WaveLength actually :)
But then could you vary the movement (oscillation)?
While when my object moves from (-x,-z) to (x,z) through a sin wave, I would like to change the osicillation to (-x,z) to (x,z) or (x,-z).
I think you've lost me! :D
Is this what you would like it to do?
Yeah partially right.
But the difference in my view is,
ins$$anonymous$$d of multiple waves - just one wave from the current position to target position.
Upon reaching "target" I want to change the initial position.
Like this image.
check my second edit, it should work though your setup means you might be better off using an animation rather than doing this mathematically as I have :) Scribe