When the sphere is a child, it inherits the scale of its parent. The spheres always become the ellipsoids. Is there a way to set the radius of that sphere to be a certain number no matter what its parent's scales are?
If none of the ancestors are rotated, there's a simple solution:
Set the local scale to be the reciprocol of the parent's lossyScale. Putting it in LateUpdate will guarantee that its scale is set after any of its ancestors' Update methods change its scale. If the ancestors' scales change in any of their LateUpdates, you might want to look into Script Execution Order Settings to set the sphere's script to execute last.
For instance:
public void LateUpdate(){
Vector3 parentScale = transform.parent.lossyScale;
transform.localScale = new Vector3(1f/parentScale.x, 1f/parentScale.y,
1f/parentScale.z);
}
Related
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.
I am trying to position my gun the way most fps games position it,
for example like this:
But I'm having a problem when I try to position and rotate it with the player. The gun doesn't rotate well and doesn't have the same position always.
Is there a way to keep a gun in the same position and make it rotate well with the player?
But my main problem is the position of the gun i need it to stay in one place like in every fps, when i start the game and pick a gun it spawn in diffrent location on the screen Because of the rotation.
Here's is the code that I am trying to use:
GameObject temp = GameObject.Find(gameObject.name);
playerGuns[keyPress] = Instantiate(temp, Player.transform.position
+ new Vector3(-2f, 3f, 4f), Quaternion.identity) as GameObject;
playerGuns[keyPress].name = gameObject.name;
playerGuns[keyPress].tag = gameObject.tag;
playerGuns[keyPress].transform.parent = Player.transform;
playerGuns[keyPress].transform.rotation.SetLookRotation(Player.transform.position);
Alright here is the answer I promised:
First issue was with how you were setting your rotation, SetLookRotation takes in 2 parameters, Vector3 view, and Vector3 up the second is defaulted to Vector3.up. You were passing in the player.transform.position, for the "view" which is the direction you want transform to look in. Think of it like this, if I am far east facing west, my weapon will face east... (That is assuming the SetLookRotation normalizes it.) this is because my actual position is east, from some arbitrary origin. Something you could have used would have been player.transform.forward.
To spawn an object and have it have the same relative rotation and and position you can use Instantiate like you have in your original code. There are Several versions of instantiate.
In the comments I said to give yourself an offsetPosition and a eulerAngle, but this can be quite troublesome if you have multiple weapons. I mentioned I would give a recommendation for how I would set this up for multiple weapons... So here yea go.
Scriptable Objects,
In Unity you can create this objects to store information about a particular object, so for example a "Weapon" object can look like this:
using UnityEngine;
using System.Collections;
[CreateAssetMenu(fileName = "New Weapon", menuName = "Weapon")]
public class WeaponObject : ScriptableObject {
public string objectName = "New Weapon";
public Vector3 offSetPosition;
public Vector3 startOffsetRotation;
public float fireRate;
// Using a gameObject to store the weapon model so you can technical
// store the firing point.
public GameObject weaponModel;
}
You can create a new object now by right-clicking in your asset directory and going to create->weapon. Once you have done this you can rename the object it made, and the inspector will show all the public fields for this object you can modify.
With this you can create multiple weapons, and store their data in like a WeaponManager, that spawns every weapon. with something like:
WeaponObject weapon = WeaponManager.getWeapon(keyPress);
playerGuns[keyPress] = Instantiate(weapon.weaponModel, Player.transform.position + weapon.offsetPosition, Quaternion.identity) as GameObject;
playerGuns[keyPress].name = weapon.objectName;
playerGuns[keyPress].transform.parent = Player.transform;
playerGuns[keyPress].transform.eulerAngles = weapon.startOffsetRotation;
if(player.weaponScript != null) {
// we can have a single script for all of our weapons, and the WeaponObject
// will control its firerate, which projectiles it fires, etc.
player.weaponScript.setWeapon(weapon);
}
playerGuns[keyPress].transform.parent = Player.transform;
This line might be causing a problem. If you are parenting your gun to the players transform then it will follow the player. But it sounds like you want it to follow the camera?
try:
playerGuns[keyPress].transform.parent = Camera.main.transform;
Here is a useful answer provided by reddit user Mathias9807:
Many games will clear the depth buffer before drawing the gun model.
This will prevent the gun model from clipping through geometry but it
can look a bit weird when standing near a wall:
If you just want to render an object sticking to the camera you should
just get rid of the view matrix (Assuming you're using model-, view-
and projection matrices).
Explanation: Normally when you are using a view matrix (the camera matrix),the objects in the scene are being translated relative to the magnitude of the cameras position vector, and rotating by its yaw and pitch, which gives the illusion of a camera moving in a 3D space, but really there is no camera, just the objects in the scene that scale, and translate in in relation to the values defined for the camera.
So, when you remove that camera matrix for an object, the cameras position now has no influence on the models position, or put another way, the model does not move relative to the camera anymore but moves congruently with the camera.
I want to move an Text object, and the part of code is as follows.
GameObject.transform.position = new Vector3(-210, -200, 0);
When I execute and check the posX of GameObject in Unity, its value becomes -1170(in 1920x1080), -1653.566(16:9). But posY can work properly. I've set the reference convolution to 1920x1080, and I think it may it have something to do with the resolution settings. Is there any thing wrong? Thanks.
If you are talking about unity ui text you should do it like this.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UITestSO : MonoBehaviour
{
public Text textObject;
void Start ()
{
//Position relative to parent transform
textObject.rectTransform.localPosition = new Vector3 (-210, -200, 0);
//Position in world space
textObject.rectTransform.position = new Vector3 (-210, -200, 0);
}
}
All the UI objects(text, image etc.) are parented by canvas object in unity. Canvas behaves differently based on it's screen space setting as follows -
Screen Space - Overlay : If the screen is resized or changes resolution, the Canvas will automatically change size to match this.
Screen Space - Camera : If the screen is resized, changes resolution, or the camera frustum changes, the Canvas will automatically change size to match as well.
Screen Space - World : The Canvas will behave as any other object in the scene. The size of the Canvas can be set manually using its Rect Transform.
The default setting is Screen Space - Overlay Which is the reason you are getting different position values for your text object on different resolutions.
The unity UI elements uses RectTransform. From unity docs
The Rect Transform component is the 2D layout counterpart of the
Transform component. Where Transform represents a single point, Rect
Transform represent a rectangle that a UI element can be placed
inside. If the parent of a Rect Transform is also a Rect Transform,
the child Rect Transform can also specify how it should be positioned
and sized relative to the parent rectangle.
So, to set position of UI elements use RectTransform's anchoredPosition variable, which sets the position of the pivot of this RectTransform relative to the anchor reference point.
textObject.rectTransform.anchoredPosition = new Vector3 (-10, -10, 0);
Reference to rect transform script API.
In Unity, the transform values you see in the inspector are relative to the gameobject's parent. However, when you try to set value for a gameobject's position (by assigning transform.position = ...), you are dealing with position relative to world's center (i.e Vector(0,0,0)). This holds true for whether you are dealing with 3d or 2d.
So, if the parent object is at Vector(0,0,0), world and local positions would be same. There isn't anything wrong with the resolution. You need to set values relative to your parent.
This is how you set values for objects.
anObject.transform.localPosition = new Vector3 (X, Y, Z);
Although there is nothing stopping you from using the same for 2d workflow, RectTransforms are used over simple Transform.
I need to know if there is an established way to do this, given that what defines screen boundaries depends on the device, etc. I have these rigid bodies that are not kinematic and not affected by gravity with light masses. When I instantiate them, they are all in an empty with a sphere overlapping them to create an "explosion" effect.
This works well, however after the sphere pushes the rigid bodies apart and explosion has occurred, I need the bodies to ALL keep moving until out of the users view/the screen. This happens for most of them but they are some stragglers and some take a very long time, staying in center of the screen.
I would normally apply a force but I do not know for each rigid body (there are a lot) which way they would need to move depending on where they are.
How can I apply a force that gets all these rigdibodies off the screen? The explosion is supposed to be in all directions. Is there a certain Vector that would do this?
Project the position of the object onto the camera's facing vector. And then make a vector from the projected point, back to the object.
So, something like..
var t = Vector3.Dot(Camera.main.transform.forward, obj.transform.position); //distance along view vector
var p = Camera.main.transform.position + Camera.main.transform.forward * t; // position along view direction
var d = obj.transform.position - p; //vector from center to object
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.