Transform object with gravity - unity3d

I am having a problem with gravity VS transform position.
I have an object falling down but I would like to change its position while it falls. But as soon as I attach a transform position in a script to the gameobject, gravity stops working.
Here is how I attend to make it moving (pos.x/pos.y are variables) in C#:
pointer.transform.localPosition = new Vector3(-pos.x-280, pos.y-50, 252);

Where in the script do you place that line of code?
If you are placing it inside the Update() function you would be setting the position to be Vector3(-pos.x-280, pos.y-50, 252) in each frame!

Related

Adding child to rigidbody makes it move

I have a parent object with a rigidbody (gravity disabled). With a script I am adding simple cubes with box colliders as children to this parent.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
public GameObject prefab;
void Update()
{
if(Input.GetMouseButtonDown(0))
{
GameObject go = Instantiate(prefab, transform);
go.transform.localPosition = new Vector3(10f, 10f, 10f);
}
}
}
This works fine, but a slight movement of the parent object is visible everytime a cube is instantiated and parented. So eventually after adding quite a few cubes the parent moves even whole units from its original position, although the velocity is always Vector3.zero.
How does this movement happen and how do I prevent it?
So, it appears that the small movement of the rigidbody parent comes from a change in the centre of mass. By moving or instantiating objects as childs this value has been changed as it states in https://docs.unity3d.com/ScriptReference/Rigidbody-centerOfMass.html:
If you don't set the center of mass from a script it will be
calculated automatically from all colliders attached to the rigidbody.
After a custom center of mass set, it will no longer be recomputed
automatically on modifications such as adding or removing colliders,
translating them, scaling etc. To revert back to the automatically
computed center of mass, use Rigidbody.ResetCenterOfMass.
Finally, as solution I just set the local center of mass to a fixed value.
rig.centerOfMass = Vector3.zero;
I am quite happy with this solution, because this also changes the center of rotation. Still I am not quite sure why it adds a movement on a change in the center of mass, because I don't see why that would be realistic behaviour.
Also there is a difference between rigidbody.position and transform.position. By using solutions such as commented under the question:
Unparent, move child, parent again
Disable child, move child, enable child again
Disable the child's collider, move child, enable it again
...it is possible to keep the transform.position the same, but rigidbody.position will still change. This difference between both values persists as long as the rigidbody is asleep. Waking it up e.g. by calling Rigidbody.Wakeup() will sync both values again. Due to a difference in both values even things like a raycast can fail, although the ray might be hitting the spot where the meshes are actually drawn and just the physics engine thinks they are somewhere else. Also waking up again looks ugly because the mesh snaps back into place were it should be to match the rigidbody.

Transform.position differs in code and editor

I'm trying to set my player's position to an cube's position in my scene.
I do this using the following function, which gets called when the object is selected:
public void PickCube ()
{
Debug.Log(this.gameObject.transform.position); //this is different from the values in the editor
Player p = GameObject.FindGameObjectWithTag ("Player").GetComponent<Player> ();
p.SetPosition (gameObject.transform.position); //put the player at this cube
}
However, my cubes position in the scene is different from the position I'm attempting to get via gameObject.transform.position:
This is the position I see in the editor:
This is the position returned by Debug.Log:
(25.0, -6.9, 20.5)
Why am I getting different positions in the editor and code?
I looked into global vs local position, and gameObject.transform.position.normalized, but neither of these were the problem or solution.
Update:
When I do Debug.Log(gameObject.name), it returns the name of the script "LevelCube". I thought gameObject was supposed to be the object the script is attached to?
1.) Just use (this).transform.position rather than your function
2.) If problem persists, try transform.localPosition instead

Sprite disappearing to the back of another sprite on moving to defined point via transform.position

I have a difficulty with Unity2D's Sprite rendering.
Currently I have a sprite for a gameBoard, an empty GameObject holding the spawnPoint, a random sprite marking it, as well as a playerSprite to be instantiated as a prefab. If I am just using the hierarchy on Unity, the playerSprite shows perfectly above the gameBoard, and "hard-coding" its position will always keep it above the gameBoard sprite, visible to the eye.
The problem comes when I want to instantiate the gameBoard and dynamically adding the playerPrefabs into the game.
Here is the current code snippet I am currently using:
gameBoard.SetActive(true); //gameBoard is defined as a public gameObject with its element defined in Unity as the gameBoard sprite.
Player.playerSprite = (GameObject)Instantiate(Resources.Load("playerSprite"));
Player.playerSprite.transform.localPosition = spawnPoint.transform.localPosition;
The result is that the spritePrefab spawns at the place I want perfectly, but behind the gameBoard sprite, making it hidden when the game runs.
The result is the same when using transform.position instead of transform.localPosition
How should I code the transform part. such that I can still make my playerSprite visible? Thanks.
It's most likely not an issue with the position, but rather the Sorting Order of your Sprite Renderers.
The default values for any SpriteRenderer is Layer = Default & Sorting Order = 0
Sprite Renderers with a higher sorting order are rendered on top of those with a lower value.
Add the following lines to the end of your code, and try it out.
gameBoard.GetComponent<SpriteRenderer>().sortingOrder = 0;
Player.playerSprite.GetComponent<SpriteRenderer>().sortingOrder = 0;
Obviously, you could do the same thing in the inspector as well.

Why Particplesystem Position is wrong while attached to a GameObject?

I'm working with unity 5(2D project).
I attached a ParticleSystem to a GameObject(an UI Button). now i can see both of them but they are not in the same position.
I move particplesystem manually and put both object in the same position .but when i move my object they will not move togothere... particlesystem will move lower and objects will have different positions.
thank you from #Code Clown and #Noel Widmer.
as my friends said at first i should transforms the GUI's screen position to world position and then to the particle system's local position in each update.
I made this by these two line of codes.
Vector3 p = Camera.main.ScreenToWorldPoint(GameObject.Find("MyObject").transform.position);
transform.localPosition = p;

How to use AddForce and Velocity together?

I have the jump component who use the AddForce for jumping and the movement component who move left and right using the Velocity.
If you don't move the character when your are jumping the jumping will be fine but when you move the character and jump at the same time then the movement component will break the jumping because the velocity is setting up a Vector2 point where define the Y axis too. I tried to use the current Y axis from the transform component in the movement but even that doesn't work.
What I should do for fix the problem between AddForce and then use Velocity?
It seems your move function is creating a new velocity vector and overwriting the existing one.
Vector2 velocityVector = rigidbody.velocity;
velocityVector.x += movement * force;
rigidbody.velocity = velocityVector;
This will retain the existing velocity, both X and Y, and modify it. You will of course need to add deceleration (usually I use something along the lines of if(grounded) velocityVector.x *= 0.999f;, but I'm sure more fancy maths exists for more realistic deceleration) and some kind of maximum speed (again, I keep things simple and use similar to if(velocityVector.x > maxSpeed) velocityVector.x = maxSpeed;).
Rigidbody.AddForce has the following definition:
public void AddForce(Vector3 force, ForceMode mode = ForceMode.Force);
One of the options available for ForceMode is ForceMode.VelocityChange:
Add an instant velocity change to the rigidbody, ignoring its mass.
Apply the velocity change instantly with a single function call. In contrast to ForceMode.Impulse, VelocityChange will change the velocity of every rigidbody the same way regardless of differences in mass. This mode is useful for something like a fleet of differently-sized space ships that you want to control without accounting for differences in mass. In this mode, the unit of the force parameter is applied to the rigidbody as distance/time.