I am trying to write a script on the enemy, that will determine if the player is to the right, left, behind or in front of the enemy so I can do sprite changes. I thought doing a simple check of the players position and comparing it to the enemy pos would work, but the code just causes MORE to be printed to the console, and i cant figure out why it is doing such.
This is the code I am trying to use, I only have the left and right code set up, but like i said, it doesnt seem to be working properly. If anyone could point out why, or give a better way of doing this detection, it would be appreciated
public Sprite[] sprites;
public Sprite[] spritesU;
public float framesPerSecond;
public Transform player;
private Vector2 EnemyPos;
private SpriteRenderer spriteRenderer;
private void Start()
{
spriteRenderer = GetComponent<SpriteRenderer>();
}
private void Update()
{
PositionCheck();
int index = (int)(Time.timeSinceLevelLoad * framesPerSecond);
index = index % sprites.Length;
spriteRenderer.sprite = sprites[index];
}
void PositionCheck()
{
if (player.position.x < EnemyPos.x)
{
Debug.Log("LESS");
}
else
{
Debug.Log("MORE");
}
}
}
thatâs a lot of math functions when you can just calculate the vector between the two and check the sign of the two components of the vector⌠OP was on the right track to do so, just was working with their world position and not the relative vector.
//not real code :P
r = A.pos - B.pos
r.x < 0 left
r.x > 0 right
r.y < 0 up
r.y > 0 down
etc. (might be off, can never remember which coords 2d use but you get the idea).
I see no code that actually assigns EnemyPos. If it is always (0,0) then of course âMOREâ is printed. You have to reference your enemy and take its position jsut like you did for the player.
When your player does not rotate then you can continue like you did. Otherwise you need to make transformations as describred in the previous posts.
I would solve this differently by using the dot product combined with some other defintions you might need.
First problem is that a trivial sequential check might short-circuit the evaluationâŚ
Suppose youâre at P(0,0,0), first enemy is at E1(100, 0, 1), second is at E2(1, 0, 100).
If you tested front first, both would be mathematically in front of you even though you (as a human being) might rather say the first enemy is on your left. Youâd need to combine and test everything and choose a result. In order to do that, you need priorities / a defintion for the subjective perception of the relative position.
If you isolate an axis and project any object onto this axis, for instance the local Z axis, any other object is always either in front of you, behind you or at the same position.
This problem does also exist when you work with angles instead, but itâs easier, shorter and cleaner to implement some additional logic.
Sorry, hoping someone will be able to help with another issue im having with this. I used Williams code above (pasted below for easy reading) and i assigned my player prefab to the transform player. But the location of the player does not seem to update when the game in running. The only way I can get the enemy script to update the player position, is to run the game then assign the player from the hierarchy. Do i need to create a prefab object in the code below then use the transform from that?
I think a decent solution is you make a reference to the player transform on the script that spawns your enemies, and then you pass the reference to the enemies that you spawn.
If you need some help, ask.
So I make the transform player, in the enemy spawning script and assign that the player prefab, How would I pass that though? Not sure if thats done withe the getComponent code? Thanks for the help
Well, just so we donât mix up our words, you should assign the player game object from the scene. That is important, as otherwise the reference wonât be valid for what you want.
Next, when you spawn the enemy, you use some code with Instantiate, right? That method returns the newly created object, so :
// somewhere outside of the method, you have:
[SerializeField]
Transform player;
public SpawnEnemy() {
GameObject newEnemy = Instantiate(enemyPrefab);
newEnemy.GetComponent<ExampleScript>().player = player; // here, we send them the valid reference
}
So i create the gameObject player, should I put that in the player code, and assign the player from the hierarchy in there. Then do your code in the enemyspawning script. The enemy spawning script it different from the animation sprite script, which is where i have the code that checks where the player is so the sprite can be determined, should I also pass the player transform to that script too?
I am a little unsure of the explanation. I realize that the spawning script is different from the one checking the relative location. Is that what you meant?
Well, maybe Iâm misunderstanding you. For instance, I do not know why your player script needs a reference to itself.
I thought we were trying to get a reference of the player to the enemy script
If I got that wrong, please just explain a few simple things:
which script needs which information (eg: is the script on the enemy or player), and does it need to know about (enemy / player)?
Then, we should be able to work out any confusion.