Move game objects on the another game object Unity3D - unity3d

I have this scene in unity with a chessboard and pieces. Each figure and chessboard are models downloaded from asset store. So I want the user to click on the square and click on the figure to move my figure to this square on the chessboard. How can I do this with my game object? Should I define some coordinates of squares clicked by the user? And how can I track where the user clicked?
My scene looks like this:
I had only such scripts for moving figures to defined by me square. An example for a rook:
void OnMouseDown()
{
transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.z + 71);
}

Rather than defining some grid, or rounding to nearest integers, you could simply have a collider on every square.
Each of those squares would be part of a square collision layer. Then you would do the same for all the pieces, allowing for the peice layer to interact with the square layer (so they don't fall through the table)
Then comes the easy part: You just do two raycasts, the first against pieces, to determine what piece the user is trying to move, and the second to determine where they are trying to move it (and move the piece to the center of the square)
This question also might be of some use in figuring out how to select objects.

Related

Precision in onCollisionStart in flame with flutter

I'm attempting to write a bouncing ball game using flame in flutter. To detect collisions the onCollision and onCollisionStart methods are provided. What I had hoped is that onCollisionStart would give a precise location when two objects first hit each other. However, instead it gives a list of positions indicating where the two objects overlap after the first game-tick when this happens (i.e. onCollisionStart is called at the same time as onCollision, but is not called a second time if the same two objects are still colliding on the next tick).
This is illustrated in the attached picture. The collision points are marked with red dots. If the ball were moving downwards, then the ball would have hit the top of the rectangle and so should bounce upwards. However, if the ball were moving horizontally, then its first point of contact would have been the top left corner of the box, and the ball would bounce upwards and to the left.
If I want to work out correct angle that the ball should fly off, then I would need to do some clever calculations to work out the point that the ball first started hitting the other object (those calculations would depend on the precise shape of the other object). Is there some way to work out the point at which the two objects first started colliding? Thanks
What you usually need for this is the normal of the collision, but unfortunately we don't have that for the collision detection system yet.
We do have it in the raytracing system though, so what you could do is send out a ray and see how it will bounce and then just bounce the ball in the same way.
If you don't want to use raytracing I suggest that you calculate the direction of the ball, which you might already have, but if you don't you can just store the last position and subtract it from the current position.
After that you need to find the normals of the edges where the intersection points are.
Let's say the ball direction vector is v, and the two normal vectors are n1 and n2.
Calculate the dot product (this is build in to the vector_math library) of the ball direction vector and each of the normal vectors:
dot1 = v.dot(n1)
dot2 = v.dot(n2)
Compare the results of the dot products:
If dot1 > 0, n1 is facing the ball.
If dot2 > 0, n2 is facing the ball.
After that you can use v.reflect(nx) to get the direction where your ball should be going (where nx is the normal facing the ball).
Hopefully we'll have this built-in to Flame soon!

Unity: Mesh Renderer seems to not fit the Edge perfectly

We are currently trying to lay mesh colliders onto our edges as shown in the pictures. The problem is that the meshes sometimes seem to be 2D instead of 3D (shown in Picture 2 and Picture 3), which makes them unselectable from certain camera-angles. Sometimes the meshes even seem to disappear through some parts of the Edge(Picture 1).
Turning convex on for the colliders makes them way easier to select, but we dont really want to do that because that makes it realy unclear which edge you are selecting right now.
We are creating our meshes through bakeMesh from our previously created Edges as shown below:
LineRenderer lineRenderer = gameEdge.GetComponent<LineRenderer>();
MeshCollider meshCollider = gameEdge.AddComponent<MeshCollider>();
Mesh mesh = new Mesh();
lineRenderer.BakeMesh(mesh, Camera.main, false);
meshCollider.sharedMesh = mesh;
meshCollider.convex = false;
Edit:
We used this https://github.com/mattatz/unity-tubular to generate tube meshes around our edges, working pretty well now!
The mesh generated by the line renderer is actually 2D. I think that your best chance is to update the mesh orientation to face to the camera so that the mesh will always be facing to the camera wherever you are looking from. That way you'll allways be able to click on it.
You have 2 options:
1.- Passing the new camera (with its new position) all the time. This would be in the Update. Be carefull to only use the code that bakes the mesh and not the Mesh mesh = new Mesh() in the update. Because if you create a new mesh in the Update passed some time you'll have an stack overflow error. I recomend if you do this, to make the Mesh mesh; a class variable and start it only in the class initialization (mesh = new Mesh();) so that you use only the created instance to update the mesh all the time, not creating a new one for each update.
2.- If you are concerned about efficiency, you can handle when your camera is moving, so that when it stops moving, you pass in the new camera along with its position. For this you would need to handle the camera OnStopMoving event yourself to pass the new camera in, so whenever the Main camera stops moving, the mesh will always be facing it.
This makes sense because its easier for the user to click on things while stopped, so it can be presumed that the user will try to click on the lines while not moving
There is one third option I did not mention due to feasability, that is wrapping your line renderer with primitive colliders with the points of your line as an starting point for the procedural collider wrapping logic. However you would need to code all that out, which might take a while.
On the other hand making it a convex collider as far as I checked is not feasable, as the behaviour and shape of the collider itself changes on the mesh cooking by the MeshRenderer component. Check if this might be of help.

How to find the center in unity 2d?

I want to create 2d game. The game is similar to the Scale Puzzle. I've already created nearly all the functionality. Only the last remains.
.
This is example.
And that's how I draw shapes.
.
I click inside a white square, and after 1 seconds a square is drawn regardless of the position of the ball. (x,y).
Square is created programmatically, and it is added to the parent element "SquaresList" with name New Game Object.
How can i do, so that the violet field becomes larger, and in the middle of the screen.
I made it so that for every 3 clicks, "SquaresList" increases Scale by 0.25f, and get negative position of the ball. Example:
SquareList.transform.position = new Vector2(-ball.pos.x, -ball.pos.y)
This does not work correctly.
What options can be? (intersections, find the max/min point, math formulas) ?
Hi NoName :) Your method
SquareList.transform.position = new Vector2(-ball.pos.x, -ball.pos.y)
would work perfectly if your object does not inherit other objects and there positions. To fix this make sure that you reset the position of all other game objects that you use as containers.

Unity - atoms - how do I get two atoms to stick to each other and move as one GameObject?

I am making a chemistry game in Unity where each atom is represented as a 3D GameObject sphere. I want the user to be able to drag an atom around and if it enters some set radius of another item that it can combine with, the two atoms "stick" together (or become "suctioned" together) and become one entity that can be dragged around and interacted with.
How it looks now:
How I want it to look after interaction:
Now comes the hard part trying to figure out how to do this. First, I attached a script to the Oxygen atom (red sphere). I want to see if the Hydrogen atom entered some radius. If it does, I create a new GameObject, make both the oxygen and hydrogen children of that object, give the new GameObject a rigidbody and collider, and turn off the rigidbodies of the children. So the problem with this is that once I do that, both spheres fall through the ground. Also, they still remain as separate spheres and don't look "stuck" together. If I drag the red sphere around, the white doesn't follow and vice versa.
Any help would be greatly appreciated.
void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.name == "HydrogenPrefab(Clone)")
{
Debug.Log("Hydrogen entered");
GameObject HOCombo = new GameObject();
//put both atoms under the same parent
collision.gameObject.transform.parent = HOCombo.transform;
this.transform.parent = HOCombo.transform;
//remove the rigidbodies
this.GetComponent<Rigidbody>().isKinematic = true;
collision.gameObject.GetComponent<Rigidbody>().isKinematic = true;
// make the parent a rigidbody;
HOCombo.AddComponent<Rigidbody>();
HOCombo.AddComponent<MeshCollider>();
}
}
It looks like a Fixed Joint could suits you.
Also make sure that you get the right object when you Raycast it. You'll probably need to move the children to a layer ignored by your raycast or use RaycastAll to get all hits (not just the first one) and manage to find the desired parent from there.

How do I center a mesh on a GameObject?

I have a 2D game where the users can create cars by clicking on the screen to add vertices and then drag these around as they see fit. These vertices are then used to draw a mesh. Users can also add wheels to the vertices (1 per vertex).
In the game there is also an option to have the computer generate a random car, which it does by creating eight vertices at random points inside of a unit circle.
These cars are stored and it is possible for the user to load them and re-use them. The two pictures below show a square button with a computer generated car (The green one with red wheels) which sits inside of the square as intended, and a user generated car (The white one with pink wheels) which sits outside of the square.
I know that this is because the mesh of the computer generated one draws triangles from Vector3.zero which is the center of the object, while the user created one only triangles between the vertices, which aren't necessarily placed around the center of the object (As in this example where they are all placed above and to the right of the center).
How would I go about centering the mesh of the user created car?
I could perhaps calculate the center of the mesh and then subtract that from the position of all the vertices. Or I could subtract that position from the position of the GameObject that holds the mesh when presenting it in the gui. Or are there better alternative solutions?
Using Mesh.Bounds
Transform car;
Bounds carBounds = car.GetComponent<MeshFilter>().mesh.bounds;
Vector3 whereYouWantMe;
Vector3 offset = car.transform.position - car.transform.TransformPoint(carBounds.center);
car.transform.position = whereYouWantMe + offset;
This will also give you access to a bunch of cool fields like center min max and size