Does anyone know why transform.position isn't working? (See details)
So I've been working on making a game for about a month or two now and in the game there is a cow (see image below) and I wrote some code for it to go to a specified location:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class spawn : MonoBehaviour
{
public Vector2 cowStart;
// Start is called before the first frame update
void Start()
{
transform.position = cowStart;
}
}
In the inspector in unity, I have 'cowStart' set to (0, 0) but I have also tried setting it to things like (1,0) and changing the numbers. There is only one other script applied to the cow and it just makes it move. I'm fairly certain it's not doing anything to affect the position in a way that would sent it to the same location every time I start the game (I looked through it several times) but just in case, here is the code: (It's really long so feel free to skip it)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CowMove : MonoBehaviour
{
//variables for speed, direction, etc.
public float direction; //1-8 (See diagram below)
//vectors for where to lerp to.
Vector2 pos1;
Vector2 pos2;
Vector2 pos3;
Vector2 pos4;
Vector2 pos5;
Vector2 pos6;
Vector2 pos7;
Vector2 pos8;
public float speed;
public float timeX;
//Bools to control animation
public bool speedCheck;
//SPEED DIAGRAM
// *--[0]---[1]---[2]--*
//DIRECTION DIAGRAM
// <^ ^ ^>
// \ | /
// 1 2 3
// < - 8 4 - >
// 7 6 5
// / | \
// <v v v>
//NOTE: Diagonals are a difference of ~0.7 on the X and Y axis, whereas the vert and horiz ones are exactly 1.
//get the renderer to flip the sprite when it's moving to the right or left
public SpriteRenderer spRenderer;
void Start()
{
spRenderer = GetComponent<SpriteRenderer>();
float side = Random.Range(1, 3);
if (side == 1)
{
spRenderer.flipX = !spRenderer.flipX;
}
else if (side == 2)
{
spRenderer.flipX = !spRenderer.flipX;
}
}
void Update()
{
direction = Random.Range(1, 9);
//activate different lerp voids depending on the direction value
if (direction == 1)
{
//left up
dir1();
}
else if (direction == 2)
{
//up
dir2();
}
else if (direction == 3)
{
//up right
dir3();
}
else if (direction == 4)
{
//right
dir4();
}
else if (direction == 5)
{
//right down
dir5();
}
else if (direction == 6)
{
//down
dir6();
}
else if (direction == 7)
{
//down left
dir7();
}
else if (direction == 8)
{
//left
dir8();
}
//set each pos vector to the cow's position plus the default values.
pos1 = new Vector2(transform.position.x - 0.7f, transform.position.y + 0.7f) * speed;
pos2 = new Vector2(transform.position.x, transform.position.y + 1) * speed;
pos3 = new Vector2(transform.position.x + 0.7f, transform.position.y + 0.7f) * speed;
pos4 = new Vector2(transform.position.x + 1, transform.position.y) * speed;
pos5 = new Vector2(transform.position.x + 0.7f, transform.position.y - 0.7f) * speed;
pos6 = new Vector2(transform.position.x, transform.position.y - 1) * speed;
pos7 = new Vector2(transform.position.x - 0.7f, transform.position.y - 0.7f) * speed;
pos8 = new Vector2(transform.position.x - 1, transform.position.y) * speed;
}
void dir1() //left
{
//transform.position = Vector2.Lerp(transform.position, destination, Time.deltaTime);
transform.position = Vector2.Lerp(transform.position, pos1, Time.deltaTime * timeX);
}
void dir2()
{
//transform.position = Vector2.Lerp(transform.position, destination, Time.deltaTime);
transform.position = Vector2.Lerp(transform.position, pos2, Time.deltaTime * timeX);
}
void dir3() //right
{
//transform.position = Vector2.Lerp(transform.position, destination, Time.deltaTime);
transform.position = Vector2.Lerp(transform.position, pos3, Time.deltaTime * timeX);
}
void dir4() //right
{
//transform.position = Vector2.Lerp(transform.position, destination, Time.deltaTime);
transform.position = Vector2.Lerp(transform.position, pos4, Time.deltaTime * timeX);
}
void dir5() //right
{
//transform.position = Vector2.Lerp(transform.position, destination, Time.deltaTime);
transform.position = Vector2.Lerp(transform.position, pos5, Time.deltaTime * timeX);
}
void dir6()
{
//transform.position = Vector2.Lerp(transform.position, destination, Time.deltaTime);
transform.position = Vector2.Lerp(transform.position, pos6, Time.deltaTime * timeX);
}
void dir7() //left
{
//transform.position = Vector2.Lerp(transform.position, destination, Time.deltaTime);
transform.position = Vector2.Lerp(transform.position, pos7, Time.deltaTime * timeX);
}
void dir8() //left
{
//transform.position = Vector2.Lerp(transform.position, destination, Time.deltaTime);
transform.position = Vector2.Lerp(transform.position, pos8, Time.deltaTime * timeX);
}
}
The problem is that every time I start the game, the cow goes to the exact same position: (-2.93496, -0.0168) and I have no clue why or how to fix this. Does anyone know how to get it to go to the right position? I eventually want to have 8-16 cows on the screen but when I do that, no matter how I arrange them, they go to the same spot. Here's the picture for reference:
Answer by Bunny83 · Oct 19, 2021 at 09:15 AM
Well, you have several issues in your code. First of all you have a general ordering issue. You first call your "dir" methods which do the lerping towards one of the positions and after that you actually set your pos variable. That means in the very first frame all those pos variables will be (0,0,0) and you lerp towards that in the first frame.
Second issue is that you assumed your "pos" variable are positions. However you multiplied the position by speed which makes no sense whatsoever. If something is located say at (25,3) and your speed is 10 that would turn the "position" into (250,30) which is probably even off screen. Speeds should only applied to the change of the position, in your case your "+0.7f" / "-0.7f".
Finally your main issue is your overall structure. You have extremely overcomplicated the whole thing. seperating out 8 methods which are poorly named and each method executes a single instruction makes not much sense.
Another conceptional issue you have is your "flipping" code in start. Apart from rolling an integer random number that is either 1 or 2 that you store in a float variable for some reason to then compare it against an integer again, the main issue is that both cases do the same thing, flipping the sprite. So no matter what you always flip.
Also lerp is a very bad way for moving things around, especially the way you use it. It makes things framerate dependent since you use it to do a non linear movement.
Your whole class could be simplified to:
public class CowMove : MonoBehaviour
{
// <^ ^ ^>
// \ | /
// 0 1 2
// < - 7 3 - >
// 6 5 4
// / | \
// <v v v>
public SpriteRenderer spRenderer;
public int direction;
public float speed;
private Vector2[] directions = new Vector2[]{
new Vector2(-1, 1), // up left
new Vector2( 0, 1), // up
new Vector2( 1, 1), // up right
new Vector2( 1, 0), // right
new Vector2( 1,-1), // down right
new Vector2( 0,-1), // down
new Vector2(-1,-1), // down left
new Vector2(-1, 0), // left
};
void Start()
{
spRenderer = GetComponent<SpriteRenderer>();
spRenderer.flipX = Random.value > 0.5f;
}
void Update()
{
direction = Random.Range(0, directions.Length);
transform.position += directions[direction] * speed * Time.deltaTime;
}
}
Of course note that choosing a new random direction every frame would result into a jittery mess. You usually want to pick a target every couple of seconds or when it reaches the target and not every frame. However that's a game design decision you have to make.
Note I changed your direction to be 0 to 7 instead of 1 to 8. Almost all programmers start counting at 0 ^^. In all C-style languages indices are 0 based which is the natural choice anyways. Yes, there are some languages out there (mostly interpreted scripting languages like lua) which start counting at 1. However this creates tons of issues with almost any forumla or equation where you may include that variable.
Bunny83, thank you for the answer. Sorry about the late response. The code you wrote was incredibly helpful. The game is working much better now, but using transform.position to send the cow to a starting point still isn't working. Any ideas/suggestions?
Never$$anonymous$$d, I figured out the problem. I had a transform.position in another code file. I thought the script was inactive on start but it was not, but I have it fixed now.
Your answer
Follow this Question
Related Questions
Hey Guys How to make a script 'private Transform Waypoint;, 0 Answers
Have object fly towards camera 0 Answers
Player floats in air when i enter play mode 0 Answers
How to make an enemy attack you when he is attacked by you ???? 0 Answers
Hi guys, please tell me or give a link to the lesson. 2 Answers