Unity. "Stretching" of an object instantiated from prefab - c#

I am trying to spawn obstacles on the road. To do so, I generate a road by spawning its parts, and each part itself spawns several obstacles in bounds of themselves. But some prefabs after being instantiated got strange "stretching" effects. I don't know how to explain it, so I recorded a small video link. Also, if I spawn that same object by "drag n drop" to the scene, this bug never appears.
This how I spawn obstacles:
Vector3 size = GetComponent<Renderer>().bounds.size;
Vector3 pos = new Vector3(Random.Range(-0.3f*size.x,0.3f*size.x), 30, Random.Range(-0.3f*size.z,0.3f*size.z));
Debug.Log(pos + transform.position +"");
GameObject newBottle = Instantiate(minus_prefabs[Random.Range(0, minus_prefabs.Length)], new Vector3(transform.position.x+pos.x,transform.position.y + pos.y,transform.position.z+pos.z), Quaternion.Euler(0, 0, 0));
newBottle.transform.SetParent(transform);

This happens because the parent GameObject of the model has diffrent sizes on X, Y and Z. This results in some weird stretching. Try going in your prefab and set the scale of your main GameObject to X:1 Y:1 Z:1 for example.
Also see: https://www.unity3dtips.com/how-to-fix-objects-stretching-when-rotated/#:~:text=Cause%20of%20the%20object%20stretching,0.01%2C%200.002%2C%200.004%E2%80%9D.
This also happens to me all the Time. Thankfully its easy to fix!
EDIT: When you instantiate the prefab, also make sure it has the same sizes on every axis.

As a general rule, whenever possible, don't use any Scale other than 1,1,1 unless you need to and it should be on a leaf node of the hierarchy or prefab not a parent node. It will make things go much smoother. If you need to change the size of a mesh (because the noob modeler didn't know how to follow the life-sized scaling metrics in their modeling program, or you just want it smaller or larger), you can do that in the Import settings on the FBX.

Related

prefab gameobject is becoming skewed when I am modifying transform.up

in my 2d unity game, i am randomly instantiating zombies that I want to face their mouth towards the center where there is it's target because the bullets come out of their mouth which need to face the center. the zombie is a prefab and I have this code on it:
transform.up = -(kids.transform.position - transform.position); it is pretty much working and there are no errors except, randomly, sometimes it becomes really skewed and squished in weird ways. here is a picture of what it looks like when it is skewed:
how can I make it not get skewed? thanks.
Probably you scaled it or one of its parent Transforms uniformly. Possible solution: create a parent which is unscaled and do the rotations there. Maybe have a script to follow some other transform, like settings its position in an update, if need be. A child Transform of the unscaled Transform, which you rotate, can then still be ununiformly scaled.

Destroying object at raycast 2D causes unrelated object to be destroyed

In my game the user can spawn instantiated versions of 2 prefabs with mouse clicks: tiles and balls. The balls can be spawned over the tiles.
The user can also erase objects which have been spawned. This is achieved by placing the following code in a if(Input.GetMouseButtonDown(0))) block of the update method:
if (Input.GetMouseButtonDown(0))
{
Vector3 mousePos = Input.mousePosition;
mousePos.z = canvas.transform.position.z;
Vector3 mousePosTrans = Camera.main.ScreenToWorldPoint(mousePos);
RaycastHit2D rayHit = Physics2D.Raycast(mousePosTrans, Vector2.zero);
if (eraserSelected)
{
Destroy(rayHit.collider.gameObject);
}
}
The objects intended for deletion are being deleted, but the problem is that other unrelated and distant objects are sometimes also simultaneously deleted. For example, if I spawn 2 squares and a ball on each square, then delete the first ball, when I go to delete the first square the second ball is simultaneously deleted. Sometimes when an object is deleted another object is simultaneously "un-deleted"!
Objects are spawned with the following code:
TileOrBall obj = (TileOrBall) Instantiate(tileOrBall, pos, Quaternion.identity);
obj.transform.SetParent(canvas.transform);
where TileOrBall is the class of the objects being spawned and tileOrBall is a reference to one of the two prefabs from this class.
So is there something wrong with the approach I'm taking to object spawning or destruction? How can I solve the simultaneous deletion (and sometimes resurrection) of distinct objects when trying to destroy an instance of these objects?
EDIT:
Adding link to zip file of project:
https://drive.google.com/open?id=0B28_MgFRWv97OWxfNE96LXcxZHc
To replicate the issue, click on the square in the side bar and "paint" squares in the grid wherever, then click on the ball in the side bar and "paint" over the squares that have been placed. Finally, click on the eraser icon and start deleting objects by clicking on them. You will see that objects you did not click on are deleted, and you may even see that objects are resurrected when you try deleting objects.
Thanks!
Found few problems in the Project.
1.When you do Destroy(unitAtMouse);, you are not deleting the GameObject from the raycast. You are ONLY deleting the Unit script that is attached to that GameObject.
Because this deletion failed, you will have multiple multiple Square GameObjects in one spot. That makes it harder to delete later on since you have to click delete multiple times until the last Square GameObjects is deleted.
To fix this, replace Destroy(unitAtMouse); with Destroy(unitAtMouse.gameObject);.
2.It is good to have the GameObject you are instantiating to be GameObject instead of script. For example public Unit selectedObject; should be public GameObject selectedObject;
3.Set eraserSelected to false when the square or circle in the side bar is clicked. This fixes problems that even user selects the square while again while in eraserSelected mode, they can delete or even create new square. You want to disable eraserSelected if square or circle in the side bar is clicked. In another word, if setSelectedObject is called.
4.The Erase Button should be under the panel like the other buttons too. Otherwise, it will go missing under some screen resolution.
5.Fixed enum to use the actual enum instead of enum.string.
6.Fix a problem that made the ball invisible which makes it look like it was deleted. What happens is that the ball is sent behind the square. Fixed this by making the ball sortingOrder to the 1 and the square sortingOrder to be 0.
Alternatively, building on #Programmer's response you could create a new script, say DeletableObject, that can be completely empty for the time being and attach this to the ball and square prefabs and any future prefabs you may have. Then in the suggested code above, change:
if (rayHit.collider.CompareTag("ball"))
to
if(rayHit.collider.GetComponent<DeletableObject>())
That way you can attach the script to any future prefabs you make to be able to delete them.
On a side note, if you're adding / deleting lots of objects and performance becomes an issue, look into Object Pooling. In fact, you should look into it anyway as it's a good habit to get into.

Unity game object not in correct position

I'm making a unity 3D game, part of the game allows the player to get into a car and drive it.
Inside the car I have put a "seat" GameObject whose position and rotation is used to determine where the player will sit.
When I want the player to sit in the car, I make the car the players parent, then set the player transform position and rotation to that of the seat.
Here is the C# code
// make player's parent the same as the seats parent (which is the car)
transform.parent = seat.transform.parent;
// put player in the exact position and rotation as the seat
animator.transform.position = transform.position = seat.transform.position;
animator.transform.rotation = transform.rotation = seat.transform.rotation;
animator.transform.localPosition = transform.localPosition = seat.transform.localPosition;
animator.transform.localRotation = transform.localRotation = seat.transform.localRotation;
This seems like it should work, but what ends up happenning is that for some reason the player does not end up perfectly in the seat, but some short distance away from it, and also the players rotation doesnt match the seat, instead ends up slightly off. So the player looks like he is not really in the seat but floating near it, and turned around in some other direction.
Anybody knows what I'm doing wrong?
position specifies an object's location in the world. If you take two objects and assign the same position, then they will both be in the same place.
localPosition specifies an object's location relative to its parent. If you take two objects and assign the same localPosition, the outcome will depend on the position of each object's parent. If they have different parents, different scaling, or different rotation, they may end up in different places.
Roughly the same idea applies to rotation and localRotation.
You seem to have confused the relationship between world-space and local-space coordinates. It's very important to understand the difference, and how they relate to the scene hierarchy.
If you want to put both objects in the same place, this should suffice:
transform.position = seat.transform.position;
transform.rotation = seat.transform.rotation;
If you want the object to move with the car, afterward, you could also reassign its parent:
transform.parent = seat.transform.parent;
Check your player object's pivot point.It might not be on position you expect.If it is not, try to make it point where you want by dragging your model.

Create random falling objects in unity C#

i am starting to learn unity3d and am developing a 2d game but need some help at the main menu. I have a coin texture which i would like to spawn multiple times above the screen and fall down to create a falling coin texture. Spawn points should be random and entities should be destroyed after falling off the screen, but i have no idea how to do it. Any help will be greatly appreciated. Thank you
Image Upload: http://imgur.com/ol4vkr2
I will give you some starting points to done your task. You can read about`
RigidBody(RigidBody2D)
Collider(Collider2D)
MonoBehaviour Callbacks for example OnTriggerEnter(OnTriggerEnter2D) or OnCollisionEnter(OnCollisionEnter2D)
For randomness you can read about Random class and his methods like Random.randomInsideUnitCircle.
If I were you I'd start by reading up on Unity's particle system. By setting up some parameters in the editor it can exactly do what you want and very efficiently as well.
Some important parameters to consider:
Emitter shape: You want this to be a rectangle in your case, positioned at the top of the scene.
Initial velocity: You want this to be something like (0,-2,0) for downwards falling coins.
Emission rate: Determines how fast new coins will be produced.
Particle shape: Either a coin texture or a coin mesh or whatever you want.
Starting lifetime: The duration of each coin. The coin will be properly destroyed after this time.
The particle system will automatically choose random points within the emitter shape.

Weird behavior when rotating 2D GameObject with hinged children in Unity

For more than two days now I am struggling with this seemingly impossible problem: I have a composite GameObject (one parent, 10 children), each one hinged to at least another with angle limits and player-controlled motors. Moves perfectly as I wish.
Now I want to be able to flip it. After a while and many trials,rotation seems the best way in order to keep the angles (inverting localSpace does not respect them):
Vector3 rotPoint = new Vector3 (ParentGameObject.transform.position.x, myY, myZ);
ParentGameObject.transform.rotateAround (rotPoint, Vector3.up, 180.0f);
BUT, if the parent rotates as asked (180 degrees around its Y axis), every child flips but not around the same axis, rather around their own rotation center. This gives ridiculous results as hinges try to get back to the desired position. How could I fix this?
Many many thanks in advance...
In the end I figured out the problem. My problem had no valuable solution.
We can rotate the transform around the Y axis even in 2D, but NOT the rigidbody2D, which in the same object will invariably cause serious problems.
This is maybe one remaining inconsistency into Unity5's implementation of 2D.
I had to flip using localScale inversion and programmatically updated positions and rotations.
It sounds like the child GameObjects are rotating around their own pivots instead of the parents. I haven't got Unity installed at the moment to test this, but if you add an empty GameObject as a child of your parent (and with the same pivot point), then make all your other GameObjects a child of this, it should work.
You should not move or rotate a rigidbody if you don't have to. That will mess up the underlying physics calculations and physics engines won't be happy about it. Instead, you have other ways to interact with them
Apply force, torque
Apply acceleration, angular acceleration
Change speed, angular speed
If you have to move/rotate the object, you should also update positions, rotations, speeds, angular speeds of all of your hinged objects. That would not be easy. Give some more details if you unable to solve.

Categories

Resources