The question is answered, right answer was accepted
Can someone help me with vector3 math?
Hey all,
I've created a good c# script for Instantiating objects based on an auto-generated grid. What I am trying to do is instantiate the object at a point other than the center of the shape (its a wall. I want to place a wall with the bottom of the wall centered on the snap point).
I've tried adding or subtracting to the Vector3 but it doesn't seem to do anything. Here is my code so far:
public class clickGrid : MonoBehaviour
{
private Grid grid;
public GameObject wall;
private void Awake()
{
grid = FindObjectOfType<Grid>();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit hitInfo;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hitInfo))
{
gridDebug(hitInfo.point);
}
}
}
private void gridDebug(Vector3 clickPoint)
{
var finalPosition = grid.GetNearestPointOnGrid(clickPoint);
finalPosition.Set(finalPosition.x, finalPosition.y - 4, finalPosition.z);
Instantiate(wall, finalPosition, transform.rotation);
}
}
For reference, the wall is 8 units high, I got my "- 4" from 8/2.
Also, next im trying to make a sims-like construction function where you click and drag along the grid and it creates a series of connected walls. I don't really know where to start with that so some guidance would be appreciated :)
Answer by streeetwalker · Sep 15, 2020 at 09:02 AM
@Gustard, first of all, up is in the +y direction, so it would seem that you want to add 4 and not subtract 4 to move the bottom up to 0 (or what ever value is the grid position).
You could make the whole affair easier by putting your wall in an empty game object and offset it there, in your prefab. Then everything is easy peasy
To drag objects around on the grid, one way to do it is create a plane at the location and orientation of your gird position, the cast a ray to get the mouse position on the plane and uses that to drag your walls and what not:
void OnMouseDrag() {
// the following sample code ensures that the
// drag location calculated is co-planar with your grid
//
// create a plane oriented with your grid, assuming the grid is in
// the xz plane
m_Plane = new Plane( Vector3.up, grid.transform.position );
//
// hold the result of the hit distance on the plane
float cameraDistance = 0.0f;
//
Ray ray = cam.ScreenPointToRay( Input.mousePositon );
//
// cast the ray from the mouse location on the screen to our plane
if( m_Plane.Raycast( ray, out cameraDistance ) ) {
dragLoc = ray.GetPoint( cameraDistance );
}
// you can now use dragLoc to position any objects you want to drag around on the gird.
Nice and simple with the walls. Kind of embarrassed that i didn't think of that :P
as for the click and drag, I think you misunderstood my question. I am hoping to click on one point and drag my mouse down the gridline to make multiple walls in a line. Im assu$$anonymous$$g itll use raycasting, dragLoc, and planes still. But would it be easier to create an array of walls and compare it back to the dragLoc increase or decrease in position, or would it be easier to instantiate?
$$anonymous$$y biggest concern is how do you make it only occur while the bool Get$$anonymous$$ouseButtonDown(0) is true? I tried to do a while statement, but my unity editor froze and crashed every time I clicked the mouse.
@Gustard, thanks for the clarification. So correct me if I understand now or not. As you drag, you'd like to start laying down walls?
It is often a good strategy to move the processor load up front, saving the load when you place your objects on the screen. This is the idea behind Object Pooling. Though what it seems you want to do is not quite the same thing.
So you could put all the walls you will need into an array or list structure when your game starts and hide/disable them until such time that you place them on the screen. That will save the processor from instantiating them at the time you place them. There is nothing wrong with that and may be a good idea for what I think you want to do.
However, in my conception, the issue of having an array of walls or instantiating them at the time you drag doesn't really matter when it comes to solving the problem of how and where to place them while you drag, which seems to me to be a fairly complex problem. I'm sure there are many ways to implement a system that solves that, and perhaps that are better than the ideas I have.
One of the problems of where to place the walls is their orientation. Are the walls going to be collinear with the drag direction? Can they be place at angles as you drag? Are the walls all straight? (if not then you'll need to start looking at how to do curves). You may need to alter your conception of dragging to place the walls if they are not in line with the direction of the drag, because how do you deter$$anonymous$$e if you are creating a corner while dragging? You wrote about a grid, but it isn't clear to me now if you meant the walls will all be aligned with the directions of the grid or not - it certainly is easier if they are.
One very easy way to solve the problem is just place one wall and stretch it as far as you drag. That is very easy to do with the code I outlined in my answer.
I think an easier solution rather than dragging is to click, creating points on a spline. You can use simple division and rounding/floor/ceiling functions to ensure that no matter where on the grid your user clicks, the potential wall position is locked to the intersections on the grid
(You can use the same math while dragging to do the same thing).
Using that idea, you just keep track of the previous click and current click location translated to the grid, and fill in walls in between. Again, you could do this while dragging, it's just simpler to click around (I think! If I think more, maybe I change my $$anonymous$$d!).
Interesting and challenging problem! I'd need you to address some of these issues before I could help further.
Simple answer to your points, the walls will always have to be in line with each other.
I want to be able to make walls along the x-axis, the z-axis and at a 45 degree angle on the xz plane. The idea is that they make one section of wall at a time. Click where you want the start of the wall and drag to create wall segments as you go until you get to the end of that wall. If you go too far and want to delete segments, you just drag the mouse backwards and it'll delete segments as you back up. When you want to change direction, you need to create a new wall.
The reason i want wall segments is because I plan on implementing a bunch of material and cost systems to the game which will be based off of whole integers. the segments of the walls are in 1 foot increments to make things easier (go imperial system! - not really, we should really switch to metric in the US).
In conclusion, what i need to do is click to start creating walls and, when i pass each grid point in line with the 1st, create another wall segment and then another wall segment as i move down the line until i release the mouse button.
Follow this Question
Related Questions
I got Some Error about how to Transform Postiton Enemy where one point can spawn 2 enemies. 1 Answer
local scale not working? 2 Answers
[C#] Object not spawning where it should? 0 Answers
Change color of object with C# 1 Answer
Gameobject array 0 Answers