My Y is changing to unexplained values

So, I have the following tidbit attached to a script being used on my character in a little game I am working on. The problem I am having is the the Y value keeps changing to mostly negative numbers. Every now and then it will display the object where I expect it, but mostly not, unless I set a static value to Y. X seems to be fine.

if(Input.GetKeyDown(KeyCode.R))
		{
			distanceFromBody = 0f;
			distanceFromBody = this.transform.localPosition.y + 1;
			projectileHolder = Instantiate(Resources.Load("Weapons/throwingWeapon")) as GameObject;
			projectileHolder.transform.position = new Vector3(this.transform.localPosition.x,this.transform.localPosition.y + 1f,0);
			projectileHolder.rigidbody.AddForce(10f, 0, 0);
			Destroy(projectileHolder,4);
		}

Any pointers on what I am overlooking?

This line seems a bit strange:

projectileHolder.transform.position = new Vector3(this.transform.localPosition.x,this.transform.localPosition.y + 1f,0);

You seem to be taking a point in local space, then treating it as a point in world space?

Perhaps you mean to do something like this:

projectileHolder.transform.position = new Vector3(this.transform.position.x,this.transform.position.y + 1f,0);

Personally, I’d usually rather use vector addition, but that may not be useful if there’s a particular reason you’re specifying each axis manually (in particular, setting the z-component to zero):

projectileHolder.transform.position = transform.position + Vector3.up;

Well, changing local position to position with no change. Vector3.up didn’t change it’s behavior either.

When using THIS it should be pulling the position of the object/character its attached to?

“this” refers to the instance of the component it’s called in. “this.transform” will then give you the transform component of the object it’s called in.

Also, does the projectile appear where you expect it to before applying force?

Honestly, I can’t remember…

I will comment out that code when I get home and report back.

So, I disabled force and the Y position is still not doing as expected. The Y value is still not staying even close.

Also, the player in the games Y stays at a solid number the whole time. I check this to make sure there wasn’t something weird going on there.

Just seems weird that if I use a static number it is in the position, but using localPosition or position it gets unexplained values when the characters y is as expected.

you haven’t explained where this script runs… am sure it is nested or multi-nested under object/s that one of them contains a negative Y value…

Check All Parents of the object that runs the script… and make sure that their position in Y is Positive… am sure this will fix the problem…

The script is attached to the player gameobject, which is why I am trying to pull this.transform.position.y figuring it should be pulling the same Y listed in Unity when I click the player object when I start the game.

The player Y is .65 and the Y value will report up to 1.3 and all the way down to -8.something.

I will recheck my code and try to report more. This code is just when the user presses R it throws an object. It is fairly simple and it just baffles me cause the X used is always the same as the X of the player object.

if you want to get positive Y you need to make sure that whatever controls player position does not end up with values below zero…
Your instantiate script code is not the source of the issue…

if i assume that you use physics and player moving on surface… the one will get effected by physics directly + jittery is the Y… because gravity pulls player downward against surface… i’d suggest moving up the whole scene Up by +50… so you eliminate the few negative float points you get because of jittery…

K, I will try that when I get home. Seems the most logical at this point since the Y does jitter a small bit on the character when moving. And yes, he has physics(gravity) applied.

Well, changing everything to 50 on the Y did not make a difference. I seriously can’t see what I am overlooking. Here is the code attached to the player and I hope one of you can see it easily:

public class player : MonoBehaviour 
{	
	public float Gravity = 21f;	 //downward force   21f
	public float TerminalVelocity = 20f;	//max downward speed
	public float JumpSpeed = 20f; //20f
	public float MoveSpeed = 20f;
	public float ThrowDistance = 2f;
	public float distanceFromBody;
	public int currentHealth = 100;
	public bool testCollide = false;
	public bool finishLevel = false;
	public bool isAlive = true;
	public bool playerTakeDamage = true;
	public bool trainerAccess = false;
	public int jumpInt = 0;
	public int duckAttackDamage;
	public int testMove = 0;
	public GUISkin mySkin;
	//public Thread runJumpBack = new Thread(new ThreadStart(jumpBack));
	
	//Ability variables
	public int trainingPoints = 0;
	public bool throwingAbility = false;
	public int throwingObjects = 0;
	public bool fartAbility = false;
	public int gasLevel = 0;
	public bool doubleJump = false;

	Stopwatch s = new Stopwatch();
	public Vector3 MoveVector {get; set;}
	public float VerticalVelocity {get; set;}
	public Vector3 throwVector {get; set;}

	public CharacterController CharacterController;
	public GameObject duckPlayer;
	public GameObject fartHolder;
	public GameObject projectileHolder;
	
	public string trainerConversation = "Well, looks like you have found away to not get yourself killed.....one of the lucky few.";
	
	void OnGUI()
	{
		GUI.skin = mySkin;
		//GUI.backgroundColor = Color.black;
		if(isAlive)
		{
			GUI.Label (new Rect (25, 25, 100, 30), "Life");
			GUI.Box(new Rect(25,45,Screen.width/4,Screen.height/25),"");
			GUI.Box(new Rect(25,45,Screen.width/4,Screen.height/25),currentHealth.ToString());
			GUI.Box(new Rect(25,85,Screen.width/4,Screen.height/25),distanceFromBody.ToString());
			if(finishLevel)
			{
				GUI.Box(new Rect(Screen.width/2,Screen.height/2,Screen.width/4,Screen.height/5),"Level Complete!!");
			}
			else if(trainerAccess)
			{
				GUI.Window(0, new Rect((Screen.width/2)-150, (Screen.height/2)-75, 300, 250), ShowGUI, "Trainer");
				//GUI.Box (new Rect (Screen.width/2, Screen.height/2, 100, 30), "Trainer");
			}
		}
		else
		{
			GUI.Box(new Rect(Screen.width/2,Screen.height/2,Screen.width/4,Screen.height/5),"You died, BITCH!!!");
			//StartCoroutine(waitMethod());
		}
	}

	// Use this for initialization
	void Awake () {
		//DontDestroyOnLoad(this);
		//DontDestroyOnLoad(CharacterController);
		//this.transform.localPosition.Set(-23,1,0);
		CharacterController = gameObject.GetComponent("CharacterController") as CharacterController;
		//fartHolder = Instantiate(Resources.Load("Weapons/fartHolder")) as GameObject;
		//fartHolder.active = false;
		//duckPlayer = gameObject.GetComponent("mainCharacter");
		if(finishLevel)
		{
			//Instantiate(this);
			this.transform.localPosition.Set(-23,51,0);
			finishLevel = false;
		}
	}

	// Update is called once per frame
	void Update () 
	{
		deathWatch();
		if(isAlive)
		{
			checkMovement();
			HandleActionInput();
			jumpBack();
			processMovement();
		}
	}

	void checkMovement(){
		//move l/r
		//var deadZone = 0.1f;
		VerticalVelocity = MoveVector.y;
		MoveVector = Vector3.zero;
		if(Input.GetKey(KeyCode.D)){
			MoveVector += new Vector3(10f * Time.deltaTime,0,0);
		}
		else if(Input.GetKey(KeyCode.A)){
			MoveVector -= new Vector3(10f * Time.deltaTime,0,0);
		}
		//jump

	}

	void HandleActionInput(){
		if(Input.GetKeyDown(KeyCode.Space)){
			jump();
		}
		if(Input.GetKeyDown(KeyCode.F))
		{
			fartHolder = Instantiate(Resources.Load("Weapons/fartHolder")) as GameObject;
			fartHolder.transform.position = new Vector3(this.transform.localPosition.x,11,0);
			Destroy(fartHolder,6);
		}
		if(Input.GetKeyDown(KeyCode.R))
		{
			distanceFromBody = 0f;
			distanceFromBody = this.transform.position.y; //using this to just show the Y value
			projectileHolder = Instantiate(Resources.Load("Weapons/throwingWeapon")) as GameObject;
			projectileHolder.transform.position = new Vector3(this.transform.localPosition.x,this.transform.position.y,0);
			//projectileHolder.transform.position = transform.position + Vector3.up;
			//projectileHolder.rigidbody.AddForce(10f, 0, 0);
			//Destroy(projectileHolder,8);
		}
	}
	
//	void throwObject()
//	{
//		int x = 0;
//		throwVector = new Vector3(-20,1,0);
//		//projectileHolder.transform.position = Vector3.Lerp(projectileHolder.transform.position,throwVector,0.1f);
//		//projectileHolder.transform.Translate(throwVector, ThrowDistance);
//		while(x<50)
//		{
//			projectileHolder.transform.Translate(Time.deltaTime,0,0);
//			//Thread.Sleep(200);
//			x++;
//		}
//	}

	void processMovement(){
		//transform moveVector into world-space relative to character rotation
		MoveVector = transform.TransformDirection(MoveVector);

		//normalize moveVector if magnitude > 1
		if(MoveVector.magnitude > 1){
			MoveVector = Vector3.Normalize(MoveVector);
		}

		//multiply moveVector by moveSpeed
		MoveVector *= MoveSpeed;

		//reapply vertical velocity to moveVector.y
		MoveVector = new Vector3(MoveVector.x, VerticalVelocity, MoveVector.z);

		//apply gravity
		applyGravity();

		//move character in world-space
		CharacterController.Move(MoveVector * Time.deltaTime);
	}

	void applyGravity(){
		if(MoveVector.y > -TerminalVelocity){
			MoveVector = new Vector3(MoveVector.x, (MoveVector.y-Gravity*Time.deltaTime), MoveVector.z);
		}
		if(CharacterController.isGrounded  MoveVector.y < -1){
			MoveVector = new Vector3(MoveVector.x, (-1), MoveVector.z);
		}
	}

	public void jump(){
		if(CharacterController.isGrounded){
			VerticalVelocity = JumpSpeed;
		}
	}
	
	void OnCollisionEnter(Collision collision)
	{
		//testCollide = true;
		//currentHealth += 10;
//		if(collision.gameObject.tag == "Enemy")
//		{
//			currentHealth = 100;
//		}
	}
	
	void OnTriggerEnter(Collider collision)
	{
		//testCollide = true;
		if(collision.gameObject.tag == "Enemy")
		{
			if(testCollide)
			{
				
			}
			else
			{
				testCollide = true;
				currentHealth += duckAttackDamage;
			}
			if(playerTakeDamage)
			{
				playerTakeDamage = false;
				//currentHealth += duckAttackDamage;
				//duckAttackDamage = 0;
			}			
			//jumpBack();
		}
		else if(collision.gameObject.tag == "trainer"  trainingPoints > 0)
		{
			trainerAccess = true;
		}
		else if(collision.gameObject.tag == "FinishObject")
		{
			finishLevel = true;
		}
		//((collision.transform.position.y + .3) < transform.position.y)
		//runJumpBack.Start();
	}
	
	void jumpBack()
	{
		if(testCollide)
		{
			testCollide = false;
			//currentHealth += duckAttackDamage;
			//duckAttackDamage = 0;
			MoveSpeed = 100f;
			jump();
			for(int i=0;i<8000;i++)
			{
				MoveVector -= new Vector3(10f * Time.deltaTime,0,0);
			}
			MoveSpeed = 20f;
		}		
	}
	
	public void adjustPlayerHealth(int adj)
	{
		duckAttackDamage = adj;
		playerTakeDamage = true;
	}
	
	void deathWatch()
	{
		if(currentHealth <= 0)
		{
			isAlive = false;
			Application.LoadLevel("level1");
		}
		else if(finishLevel)
		{
			levelLoader();
		}
	}
	
	void levelLoader()
	{
		DontDestroyOnLoad(CharacterController);
		DontDestroyOnLoad(this);
		Application.LoadLevel("level2");
		finishLevel = false;
		this.transform.position = new Vector3(-23,51,0);
		fartHolder = (GameObject)Instantiate(Resources.Load("Weapons\fartHolder"));
		//this.transform.localPosition.Set(-23,1,0);
	}
	
	IEnumerator waitMethod()
	{
		yield return new WaitForSeconds(7);
	}
	
	void ShowGUI(int windowID)
     {
         // You may put a label to show a message to the player
         GUI.Label(new Rect(10, 40, 300, 200), trainerConversation);
         // You may put a button to close the pop up too
         if (GUI.Button(new Rect(10, 210, 75, 30), "Done"))
         {
         	trainerAccess = false;
         	trainerConversation = "Well, looks like you have found away to not get yourself killed.....one of the lucky few.";
         	// you may put other code to run according to your game too
         }
         else if (GUI.Button(new Rect(95, 210, 75, 30), "Back"))
         {
         	trainerConversation = "You clicked back.......didn't get it the first time?.....mumble...dipshit.....mumble......";
         	// you may put other code to run according to your game too
         }
         else if (GUI.Button(new Rect(180, 210, 75, 30), "Next"))
         {
         	trainerConversation = "May want an array of statements....";
         	// you may put other code to run according to your game too
         }
      }
}

Thanks for any input you can give and if any other info is needed, let me know.

i suggested moving whole scene, which means the player + the surface which player walks on it by 50+ something on Y axis in inspector… because player is almost at zero position in world in Y axis and that’s why any small jittery in Y will result the player going below zero easily…

looking at your script…
i assumed that unity physics engine handles the position of player in Y axis, but it seems you are controlling the Y axis manually through script!
if the player have a rigidbody effected by unity physics engine gravity + you are manually controlling Y axis in script, the result is jittery physics…

if the player doesn’t have a rigidbody, then it’s something in script pushing player heavily below zero…
your script have Many things controls and effects the Y axis!!!

void applyGravity(){

        if(MoveVector.y > -TerminalVelocity){

            MoveVector = new Vector3(MoveVector.x, (MoveVector.y-Gravity*Time.deltaTime), MoveVector.z);

        }

        if(CharacterController.isGrounded  MoveVector.y < -1){

            MoveVector = new Vector3(MoveVector.x, (-1), MoveVector.z);

        }

    }

why if character already on ground, you need to move player Even More into -Y ???
there is a chance that both conditions can be true…which drags character position heavily below zero easily!
you need a line of code to control the minimum allowed Y axis position, in your case 0f is minimum (i you don’t want negative Y)!

i have an easy fix work around, this doesn’t solve the code logic you are using to control game mechanics…
but will give you the desired results which is none negative value for Y axis…that’s if the player gameobject is not a child of another object…

add this at the end of processMovement()

if(transform.position.y<0)transform.position = new vector3(transform.position.x,0f,transform.position.z);

Arrange your update() as follows:

 void Update () 

    {

        deathWatch();

        if(isAlive)

        {

            checkMovement();

            jumpBack();

            processMovement();
 
           HandleActionInput();
        }

    }

i pushed HandleActionInput() at the end, so only it runs after all position adjustments finish!

i suggest for you to invest some time in player movement to make sure it works as expected before moving on to add new stuff the player can do… especially at the applyGravity() part…

also avoid using localposition if you want to get object position in world…
because they give values relative to their parents position and not their position in world.

Thanks for the input and I will try it when I get home.

On the Y position, I should have been more clear. After moving everything up to 50, the behavior is still the same(Y changing and going lower) but it is not going below 0 now. It have seen it get as low as 42 during my testing. This was after creating about 20 objects. Some would go to a somewhat reasonable Y while most would not.

The player movement code has seemed to work fine for this stage of development. Walking, jumping, bouncing off enemies have all had the desired results, so not sure what to really invest more time in on it. Most of the code is examples I have found with searches and then tweaked for what I needed.

For this stage of development I made just a small list of core components and the using/throwing of objects was the last thing I started and needed to finish and have working.

And thanks for the info on position. Still trying to get better with the Unity aspect of coding as well as my general knowledge of coding.

Thank you!!! Tried both things and the setting the minimum Y caused initial issues. I commented that code and just had the handle input moved and that fixed it!!!

Thank you so much. Hate when it’s something so simple.