Moving object continuously using translate - unity3d

I want to move an object from A to B continuously,like 1st A to B then B to A then again A to B and so on,thanks in advance. I've tried this.
float speed X = 1; float speed Y = 0; float speed Z = 0;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
transform.Translate (new Vector 3 (speed X, speed Y, speed Z) * Time . delta time );
}

You should need to use Vector3.Lerp:
Linearly interpolates between two vectors.
Interpolates between the vectors a and b by the interpolant t. The
parameter t is clamped to the range [0, 1]. This is most commonly used
to find a point some fraction of the way along a line between two
endpoints (e.g. to move an object gradually between those points.(read this)
While for your actual answer here is code you can see:
http://answers.unity3d.com/questions/14279/make-an-object-move-from-point-a-to-point-b-then-b.html
http://answers.unity3d.com/questions/905966/moving-an-object-constantly-between-two-points-wit.html
How to move an object between two points in Unity?
http://answers.unity3d.com/questions/690884/how-to-move-an-object-along-x-axis-between-two-poi.html

Related

Make ring of vectors "flat" relative to world space

I am trying to simulate liquid conformity in a container. The container is a Unity cylinder and so is the liquid. I track current volume and max volume and use them to determine the coordinates of the center of where the surface should be. When the container is tilted, each vertex in the upper ring of the cylinder should maintain it's current local x and z values but have a new local y value that is the same height in the global space as the surface center.
In my closest attempt, the surface is flat relative to the world space but the liquid does not touch the walls of the container.
Vector3 v = verts[i];
Vector3 newV = new Vector3(v.x, globalSurfaceCenter.y, v.z);
verts[i] = transform.InverseTransformPoint(newV);
(I understand that inversing the point after using v.x and v.z changes them, but if I change them after the fact the surface is no longer flat...)
I have tried many different approaches and I always end up at this same point or a stranger one.
Also, I'm not looking for any fundamentally different approach to the problem. It's important that I alter the vertices of a cylinder.
EDIT
Thank you, everyone, for your feedback. It helped me make progress with this problem but I've reached another roadblock. I made my code more presentable and took some screenshots of some results as well as a graph model to help you visualize what's happening and give variable names to refer to.
In the following images, colored cubes are instantiated and given the coordinates of some of the different vectors I am using to get my results.
F(red) A(green) B(blue)
H(green) E(blue)
Graphed Model
NOTE: when I refer to capital A and B, I'm referring to the Vector3's in my code.
The cylinders in the images have the following rotations (left to right):
(0,0,45) (45,45,0) (45,0,20)
As you can see from image 1, F is correct when only one dimension of rotation is applied. When two or more are applied, the surface is flat, but not oriented correctly.
If I adjust the rotation of the cylinder after generating these results, I can get the orientation of the surface to make sense, but the number are not what you might expect.
For example: cylinder 3 (on the right side), adjusted to have a surface flat to the world space, would need a rotation of about (42.2, 0, 27.8).
Not sure if that's helpful but it is something that increases my confusion.
My code: (refer to graph model for variable names)
Vector3 v = verts[iter];
Vector3 D = globalSurfaceCenter;
Vector3 E = transform.TransformPoint(new Vector3(v.x, surfaceHeight, v.z));
Vector3 H = new Vector3(gsc.x, E.y, gsc.z);
float a = Vector3.Distance(H, D);
float b = Vector3.Distance(H, E);
float i = (a / b) * a;
Vector3 A = H - D;
Vector3 B = H - E;
Vector3 F = ((A + B)) + ((A + B) * i);
Instantiate(greenPrefab, transform).transform.position = H;
Instantiate(bluePrefab, transform).transform.position = E;
//Instantiate(redPrefab, transform).transform.position = transform.TransformPoint(F);
//Instantiate(greenPrefab, transform).transform.position = transform.TransformPoint(A);
//Instantiate(bluePrefab, transform).transform.position = transform.TransformPoint(B);
Some of the variables in my code and in the graphed model may not be necessary in the end, but my hope is it gives you more to work with.
Bear in mind that I am less than proficient in geometry and math in general. Please use Laymans's terms. Thank you!
And thanks again for taking the time to help me.
As a first step, we can calculate the normal of the upper cylinder surface in the cylinder's local coordinate system. Given the world transform of your cylinder transform, this is simply:
localNormal = inverse(transform) * (0, 1, 0, 0)
Using this normal and the cylinder height h, we can define the plane of the upper cylinder in normal form as
dot(localNormal, (x, y, z) - (0, h / 2, 0)) = 0
I am assuming that your cylinder is centered around the origin.
Using this, we can calculate the y-coordinate for any x/z pair as
y = h / 2 - (localNormal.x * x + localNormal.z * z) / localNormal.y

Find collision time given distance and speed

Suppose I have an object A at position x = 0 and object B at position x = 16.
Suppose A have this code:
public class Move : MonoBehaviour
{
float speed = 0.04f;
Update()
{
transform.Translate(speed, 0, 0);
}
}
My question is: how to evaluate how many seconds (precisely) will it take for A to collide with B?
If I apply the formula S = S0 + vt, it won't work correctly, because I don't know how to measure how many frames it will pass in a second to exactly measure what speed is.
First of all you shouldn't do that. Your code is currently framerate-dependent so the object moves faster if you have a higher framerate!
Rather use Time.deltaTime
This property provides the time between the current and previous frame.
to convert your speed from Unity Units / frame into Unity Units / second
transform.Translate(speed * Time.deltaTime, 0, 0);
this means the object now moves with 0.04 Unity Units / second (framerate-independent).
Then I would say the required time in seconds is simply
var distance = Mathf.Abs(transform.position.x - objectB.transform.position.x);
var timeInSeconds = distance / speed;
Though .. this obviously still assumes by "collide" you mean at the same position (at least on the X axis) .. you could also take their widths into account since their surfaces will collide earlier than this ;)
var distance = Mathf.Abs(transform.position.x - objectB.transform.position.x) - (objectAWidth + objectBWidth);
var timeInSeconds = distance / speed;

Procedural structure generation

I have a voxel based game in development right now and I generate my world by using Simplex Noise so far. Now I want to generate some other structures like rivers, cities and other stuff, which can't be easily generated because I split my world (which is practically infinite) into chunks of 64x128x64. I already generated trees (the leaves can grow into neighbouring chunks), by generating the trees for a chunk, plus the trees for the 8 chunks surrounding it, so leaves wouldn't be missing. But if I go into higher dimensions that can get difficult, when I have to calculate one chunk, considering chunks in an radius of 16 other chunks.
Is there a way to do this a better way?
Depending on the desired complexity of the generated structure, you may find it useful to first generate it in a separate array, perhaps even a map (a location-to-contents dictionary, useful in case of high sparseness), and then transfer the structure to the world?
As for natural land features, you may want to google how fractals are used in landscape generation.
I know this thread is old and I suck at explaining, but I'll share my approach.
So for example 5x5x5 trees. What you want is for your noise function to return the same value for an area of 5x5 blocks, so that even outside of the chunk, you can still check if you should generate a tree or not.
// Here the returned value is different for every block
float value = simplexNoise(x * frequency, z * frequency) * amplitude;
// Here it will return the same value for an area of blocks (you should use floorDiv instead of dividing, or you it will get negative coordinates wrong (-3 / 5 should be -1, not 0 like in normal division))
float value = simplexNoise(Math.floorDiv(x, 5) * frequency, Math.floorDiv(z, 5) * frequency) * amplitude;
And now we'll plant a tree. For this we need to check what x y z position this current block is relative to the tree's starting position, so we can know what part of the tree this block is.
if(value > 0.8) { // A certain threshold (checking if tree should be generated at this area)
int startX = Math.floorDiv(x, 5) * 5; // flooring the x value to every 5 units to get the start position
int startZ = Math.floorDiv(z, 5) * 5; // flooring the z value to every 5 units to get the start position
// Getting the starting height of the trunk (middle of the tree , that's why I'm adding 2 to the starting x and starting z), which is 1 block over the grass surface
int startY = height(startX + 2, startZ + 2) + 1;
int relx = x - startX; // block pos relative to starting position
int relz = z - startZ;
for(int j = startY; j < startY + 5; j++) {
int rely = j - startY;
byte tile = tree[relx][rely][relz]; // Get the needing block at this part of the tree
tiles[i][j][k] = tile;
}
}
The tree 3d array here is almost like a "prefab" of the tree, which you can use to know what block to set at the position relative to the starting point. (God I don't know how to explain this, and having english as my fifth language doesn't help me either ;-; feel free to improve my answer or create a new one). I've implemented this in my engine, and it's totally working. The structures can be as big as you want, with no chunk pre loading needed. The one problem with this method is that the trees or structures will we spawned almost within a grid, but this can easily be solved with multiple octaves with different offsets.
So recap
for (int i = 0; i < 64; i++) {
for (int k = 0; k < 64; k++) {
int x = chunkPosToWorldPosX(i); // Get world position
int z = chunkPosToWorldPosZ(k);
// Here the returned value is different for every block
// float value = simplexNoise(x * frequency, z * frequency) * amplitude;
// Here it will return the same value for an area of blocks (you should use floorDiv instead of dividing, or you it will get negative coordinates wrong (-3 / 5 should be -1, not 0 like in normal division))
float value = simplexNoise(Math.floorDiv(x, 5) * frequency, Math.floorDiv(z, 5) * frequency) * amplitude;
if(value > 0.8) { // A certain threshold (checking if tree should be generated at this area)
int startX = Math.floorDiv(x, 5) * 5; // flooring the x value to every 5 units to get the start position
int startZ = Math.floorDiv(z, 5) * 5; // flooring the z value to every 5 units to get the start position
// Getting the starting height of the trunk (middle of the tree , that's why I'm adding 2 to the starting x and starting z), which is 1 block over the grass surface
int startY = height(startX + 2, startZ + 2) + 1;
int relx = x - startX; // block pos relative to starting position
int relz = z - startZ;
for(int j = startY; j < startY + 5; j++) {
int rely = j - startY;
byte tile = tree[relx][rely][relz]; // Get the needing block at this part of the tree
tiles[i][j][k] = tile;
}
}
}
}
So 'i' and 'k' are looping withing the chunk, and 'j' is looping inside the structure. This is pretty much how it should work.
And about the rivers, I personally haven't done it yet, and I'm not sure why you need to set the blocks around the chunk when generating them ( you could just use perlin worms and it would solve problem), but it's pretty much the same idea, and for your cities too.
I read something about this on a book and what they did in these cases was to make a finer division of chunks depending on the application, i.e.: if you are going to grow very big objects, it may be useful to have another separated logic division of, for example, 128x128x128, just for this specific application.
In essence, the data resides is in the same place, you just use different logical divisions.
To be honest, never did any voxel, so don't take my answer too serious, just throwing ideas. By the way, the book is game engine gems 1, they have a gem on voxel engines there.
About rivers, can't you just set a level for water and let rivers autogenerate in mountain-side-mountain ladders? To avoid placing water inside mountain caveats, you could perform a raycast up to check if it's free N blocks up.

How to create an object in a cube in Unity3D?

I have a cube in Unity3D. I know the vectors of its 8 vertices. It is rotated and scaled in 3D around all axes. How can I instantiate an object at run time inside that cube at a random position?
If you know the 8 vertices of your cube, it's easy to randomize an object inside of this cube. Consider the random object to have an x, y and z value in the position of the Transform. Both UnityScript and C# provide a nice Random class which can easily give you a random number between two values. Use this class three times:
Create a random number between the max x value and the min x
value of all 8 vertices.
Create a random number between the max y value and the min y
value of all 8 vertices.
Create a random number between the max z value and the min z
value of all 8 vertices.
Next, create your gameobject which has to be instantiated in this cube, and use the x, y and z value you've calculated from above three steps. That would randomly create your object in the cube.
Note that if your random object has a certain size, it would technically be possible to generate the object randomly on the edge of the cube, thus letting the random object 'stick out' of the cube. To avoid that, make sure to substract half the size of the object from the max values you enter in the randomize function and to add up half the size of the object from the min values you enter in the randomize function.
EDIT: To get your points when the object is rotated, you can use cube.transform.localScale / 2. This will get you the local position of one of the cube's corners. Vector3.Scale(cube.transform.localScale / 2, new Vector3(1,1,-1)) will get you one of the others (different combinations of 1 and -1 there will get you all eight). Then, to find them in world space, use cube.transform.TransformPoint().
If I understand what you're trying to do correctly, I'd probably suggest something like the following.
public class Instantiation : MonoBehaviour {
void Start() {
for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.AddComponent<Rigidbody>();
cube.transform.position = new Vector3(x, y, 0);
}
}
}
}
It will create the GameObject cube (or whatever you desire) at the new transform.position. However instead of it's position being a specific Vector3, you have it as a randomly generated Vector3 from a new method. This method will be created to randomise the numbers for x then y and z within specific boundaries. You then just feed it into the new position.
I hope that makes sense, I'm not a fantastic teacher.
Edit: http://docs.unity3d.com/Documentation/Manual/InstantiatingPrefabs.html this is a good reference for instantiating Prefabs. Your run time instantiated object should be of a prefab.

How does CGPoint Variable work behind the scenes?

I'm not sure how the CGPoint variable that I have created knows how to handle the specific if statement.
For example, I have CGPoint myVelocity; then I have an arbitrary number float maximumVelocity = 100;
Then I execute the following code
if (myVelocity.x > maximumVelocity) {
myVelocity.x = maximumVelocity;
}
else if (myVelocity.x < -maximumVelocity)
{
myVelocity.x = -maximumVelocity;
}
From what I understand, if the first condition is met, which is myVelocity.x > maximumVelocity then the CGPoint variable is set to the maximum, which is the number 100. This is so that my variable never exceeds the arbitrary number. And the other condition is set up so that it doesn't go into the negative..
At least that's what I think.
Now here is the important part of this post.. I'm confused with how the myVelocity variable knows what the that arbitrary number is. For example is it 10? is it 25 the next second or when does it reach 100.
I should also point out that before the if statement is run, I have the following code stored in myVelocity
The following is the code that is stored into 'myVelocity' prior to the if statement executing.
float deceleration = 0.4f;
float sensitivity = 6.0f;
float maximumVelocity = 100;
myVelocity.x = myVelocity.x *deceleration + acceleration.x *sensitivity;
I have recently inquired about code smilar to the latter part of my question, but now I'm curious about the former.
A CGPoint is just a struct with "x" and "y" components. You can think of it as an easier way to pass around a pair of floats.
So your code above would be equivalent to:
float x;
// other stuff
if (x > maximumVelocity) {
x = maximumVelocity;
}
else if (x < -maximumVelocity)
{
x = -maximumVelocity;
}
Now pair that with another variable by using a struct:
struct CGPoint {
float x;
float y;
};
and to access that "x" variable, to either set or read from it, use ".x", like you did in your code sample.
(P.S. CGPoints actually are a pair of CGFloats for reasons that are irrelevant to this post)
GCPoint represent a bidimensional space, ideally storing a velocity in a CGPoint means that you need a velocity vector represented by 2 dimensions, x and y.
In your case i see that you only use 1 dimension, i didnt quite get what your trying to achieve but in your case you can just use a float to store velocity value if it has not a direction.
If you need a 2 dimension velocity you have to check for maximumVelocity by checking the lenght of the vector. In you example your checking only the x dimension, but if the velocity is x=50,y=20000 this is moving pretty fast on the y axis.
ccpLength(<#const CGPoint v#> let you check the lenght of a CGPoint, so you can compare with a float to see if the actual velocity is faster than your maximum, in that case you need to normalize your vector to actually match your maxiumVelocity, you can do this with
ccpMult(v, maximumVelocity/ccpLength(v))