Why are Unity Prefab values wrong when instantiated? - c#

I have a C# script on a character that holds a reference to a Prefab.
During initialization, the script runs :
weaponSlot = Instantiate(weaponPrefab) as Transform;
and sets
weaponSlot.parent = rightHand;
the prefab contains scaling information for the weapon, as well as some small rotation and position offsets for it to look correct.
When the game is run, the weapon's actual position is offset from the rightHand by a massive amount, although the rotation is preserved. The scaling is also a bit off, smaller than the prefab-ed size by roughly 40%.
Any insight on why this is happening, or even hints on what to check would be appreciated!

Make sure to wrap any models in an empty game object. The size, position, and orientation need to be correct under the root gameobject. When you instantiate a gameobject under a parent you need to be sure to zero-out the localPosition, and localEulerAngles (set them = Vector3.zero). You need to also set the localScale = Vector3.one.
It should look like this in the project:
Prefab (zero position, zero rotation, one scale)
->Model (correct scaling, rotation, and position)
Then you parent it.

Related

Can't Make animation for only Z axis in uniy

I have a quick question. If anyone can answer me, I will be grateful. I want to make an animation for about 117 cubes. I know that I don't need to do it one by one. I can simply make a prefab for the cube and duplicate it, but the problem is I just want to make it for the z-axis. However, the animation applies it for all the position properties. So how can I make an animation for the z-axis without affecting y and x? Thank you.
The problem is that you are animating the cubes based on the world position, so it is teleporting everything even for x axis and y axis.
You can easily avoid this by adding your prefab with the animation inside an empty gameObject, you can save it as a prefab too. In this way when you instantiate the empty with inside the cube, the child object (your cube) will move based on the empty position, so y and x will be the x and y of the empty one.
So
1 animate your cube
2 add the cube to an empty game Object
3 set your empty as prefab and duplicate it
If your animation is not sprite based, only transform based, you can use TWEENING Libraries. LeanTween is in the Unity Asset Store as free asset. It is far much faster than builtin unity animation. It is really easy to use. I used it in over 100 UI objects and it didn't even used any remarkable resource at all (FOR 2D Object). I believe that will solve your problem easily.

Unity 3d : Slider values take place on second run when trying to modify scale of prefab clones

Title pretty much sums it up. I am trying to adjust the scale of cloned prefabs during runtime, through a UI slider. However on first run the slider doesn't seem to have any effect on them, and on second run the Objects just keep one value from the slider and appear already taller or shorter. I need the slider to adjust the height of the objects dynamically, just as it does on a normal, not cloned, object. Any help will be greatly appreciated. Thanks!
The script works on normal objects, not clones.
Here is my slider method :
public void slideScale(float textNumber)
{
Vector3 scale = Wall.transform.localScale;
scale.y = textNumber;
Wall.transform.localScale = scale;
}
I expected to be able to change the height, while moving the slider.
A value is being stored and just takes place on second run while the slider still seems not to be affecting anything.
Looks like you're modifying the reference to the Prefab instead of the instance of a prefab (clone, in your words).
Here's how you store the reference to an instance of a prefab:
// Spawn an object based on a prefab "Wall"
// and store the spawned object in variable "instance"
GameObject instance = Instantiate(Wall);
// Modify the instance properties
instance.transform.localScale = scale;

Display complete object from camera with specific rotation in unity C#

I have different kind of objects with variable dimensions and placed at different position in a scene. I want to focus/display each object with the camera with a hard code rotation (north rotation). Like with specific camera rotation I want to focus the object that it completely show to the camera and center of the screen. For this reason, I have write this code snippet that
1
Get the position behind the specific focus object using
TransformPoint
Provide the elevation using the largest extent of the bound so that it display maximum area of the object.
Assign the position and the fixed rotation
Vector3 dest = destination.transform.TransformPoint(0, 0, behindPositionDistance);// GetBehindPosition(destination.transform, behindPositionDistance, elevation);
Debug.Log(dest);
float eleveMax = Mathf.Max(destination.GetComponent<MeshRenderer>().bounds.extents.x, destination.GetComponent<MeshRenderer>().bounds.extents.z);
dest = new Vector3(dest.x, eleveMax, dest.z);
camera.transform.position = dest;
camera.transform.rotation = lookNorth;
But the problem is, it is not accurately working with all objects as every object is at different position and dimension. I want to focus the full object using the camera but without changing the rotation.
Maybe create an empty gameobject as a child of your objects. Use that as your Camera position at runtime.
If you can use an orthographic camera, you can set the camera's orthographicSize dynamically based on the size of the bounds of the GameObject. This is probably the easiest solution.
If you need a perspective camera, you can get the Planes or corners of the camera frustum via GeometryUtility.CalculateFrustumPlanes(Camera.main) or Camera.CalculateFrustumCorners and use the results from either to manually test that your Bounds is entirely inside.
With a perspective camera, you could also compute the necessary distance from the object based on the size of the object's bounds and the FOV of the camera. If I'm not mistaken, this would be something along the lines of distance = 0.5 * size / tan(0.5 * fov), but the function doesn't have to be precise; it just needs to work for your camera. Alternatively, you could keep distance constant and compute FOV from the size of the object, although I wouldn't recommend that because frequent FOV changes sound disorienting for the viewer; my point is that there are many options.

Interpolate where OnTriggerExit is called

In my code, I use OnTriggerExit to detect when an object leaves a previous cube's space, and then create another cube. However, because of delta time, the cube gets placed slightly late creating these varied size gaps:
How do I get rid of them, and position the cube properly?
I am pretty sure I need to interpolate, but I am not sure exactly what/how to do it. If needed, I have the last cube, last frame and current transforms, as well as current speed (in Vector3 form). Thanks!
When you leave, set this cube's position to lastCube.position + size_offset, where size_offset is however big your cubes are in the direction that they're moving.
You already have a reference to the previous cube (due to the OnTriggerExit supplying you with a reference to the other collider, from which you can get the needed Transform).
I don't think this is strictly deltatime,s fault. Physisc engine has its on timestep, and if the velocity is x, the object will travel x*dt per physics step. So, by the time the next round of triggers is fired, the object is already penetrating. You could either use a rigidbody (easier but may not give expected results), or check penetration depth with that collider and offset that

How do I make so when user moves the camera it doesn't go beyond the scene borders?

How do I make so when I move the camera(with touch) it doesn't go beyond the scene borders?
How do I move the camera with touch so it moves strictly with scene parts, like slides(swipe-first slide, another swipe-another slide) with not going beyond the borders of the scene?
The game I'm making has a camera like in Disco Zoo game for android (I'm a newbie)
Technically, the scene doesn't really have a border. You'll need to define the border somehow within your game, then constrain the camera's position with something like Mathf.Clamp(value, min, max) in an Update() function on the camera.
How can you define the border? It's up to you. Some ideas:
Hard-code the values in the script that clamps the camera. Probably the quickest option, but not flexible
Make public parameters on the camera script that let you set min and max positions in the X and Y directions
If you have a background image: use the extents of that to define your camera's extents
Create empty objects in your scene that define the minimum and maximum extents of the scene. Put your "min" object at the top-left, and the "max" object at the top-right. Connect it to the camera script, then use those positions to see if you've gone too far in any given direction. The main reason to do this is that it's visual.
(Slower, but dynamic) If everything in your scene uses physics, you could search the entire scene for every Collider component, then find the furthest extents in each direction. However, this is probably going to be pretty slow (so you'll only want to do it once), it'll take a while to code, and you'll probably want to tweak the boundaries by hand anyway.

Categories