UNITY How do I change image position? - unity3d

Below is a snippet of code thats running every update but when I log the local position of the image it still says 0,0,0 when it should be 10,10,10. What am I doing wrong??? Ultimately I am trying to understand how to programmatically move an image around on screen
public partial class MainCanvasSystem : SystemBase
{
protected override void OnUpdate()
{
if (MainGameObjectCanvas.Instance != null && SystemAPI.HasSingleton<MainEntityCanvas>())
{
Entity mainEntityCanvasEntity = SystemAPI.GetSingletonEntity<MainEntityCanvas>();
LocalToWorld targetLocalToWorld = SystemAPI.GetComponent<LocalToWorld>(mainEntityCanvasEntity);
Canvas canvas = MainGameObjectCanvas.Instance;
Image image = canvas.GetComponentInChildren<Image>();
var rect = image.GetComponent<RectTransform>();
rect.localScale.Set(10,10,10);
Debug.Log(rect.localPosition.x);
}
}
}

I think there is general misunderstanding here.
rect.localScale.Set(10,10,10);
does .. nothing!
Transform.localScale is a property and returns a COPY of a Vector3 struct.
You are calling Vector3.Set on it which replaces the values within that Vector3 copy, yes, but then you never actually apply it anywhere.
=> you need to actually set the property!
You rather would do e.g.
rect.locaScale = Vector3.one * 10;
or
rect.localScale = new Vector3(10,10,10);
However, this said, changing a localScale won't change the position at all. The RectTransform.anchoredPosition is probably rather the one to go with.

Related

unity2d Problem With local positioning of child with rotating parent

I am making a game, in which I have clouds that when shot are hidden using sprite masks, the sprite masks are then attached to the cloud via parenting, here is the function that attaches and positions the masks.
public void SpawnGasCloudMask(Transform collisionTransform, Vector2 difference)
{
GasCloudMaskController selectedGasCloudMask = null;
for (int i = 0; i < gasCloudMaskList.Count - 1; i++)
{
if (!gasCloudMaskList[i].gameObject.activeSelf)
{
selectedGasCloudMask = gasCloudMaskList[i];
break;
}
}
if(selectedGasCloudMask == null)
{
selectedGasCloudMask = InstantiateGasCloudMaskController();
}
selectedGasCloudMask.transform.SetParent(collisionTransform);
float angle = collisionTransform.rotation.z;
Vector2 straightPosition = new Vector2(difference.x / collisionTransform.localScale.x, difference.y / collisionTransform.localScale.y);
selectedGasCloudMask.transform.localPosition = straightPosition;
selectedGasCloudMask.gameObject.SetActive(true);
}
enter image description here
This is the result when the cloud is not rotated, However if I rotate it, say 90 degrees.enter image description here
I have tried using RotateAroundLocal, but it is said to be deprecated and I cannot see it having an effect. Obviously what I want is for the masks to be properly attached to the parent based on its rotation, I tried doing some geometry, but solving this remains yet out of my reach. I believe I have to change its local parameter position, I did manage to do it with non parented gameObject, however the local parameter does not offer the RotateAround function. I will appreciate any help.TY.
I found my answer:
selectedGasCloudMask.transform.RotateAround(collisionTransform.position,
-collisionTransform.forward, collisionTransform.eulerAngles.z);
Since the position to which the child attaches to the parent, you need to account for the parent's rotation. The deprecate function that did exactly that was replaced by the generic function, which requires you to understand what is going on.

Unity RectTransform.GetLocalCorners(Vector3[] fourCornersArray) result not change as object;s position changing

my brothers and sisters from another mother : )
I'm trying using unity to implement a swipe menu, which is like the apps menu on a smart phone. I want to get the current corner's local location value, so I can use them as a reference to do some stuff. However, while I'm dragging the object, the corners' value seems remain fixed, which looks weird to me, since the object's relative position (local position) to its parent is definitely changed, I don't know why the corners' location position can all the way just stay the same.
public class pageSwiper: MonoBehaviour, IDragHandler
{
private Vector3 panelLocation;
void start() {panelLocation = transform.position;}
public void OnDrag(PointerEventData data)
{
float difference = data.pressPosiiton.x - data.position.x;
transform.position = panelLocation - new Vector3(difference,0,0);
Vector3[] corners = new Vector3[4];
GetComponent<RectTransform>().GetLocalCorners(corners);
Debug.Log(corners[0].x)
Debug.log(corners[3].x)
}
}
while I using using pointer (mouse) drag the object, the Debug's log value always be the same. Should they change as the object moving, shouldn't they?
You are using GetLocalCorners which are relative to the center of your object.
You can try using GetWorldCorners.

Unity 2D - how to check if my gameobject/sprite is below ceratin Y lvl?

I've been trying to get a script working to check if my player is below a certain Y lvl, for a platformer. so it can be respawned to the beginning, But how do I put the y lvl inside a variable to check it? i cant figure it out lol
In the Update() run something like:
if(player.transform.position.y < 1)
{
//do something
}
where 'player' is the GameObject in question.
I am assuming you want to just want to compare (==, <=, >=, all that jazz is what I mean by comparing just in case you were not aware) the Y value to something like 10 for example. This is easy and you don't even need a variable necessarily for this.
//For the object position relative to the world
if(transform.position.y == 10) //"transform" gives you acces to the transform component
{ //of the object the script is attached to
Debug.Log("MILK GANG");
}
//For the object position relative to its Parent Object
if(transform.localPosition.y == 10)
{
Debug.Log("MILK GANG");
}
If you want to change the value of the position of your object then
transform.position = new Vector2(6, 9)//Nice
//BTW new Vector2 can be used if you dont
//want to assign a completely new variable
However, if you want to get a reference (Basically a variable that tells the code your talking about this component) to it.
private Transform Trans;
void Awake() //Awake is called/being executed before the first frame so its
{ //better than void Start in this case
Trans = GetComponent<Transform>();
Trans.position = new Vector2(69, 420); //Nice
}
This is the code way of doing it but there's another way that uses Unity
[SerializeField] private Transform Trans;
//[SerializeField] makes the variable changeable in Unity even if it is private so you
//can just drag and drop on to this and you good to go
Hope this help
if it doesn't
then welp I tried lel
You can use a script added to gameobject to check transform.position of the object.
if(transform.position.y < ylvl)
{
//do something
}
where ylvl is the integer of the height you want to check

Instantiate GameObjects and change Material when it hits on the ground

There is a code for instantiate cube into the list and change a Material of each clone when it hits on the ground
The following code works but not in Real-Time. Update function works like a Start function for a Foreach method
How to get a value of item.transform.position.y in the Update function Real-Time?
public GameObject cubePrefab;
public Material RedMat;
public float GroudLevel = 0.5f;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
List<GameObject> cloneList = new List<GameObject>();
//instantiate clones into the list
for (int i = 0; i < 10; i++)
{
var clone = Instantiate (cubePrefab,new Vector3(Random.Range(-3f, 3f),
Random.Range(4f, 10.5f),Random.Range(-3f, 3f)), Quaternion.identity);
cloneList.Add(clone);
}
//if clone is grounded change a Material for each clone
foreach (var item in cloneList)
{
//Debug.Log(item.transform.position.y);
//check if clone is on the ground
if(item.transform.position.y < GroudLevel)
{
item.GetComponent<Renderer>().material = RedMat;
}
}
}
}
There is a screenshot for a GroudLevel = 7
The reason this function isn't working is because the pivot (transform.position) of your item is always in the center of the object. This isn't something you can change in Unity (nor would you necessarily want to).
On top of this, you're checking if the item is under the ground, and not on it when you use < insteaad of <=, because the position needs to be less than groundLevel to return true.
There are several solutions here.
The simplest would involve moving all of this logic to an OnCollisionEnter or OnTriggerEnter method. For more information on this, check the Unity documentation.
Another solution would be to find a way tthe size of the object, divide it by two, and check if
item.transform.position - halfSize <= groundLevel;
This seems really cumbersome and overly complex, however. You'd be better off using Unity's built-in collision system, unless you have a reason not to.

How do i replace my game object's current position with a new one?

I wanted to make a vertically scrolling background with 3D assets (2D pictures works fine, but i wanted the cool lighting effect), and i kept failing doing something i though would be so simple.
so here's my current progress:
public Vector3 target;
private Transform Top_Top_Left_Rescroll;
void Start (){
target = GameObject.FindGameObjectWithTag ("Top_Top_Left_Rescroll").GetComponent<Transform>();
}
void Update () {
if (gameObject.transform.position.y <= -12) {
gameObject.transform.position = new Vector3 (target.x, target.y, target.z);
}
}
}
The object resets it's position to 0 after the if statement (the rotation and scale weren't affected), and i ran out of ideas to do what i want.
You are passing a Transform to a Vector3.
try :
target = GameObject.FindGameObjectWithTag("Top_Top_Left_Rescroll").transform.position;
ps: I'm not sure if you really want your target position to never change, but you are passing it's value during Start() so you will always place your gameObject in every frame at the same initial position.