Scale gameobject on just one side - c#

I have added Cube to scene and I scaled and put to position ( 0, 0, 0 ).
I am scaling that Cube with code attached to Cube
IEnumerator Start() {
StartCoroutine("DoSomething", 2.0F);
yield return new WaitForSeconds(1);
StopCoroutine("DoSomething");
}
IEnumerator DoSomething(float someParameter) {
while (true) {
transform.localScale += new Vector3(0, 0.1f, 0);
yield return null;
}
}
but Cube scales on both sides, to top and bottom. I want to scale with same factor but that bottom of Cube stays on same position.
I tried to set new position between transform.localScale += new Vector3(0, 0.1f, 0); and yield return null; but I don't know how to get exact amount.
( I tried to read
Mesh planeMesh = gameObject.GetComponent<MeshFilter>().mesh;
Bounds bounds = planeMesh.bounds;
bounds.size.y;
before and after scale and add to
transform.position.y difference between
boundsAfter.size.y and boundsBefore.size.y
but it moves too much.
How to solve this ?

You can actually do this in two ways.
METHOD 1:
Change pivot point from an external application.
Create a simple Cube in a 3D software such as Maya then position the pivot point to the bottom of the cube and then export it Unity. This should work out of the box.
METHOD 2:
Parent the Cube to an empty GameObject.
Steps:
A.Create a an Empty GameObject.
B.Move the new GameObject to the position of the Cube then move the y axis of that new GameObject to the bottom of the cube. The y-pos must be positioned precisely by zooming in. See to the animation below for more information.
C.Now drag the Cube to the that new GameObject and the cube should be the child of that new GameObject. You can now attach the script in your question to that new GameObject and it should scale the cube on one side only. Don't forget to remove the old scaling script that is directly attached to the cube.
Image Tutorial. High quality version here.

You can use Slider for the purpose. I was designing a Loading bar for which I needed to Increase width of the loader according to the download that is progressed. You can disable its handle, and use custom Sprite for loading fill percentage. You can also use custom Sprite for background. To use Slider, go to Menu Bar -> GameObject -> UI -> Slider. Or instead You can Add a Slider Component from the Inspector for the GmaeObject you want (Select the GameObject you want to add Slider -> In the Inspector click Add Component -> UI -> Slider. Now Set Fill Rect and other Options). You can set Slider from Left to Right, Right to Left, Bottom to Top, or Top to Bottom.
In the Script
using UnityEngine.UI;
public class SliderExample : MonoBehaviour
{
public Slider slider; // Drag and Drop Slider GameObject in Unity Inspector
float percentageCompleted;
void Update()
{
slider.value = percentageCompleted;
// specify percentage Completed, if required Divide by 100 as Slider values are from 0 to 1 or set Max Value in Inspector as 100
}
}
You can also watch this Brackeys video for some help regarding setting up the Slider "https://www.youtube.com/watch?v=YMj2qPq9CP8".

Related

Unity - drag to resize / scale plane based on handle position?

Alright, I cant find any example of this already done and my attempt is yielding odd results - I need to drag to resize a flattened cube (like a plane, but must have thickness so it was a cube) using a handle in the corner. Like a window on your desktop.
So far Ive created my handle plane and gotten it via script attached to my cube plane. The cube plane and the handle are children of an empty to which the scale is being applied so that the cube plane scales from left to right as desired:
That works, however my attempt at using the delta scale handle position to scale the parent empty scales either way too much or in odd directions:
Awake() {
scaleHandle = GameObject.FindGameObjectWithTag("ScaleHandle");
scaleHandleInitialPos = scaleHandle.transform.localPosition;
}
Update()
{
width += -1*(scaleHandleInitialPos.x - scaleHandle.transform.localPosition.x);
height += -1 * (scaleHandleInitialPos.y - scaleHandle.transform.localPosition.y);
transform.parent.localScale = new Vector3(width, height, thickness);
}
what is wrong here?
Hierarchy:
Transform of the child:
With updating initialPos every Update() OR doing width = scaleHandle.transform.localPosition.x / scaleHandleInitialPos.x; where the white square is the scaleHandle

Always move on surface of the mesh unity C#

I have a cube which i want to move always on the surface of the mesh. Like i have a destination on the surface where player want to go but it should go to the destination without leaving the mesh. Like it go along the surface of the mesh. I know that i Can move towards the destination like this:
IEnumerator MoveToDirection(Vector3 startPosition, Quaternion orientation, Transform planet)
{
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
go.transform.rotation = orientation;
go.transform.position = startPosition;
while (true)
{
go.transform.position= go.transform.position + go.transform.up * Time.deltaTime* speed;
yield return new WaitForEndOfFrame();
}
}
But don't know how to restrict that it should not leave the surface of the mesh.
There are 3 ways to achieve this effect:
Use physics: attach rigid body/collider to cube/mesh and use something like AddForce
Add every frame move cube to target and calculate position in runtime. If you have formula to calculate height (for example, if you mesh generated from noise or it just sphere) - you can use formula, in other case you can add MeshCollider to mesh and RayCast touch point of mesh/cube every frame + correct cube position
If mesh not endless you can use Unity Nav Mesh system - it will be easiest way to solve complex tasks.

In unity script, how to "rotate" and "rotate to" around pivot position

in unity editor, when i enable "Pivot", gameobject will rotate around "pivot point" position, when i enable "Center", gameobject will rotate around "center point"
but if i use script to rotate, it always rotate around "center point", for ex, here is my scene:
I use following code:
void Start()
{
// transform.rotation = Quaternion.Euler(new Vector3(0, 0, 90));
transform.RotateAround(transform.position, new Vector3(0, 0, 1), 90);
}
it rotate around "center point"
if object has collider, i can get pivot point with colider.bounds, if not, how should i do?
and even worse, in some case, i hope rotate to like set rotate in unity editor inspector, i use following code:
transform.rotation = Quaternion.Euler(new Vector3(0, 0, 90))
I have no idea to adjust above code to rotate around pivot point
update
I think if i can "rotate", i can also impl "rotate to", so the key point is, how should i get "pivot point" that is used in RotateAround, to object has collider, I can get with colider.bounds with transform.position, to no collider object, how should i do?
The pivot point is the-same as the transform.position you're already using. If you don't like where the pivot point is or the location the rotation is rotating against, you have two options:
1. Create new empty GameObject. Move it to the position you want your GameObject to rotate around. Once satisfied by that location, make this new GameObject a child of the GameObject you will be rotating around. Use the position of this new GameObject as the pivot rotation point for the transform.RotateAround function.
Drag the empty GameObject to the customPivot slot in the script below. That should give you a new pivot point to rotate your GameObject around.
public Transform customPivot;
void Update()
{
transform.RotateAround(customPivot.position, Vector3.up, 20 * Time.deltaTime);
}
2. Open a 3D application and change the pivot point of your object, then save and re-import it into Unity.
Since this is just used to rotate object around, I suggest #1. If the problem is that the pivot point is not centered, I would suggest #2.

How to move an gameobject in Unity properly?

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.

Script not working when animation is enabled

I am testing to make a cube move with a script. Also have a simple Roll animation for the cube which is supposed to activate whenever I move the cube.
But the cube doesn't move when the animation is 'checked' as active under the inspector tab. The cube only moves if I disable animation thus not even able to see if the animation works properly when I move the cube. The cube is imported from Blender to Unity. Please advice what I am doing wrong.
The script is as follows. It is a very simple and small test file thus I have attached my Unity and Blender files too at Dropbox for reference if that helps. Thank you.
Link to Unity Project:
https://www.dropbox.com/sh/cvpjf26i31o1ell/AABmLMqYV4tPiG7qruph2D4Ra?dl=0
Link to Blender model and animation:
https://www.dropbox.com/s/deowh3yk5wpse1u/box.blend?dl=0
Movement script for cube:
public float speed = 10.0F;
Animator anim;
void Update()
{
float translation = Input.GetAxis("Vertical") * speed;
translation *= Time.deltaTime;
transform.Translate(0, 0, translation);
Animating(translation);
}
void Animating(float v)
{
bool roll = v != 0f;
anim.SetBool("Roll", roll);
}
I've updated the project and put it back up on dropbox
https://dl.dropboxusercontent.com/u/9274763/MechanimTester%20v2.zip
I added a new emtpy gameobject and made the blender cube a child of that.
The TestScript is now attached to that new gameobject and controls its position.
The animation now only applies to the child object and so the animation is no longer
interfering with the position of cube.
(What was happening was that the animation was modifying the transform for the gameobject - now as its a child its not affecting its parent so it doesn't reset the position of the overall gameobject
Does that make sense ?
Garrett

Categories

Resources