Unity Cube gameobject Transform position not changing - c#

I want to transform the position of the bottom wall. The bottom wall is a 3D cube used for collision. Here is a picture of the cube and properties.
On the right of the image you can see a property bar called transform. I want to access that through a script and change the position. Here is the code I am trying to do that with.
void Start () {
GameObject bottomWall = GameObject.Find("Bottom");
Bottom bottomScript = bottomWall.GetComponent<Bottom>();
bottomScript.wallPos.y = -Camera.main.orthographicSize * 1000;
bottomWall.transform.position.Set(1000, 100, 1000);
bottomWall.GetComponent<Transform>().position.Set(100, 100, 100);
}
Nothing happens when I do this. I can't seem to do it, any help with this is extremely appreciated.

Transform.position returns a copy of a Vector3 instead of the reference. So modifying the copy won't affect the original Vector3 position.
Replace bottomWall.transform.position.Set(1000, 100, 1000);
with
bottomWall.transform.position = new Vector3(100, 100, 100);
Not related to your problem:
Since Bottom is a child of Walls, it is better to use Walls/Button in your Find function as that will tell Unity to look for the Bottom GameObject only under Walls hierarchy. This is fast when you have too many GameObjects in the scene.
So use GameObject bottomWall = GameObject.Find("Walls/Bottom");

Is it the child of another Game Object? Could try gameObject.transform.localPosition

Related

Draw a line from object to where camera is facing in Unity

I am starting out to create a minigolf game in Unity. I want to aim by draggin the screen with my mouse which rotates the camera around the ball. Basically I want to draw an aim line (line renderer or any other good method) from the ball to where the camera is pointing. Right now I just draw the line I want from beginning, but in the end I want it to rotate with the camera like the red line in picture below.
The code for rotating the camera is working great, where previousCameraPosition is set when I click the mouse and Rotate() is called when mouse button is being held down:
private void Rotate()
{
// Get the movement vector
Vector3 cameraMoveDirection = previousCameraPosition - mainCamera.ScreenToViewportPoint(Input.mousePosition);
// Rotate around the ball
mainCamera.transform.position = ballObject.transform.position;
// Make the rotations
mainCamera.transform.Rotate(new Vector3(1, 0, 0), cameraMoveDirection.y * 360);
mainCamera.transform.Rotate(new Vector3(0, 1, 0), -cameraMoveDirection.x * 360, Space.World);
// Set the camera a certain amount away from the ball
mainCamera.transform.Translate(new Vector3(0, 0, -ballObject.transform.position.z*2.5f));
// Update the previousCameraPosition during the movement
previousCameraPosition = mainCamera.ScreenToViewportPoint(Input.mousePosition);
}
I tried to create a helper object which was set to rotate exactly like the camera which made the line exactly like I wanted it, except it was backwards (180 degrees wrong, facing into the camera instead of away) and it was 1 unit long since it was normalized. I am stuck on this for far too long now, any help or guidance would be very appreciated.
First you can simply use the camera's forward vector without having to deal with any Quaternion rotation at all:
var forward = Camera.main.transform.forward;
Then what you actually seem to want is not exactly this direction but rather map it onto a flat XZ plane:
var actualForward = Vector3.ProjectOnPlane(forward, Vector3.up).Normalized;
then finally you can use this direction to draw your line e.g. between the points
var startPoint = ball.position;
var endpoint = startPoint + actualForward * lineLength;

How to change location of spawned instances without ruining instances' positions relative to each other?

Currently I have code that spawns a bunch of Sphere mesh instances into the shape of a Cube (by spawning one Sphere per a Cube mesh's vertex), like this:
public CubeMesh CubeMesh;
mesh = CubeMesh.GetComponent<MeshFilter>().mesh;
public GameObject spherePrefab;
public GameObject[] spheres;
public List<TransformData> matrices1 = new List<TransformData>();
Vector3[] matrices1pos = new Vector3[24]; //cube has 24 vertices
spheres = new GameObject[mesh.vertexCount];
for (int i = 0; i < mesh.vertexCount; i++)
{
matrices1pos[i] = matrices1[i].position;
spheres[i] = Instantiate(spherePrefab, matrices1[i].position, Quaternion.identity);
}
So this works to have a bunch of sphere instances creating the shape of a Cube when you hit play.
What I'm now trying to do is move the spheres that make up this Cube shape, so that this 'Cube' shape can follow the player, without ruining the shape.
When I manipulate the Transform data of the GameObject that the above script runs on, the sphere instances don't change their position at all. They do not care what the position of the GameObject is.
I also tried parenting it to another object and moving the Parent's position, but the sphere instance positions do not care about the parent's position either.
What would be the correct approach here, for moving the 'Cube' shape around without changing the actual spheres' positions relative to one another? It looks like this (https://i.imgur.com/aGi4cOS.png), for reference.
Edit:
doing this line instead:
spheres[i] = Instantiate(spherePrefab, matrices1[i].position, Quaternion.identity, transform);
allows me to manipulate the rotation and scale of the sphere instances, but not the position
Edit2: Solved! see answer below
I figured it out! I needed to use localPosition. Thank you! =]
spheres[i].transform.SetParent(GO2.transform);
spheres[i].transform.localPosition = Vector3.Lerp(matrices1pos[i], matrices2[i].position, t);

How to drop a box to the mouse position?

I am trying to learn unity, and made my first own game and stucked at the beginning. The first idea was to drop a box (cube) to the mouse position. There are many videos and posts about getting the mouse position, and i tried to use them. My problem is, the mouse position i got is the camera's position, instead of the plane.
As you can see, it is kinda works, but it isn't fall to the plane.
https://prnt.sc/lmrmcl
My code:
void Update()
{
Wall();
}
void Wall()
{
if (Input.GetMouseButtonDown(0))
{
if (Input.GetMouseButtonDown(0))
{
wall = GameObject.CreatePrimitive(PrimitiveType.Cube);
Rigidbody wallsRigidbody = wall.AddComponent<Rigidbody>();
wall.transform.localScale = new Vector3(0.6f, 0.6f, 0.6f);
wallsRigidbody.mass = 1f;
wallsRigidbody.angularDrag = 0.05f;
wallsRigidbody.useGravity = true;
wallsRigidbody.constraints = RigidbodyConstraints.FreezeRotation;
wall.transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
Debug.Log(Camera.main.ScreenToWorldPoint(Input.mousePosition));
BoxCollider wallsCollider = wall.AddComponent<BoxCollider>();
wallsCollider.size = new Vector3(1f, 1f, 1f);
}
}
How should i change my code to get the right position?
This isn't a direct answer to your question, but I'm hoping it'll still get you where you need to go.
Prefabs are your friends! I'd highly recommend leveraging them here instead of constructing a cube directly in code.
But first, make sure everything else is set up right. Go ahead and construct a cube by hand in the Editor and make sure that when you hit Play, it falls as you expect. It should, provided it has a Rigidbody, collider, and you have gravity enabled (true by default).
If that works, drag that cube from your Hierarchy view into a folder in the Project view. This creates a prefab. You can now delete the cube from the Hierarchy view.
Update your script to have a public GameObject field, e.g.
public GameObject cubeToCreate;
Then, in the Inspector pane for whatever gameobject has that script attached, you should get a new field, "Cube To Create". Drag your prefab cube into that slot.
Lastly...update your code to wall = Instantiate(cubeToCreate). You'll still need to update the position, but you should be able to drop the rest of the initialization logic you have above, e.g. setting mass and drag.
As for the actual problem, the first thing that concerns me is how do you plan on turning a 2d mouse click into a 3d point? For the axis going "into" the screen...how should the game determine the value for that?
Camera.main.ScreenToWorldPoint accepts a Vector3, but you're passing it a Vector2 (Input.mousePosition, which gets converted to a z=0 Vector3), so the point is 0 units from the camera -- so in a plane that intersects with the camera.
I haven't done this, but I think you'll need to do raycasting of some sort. Maybe create an invisible 2d plane with a collider on it, and cast a physics ray from the camera, and wherever it hits that plane, that's the point where you want to create your cube. This post has a couple hints, though it's geared toward 2D. That might all be overkill, too -- if you create a new Vector3 and initialize it with your mouse position, you can set the z coordinate to whatever you want, but then your cube creation will be in terms of distance from the camera, which is not the best idea.
Hope this helps.

creating a 2d rectangle and applying a texture to it

I want to create a colored rectangle, my normal approach would be to create a sprite of a rectangle in the desired size, import it to unity, attach it to a game object, then attach things like physics, collision control and what not.
However, I would like to create a rectangle of random size, then give it a texture. I can't do it the old way, cause then I would have to create several thousands sprites then take a random one.
How can I create a 2d rectangle, of random size, without using any sprite?
Honestly, I don't know if this question makes sense, I might be thinking of it all wrong, I just need to know what approach I should use, I am completely at a loss here.
You could instantiate a cube, as since it's a 2D environment cubes render as rectangles unless rotated. The simplest way is to make a prefab of the cube you want and then instantiate it, à la Instantiate(myCube, new Vector3(0, 0), Quaternion.Euler(0, 0, 0), myParent);.
You could also attempt to make a primitive cube and then assign its properties manually, though this is very convoluted. I'm away from home right now so it's untested, but the following method should return a cube out of a position, scale, and a color (but can be edited to accept a material):
GameObject NewCube(Vector3 pos, Vector3 scale, Color color) {
GameObject cubePrototype = GameObject.CreatePrimitive(PrimitiveType.Cube);
cubePrototype.transform.position = pos;
cubePrototype.transform.localScale = scale;
Material materialPrototype = new Material(Shader.Find("Unlit/Color"));
materialPrototype.color = color;
Renderer cubeRenderer = new Renderer(cubePrototype.GetComponent<Renderer>());
cubeRenderer.material = materialPrototype;
return cubePrototype;
}
In your own case, simply pass three random numbers for the scale argument.
The way to go about this is to add a sprite to your project then attach a script to that sprite that produces two random numbers one for the length and then one for the width.
void Awake(){
Vector3 scale = new Vector3( width, height, 1f );
}

Rotate and transform connected rigid bodies in unity3d

I want to move connected rigid bodies as in image example, one of them needs to rotate around a point. Then using ground check I want to rotate it back to line
I tried using hinge joint 2d, using angle limits, but can not control rotating angle.
How can I achieve this effect? thanks.
Edit:
Tagged both rigidbodies as fixed angle and then applied rotation to upper object
void Update () {
if(Input.GetKeyDown(KeyCode.F)){
zRotation += 45;
myGameObject.transform.eulerAngles = new Vector3(myGameObject.transform.rotation.x, myGameObject.transform.rotation.y, zRotation);
}
How can I achieve this effect?
Point to the object then rotate it.
First you want to find the GameObject.
GameObject g = GameObject.Find("Object Name");
Save the original rotation so you can return to it.
Quaternion originalPos = g.transform.rotation;
Then rotate it to your liking.
g.transform.rotation = new Quaternion(x,y,z,w);
In addition you could use iTween to smoothen out the rotation.

Categories