u know , after a week of searching , luckily i found you , this script is really simple without that bs that other youtube does , 10 minutes perfect timing explained everything in it (i watched ur other vids too, love em), you made my day so here is a new subscriber ❤👌
it shouldve only taken 30 minutes of teaching to understand everything, AT MOST! which means ur teacher sux so gl with him, many helpful yt tutorials out there
Your voice is soothing and your pace is on point. After scrapping three different AI implementations, this video finally had it dawn upon me how I should've been doing it all along! Great tutorial. THANK YOU!
This tutorial was extremely helpful. I've been looking everywhere for a code that I can actually understand and that doesn't seem unnessesarily cluttered. This was just what I've been hoping for. Thanks :)
Hey, so I have a couple of questions. So when the enemy turns, it gets really distorted for some reason. And is there a way I can use two different colliders for ground and wall detection? Thanks in advance
I understand the problem, When the enemy turns the problem is the code doesn't simply ROTATE the enemy by 180 deg. It changes the actual SCALE... so for example, if your enemy size is 5x, 5y, 5z, than when the code tells him to turn it takes the SCALE and ASSUMES it is 1x 1y 1z, and to rotate the enemy it takes the 5x and makes it -1x, so after he turns he probably would look like a stick Hope this helps 👇 Here's the fix: Your scale rotating code line probably looks like this private void OnTriggerExit2D(Collider2D collision) { transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y) } 1. First easy fix would be if it is a SPRITE and not a UI element than simply press on the sprite and in the inspector you'll see there is a "Pixels Per Unit" (default at 100) lower that number to make him bigger and go back to your enemy and set his scale back to (1x, 1y, 1z) 2. Second fix requires some code but here what you need to do - private void OnTriggerExit2D(Collider2D collision) { //transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y) < CHANGE FROM THIS //TO THIS 👇 transform.localScale = new Vector2(-transform.localScale.x, transform.localScale.y) //All this does is flip our CURRENT SIZE, which the old line doesn't do, so now you can have any size //All was done was I switched -(Mathf.Sign(myRigidbody.velocity.x)) with -transform.localScale.x }
@@kapkoder4009 So the inital code only works when the character's scale is 1x,1y,1z ? because the Mathf.Sign structure returns the number (x value) to 1? Therefore if my character has a different size than 1 it will get deformed. Is that correct?
@@violala8279 That is correct! And if your sprite is not your desired scale when it is scale 1 than all you have to do is go to your sprite in your assets and decrease the "Pixels per unit" from 100 to a lower number to make is bigger and vice versa, or maybe if your purposely stretching your sprite (say 1.5x and 1y) than you would have to use a different formula
@@IM-ws5if I know I am pretty late but I also found using transform.localScale*= new Vector2(-Mathf.Sign(myRigidbody.velocity.x),1); works too. It takes the sprites current scale and multiplies it by 1 or -1 to get the new scale. Oh wait I think I found a problem with it, when you multiply the current scale by 1, it doesn't change so you would have to multiply it by -1 each time I did find that transform.localScale*= new Vector2(-1,1); woks for now, but I may find an issue with it later on.
There's a few correction I think you could make... For one, on line 33, I don't see why you'd use a mathematical constant where precise maths isn't needed; just use 0.001f, or even better, 0f. Another shortcut you could take is skipping the whole `if(IsFacingRight())` step anyway and just set the velocity to `new Vector2(moveSpeed * Mathf.Sign(myRigidBody.velocity.x), 0f)`, which is way more efficient. ...The edge detection is a smart idea tho
When he walks to a ledge his collider exits the ledge's collider and turns, and for walls it works because the collider sticks out of the ground a little bit
Hi nice video very well made and simple code. I'm just having a problem, it detects the edge of a platform and turns around but its not turning back when it runs into a wall, what am I missing or where did my code go wrong??
I now changed the collider trigger box a bit in scale now it turns at edge of platform but when it runs into a wall its stationary and just spazms back and forth at the wall
@@dubcan4213 this is caused by the position and size of the collider, in the video I show how to set up the collider, You can also make a secondary collider to detect walls, also make sure your walls and floors are used by composite collider to decrease the amount of edges on painted tilemaps collider
@@dubcan4213 BTW if you ended up trying to use a second collider this is what you would do: ColliderType2D collider; //Whatever type of collider you chose void Start() { collider = GetComponent(); } void OnTriggerEnter2D(Collider2D collision) { if(collider.IsTouchingLayers(LayerMas. k.GetMask("Layer name"))) { //Do stuff } }
@@kapkoder4009 Thank you so much for the reply! the detection collider is getting messed up by my wall and floor colliders. Thank you so much for your help!!
@@kapkoder4009 Can I do the same thing with if(collision.gameObject.CompareTag("Wall"))? I have the problem that If I create a void OnTriggerEnter(Collider2D collision), it won't work unless I get rid of the OnTriggerExit function. What exactly do I have to write into the OnTriggerEnter so that it harmonizes with OnTriggerExit? Thanks in advance for all your efforts :)
How would you do this with an overlapbox? I want to use layers to not allow the player to redirect the enemy. A platform effector's collider mask works for now but is there a better way to do this?
I have 2D sprites but the environment is 3d. Right now the sprite is going through the 3d objects and not treating them as barriers. How could I make this work? Also, does it matter if the terrain is not completely straight. I have some diagonal slopes in the scene and I would like the patrol to continue up along the path until it hits a wall or edge like in your video. Thanks!
Even though I am 2 years late, if you or anyone else are still having this problem it's probably because BoxCollider 2Ds and Box Colliders (3d Box colliders) don't interact with each other.
it is helpful, but I got one problem, when the enemy walks away to a different direction from the no tile part, it just keep on bumping and switching between frames right to a wall,, even it it doesn't do that anymore, it goes right through the wall
I do not have an animation for my enemy, but the sprite that I am using is rotating on the z axis when moving and it won't come back to the original position. Any ideas how I can fix this? I tried to freeze the rotation from the RigidBody component but it did not work.
My character's scale needs to change on the y-axis. I did the opposite by putting y where you put x, x where you put y, but the code doesn't work, can you help?
its been a while since you posted this, but it all works fine. the only problem i have is when i place it on something that isnt a tilemap, it goes crazy between the two colliders. gotta fix?
Nice video. I'm new to Unity/C#. Do you have any ideas for how to set up a patrol where an enemy will follow the player if they see them, before returning to a patrol?
I put together this little script for you, put it on your enemy and it should work :) make sure your player has a player script too cause that's how it's found, i know how hard it is to start out coding i hope this helps. { [SerializeField] float enemySpeed = 1f; //HERE are the presets for your enemy! feel free to change any of the values here [SerializeField] float startFollowRange = 5f; //only in the inspector though because the inspectors values override these values [SerializeField] float damageRange = 0.5f; [SerializeField] float damageAgainDelay = 1f; float distance = 0f; //These check don't need to be changed anywhere cause its set by code bool damagePlayerCalled = false; bool damagedPlayer = false; GameObject player; void Start() { player = FindObjectOfType().gameObject; //Player MUST have a "Player.cs" script on it in order to find Player //player = GameObject.FindGameObjectWithTag("TagName"); //If you want to find by Tag this is what you do } void Update() { CheckForPlayer(); //We check if player is in range every frame } private void CheckForPlayer() { distance = Vector2.Distance(transform.position, player.transform.position); //calculate the distance if (distance < startFollowRange) //Check if player is in following range { MoveToPlayer(); } } private void MoveToPlayer() { transform.position = Vector2.MoveTowards(transform.position, player.transform.position, enemySpeed * Time.deltaTime); //simply moves from our position to player position if (distance < damageRange && !damagePlayerCalled) //We say "&&" to say "and" in an if statement, and i check for if damagePlayerCalled == true { //so we don't call the coroutine multiple times StartCoroutine(DamagePlayer()); } } private IEnumerator DamagePlayer() { damagePlayerCalled = true; if (damagedPlayer) { yield return new WaitForSeconds(damageAgainDelay); damagedPlayer = false; } //If first time getting in range damage immediately Debug.Log("Damage player!"); //You can put whatever you want here damagedPlayer = true; damagePlayerCalled = false; } }
Np 😂 when I first started off I spent hours and hours trying to make a 2D wandering object.. i could never find the answer on Google anywhere either lol I adventually figured it out
Hey there! So the velocity of my rigidbody is always 0 and doesn’t change when the enemy is moving. So it always rotates to the right. I tried fixing this since yesterday morning but i just don’t get it. I tried so many ways to flip the enemy but nothing works :( Maybe you could help me? Would be really great 😊
Because your rotate code uses "Mathf.Sign", and mathf.sign only rounds up to the nearest value, so it can only be 1, or -1, to fix that you would need to replace it with your own variable You could also fix this problem by just lowering the pixels per unit of your enemys sprite to make him bigger IF he is going to be a fixed size for your game
my problem is that the enemy doesn't really stop at the end of a platform. it goes some steps more as it should and flips too late, resulting him being in the air for some seconds. How can i fix this? I tried changing the box colliders and edge colliders on the ground but it still doesn't work :( My terrain has colliders too and my BoxCollider is marked as a trigger so I really don't see what i'm doing wrong
The only thing I can think of is your collider may be exiting your ground collider too late based on its size and shape or you tweaked your code in some way to delay it :/
Edit: Wow i didnt even see you replied! thank you so much!! I just fixed it by putting the collider in the middle of the enemy instead of outside of it. My next problem ist that with my current script if I kill the enemy it keeps moving... the death animation takes places, so dying actually works. but the enemy well.. still moves. do you maybe have a "Die" and "Damage" method for the enemy?
I actually figuered out how to stop him from moving. I have another question. do you know how to disable multiple colliders of one GameObject? My Enemy contains of 2 box colliders, one that's a trigger like in your video and the other for detecting collision with the ground and other objects. do you know how to disable BOTH of them in a script? What I've done only works for the "trigger" collider... the other one is still enabled when he's dead
@@lynai8273 Get a reference to both of your colliders and disable them both at once, or you can also make a game object childed to the enemy and just get a reference to that object that has the collider components and just disable that game object, but I think the first option is easier
My enemy just stops randomly and i don't see any problem with the code that i have. I tried adjusting the size of the collider but still does not work please help me how to fix this problem.
Someone also had a similar problem in the comment section... Check out MichealTheBot's comment, I replied to him the solution to the problem and also some code that you can copy/paste 👍 its very detailed
transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y); "Mathf.sign" make my character change size into 1 or -1 scale, i use 0.1.... for my character scale. what should i do?
Well you need to cache your start scale so here's (A) way to do it float xScale = 0f; void Start() { xScale = transform.localScale.x //Note that this assumes that the start scale is positive, if not than flip the xScale like this xScale = -xScale; } And do this for the flip code float x = myRigidbody.velocity.x > 0f ? xScale : -xScale; Thats a pretty complicated line but its basically a cleaner if statement like this, if x > 0 (? Question mark) firstValMeansTrue : secondValMeansFalse; transform.localScale = new Vector2(x, transform.localScale.y) Hope this helps! 😁 have an amazing day
@@SamiBeyondBorders my insta is paulkapitula if you want to message me there or you can just ask following questions here if you'd like... more comments 😉😉
did i do it corectly bc my sprite doesnt stop from walls and when he changes direction he kinda goes thin using System.Collections; using System.Collections.Generic; using UnityEngine; public class enemybehavior : MonoBehaviour { [SerializeField] float moveSpeed = 1f; Rigidbody2D myRigidbody; void Start() { myRigidbody = GetComponent(); } void Update() { if(IsFacingRight()) { myRigidbody.velocity = new Vector2(moveSpeed, 0f); }else { myRigidbody.velocity = new Vector2(-moveSpeed, 0f); } } private bool IsFacingRight() { return transform.localScale.x > Mathf.Epsilon; } private void OnTriggerExit2D(Collider2D collision) { transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y); } }
My Sprite is not moving and when my player hits the enemy object, the flip happens but it is weird, the sprite shrinks when the flip happens. keep doing vids like this and you'll be raking subs in no time. Although, you might wanna add the code in git or somewhere else and leave a link along with the assets so that it'd be useful for those who are just starting with something.
If the sprite shrinks or grows, it means it's scale was set to more or less than 1, for the sprite not moving, no idea, follow step by step his guide, maybe you missed something? (three years ago but hey, who knows)
Please help me, my character don't turn back it just stay going forward, and the scale is 1x 1y 1z and also I copy/pasted the script you put in the chat with all the requirements. PLEASE HELP MEEEEE.
Someone had this problem in the comment section, I copy and pasted my answer: I understand the problem, When the enemy turns the problem is the code doesn't simply ROTATE the enemy by 180 deg. It changes the actual SCALE... so for example, if your enemy size is 5x, 5y, 5z, than when the code tells him to turn it takes the SCALE and ASSUMES it is 1x 1y 1z, and to rotate the enemy it takes the 5x and makes it -1x, so after he turns he probably would look like a stick Hope this helps 👇 Here's the fix: Your scale rotating code line probably looks like this private void OnTriggerExit2D(Collider2D collision) { transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y) } 1. First easy fix would be if it is a SPRITE and not a UI element than simply press on the sprite and in the inspector you'll see there is a "Pixels Per Unit" (default at 100) lower that number to make him bigger and go back to your enemy and set his scale back to (1x, 1y, 1z) 2. Second fix requires some code but here what you need to do - private void OnTriggerExit2D(Collider2D collision) { //transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y) < CHANGE FROM THIS //TO THIS 👇 transform.localScale = new Vector2(-transform.localScale.x, transform.localScale.y) //All this does is flip our CURRENT SIZE, which the old line doesn't do, so now you can have any size //All was done was I switched -(Mathf.Sign(myRigidbody.velocity.x)) with -transform.localScale.x }
this is code and make him ignore collision with player and Other objects float speed = 1f; Rigidbody2D rb; BoxCollider2D bc; // Start is called before the first frame update void Start() { rb = GetComponent(); bc = GetComponent(); } // Update is called once per frame void Update() { if (isfacingright()) { rb.velocity = new Vector2(-speed, 0f); } else { rb.velocity = new Vector2(speed, 0f); } } bool isfacingright() { return transform.localScale.x > Mathf.Epsilon; } void OnTriggerExit2D(Collider2D other) { if (other.tag == "tilemap" ) { transform.localScale = new Vector2((Mathf.Sign(rb.velocity.x)), transform.localScale.y); } }
How would I change this code to make the enemy go up and down along the y axis instead? i tried changing the transform local scale to y but it did nothing
On the line "myRigidbody.velocity = new Vector2(moveSpeed, 0f);" this line sets the velocity (movement speed or direction) of the gameObject, the vector has an x and y axis "Vector2(x, y)" replace the x with 0f and put the moveSpeed in the y instead Now of course after this you'll need to make sure your collider will be changed to find vertical walls instead so you may have to tweak that meanwhile making sure the walls have colliders aswell Hope this helps sorry I'm tired rn lol
@@kapkoder4009 That's such a simple fix, thank you! As for the flipping, I got it to go up and flip and go back down, but it stops after that and doesn't flip again, any thoughts?
Make sure the terrain has colliders too and the enemy collider is setup properly Also make sure your enemy collider is set to trigger so it can call the OnTriggerEnter2D function
Heres the code for "Enemy Platformer patrol" hope it's what you need { //This isn't just cut and dry copy and paste code! here's the requirements: //TODO - make sure you have a Rigidbody2D component on your enemy //TODO - make sure you have a BoxCollider2D setup on the edge of your enemy (as // - wall & ground detection, setup instruction in video) [SerializeField] float moveSpeed = 1f; //This movement speed is tweakable in the inspector Rigidbody2D myRigidbody; private void Start() { myRigidbody = GetComponent(); } private void Update() { if(IsFacingRight()) { myRigidbody.velocity = new Vector2(moveSpeed, 0f); } else { myRigidbody.velocity = new Vector2(-moveSpeed, 0f); } } private bool IsFacingRight() //Automatically set direction { return transform.localScale.x > Mathf.Epsilon; } private void OnTriggerExit2D(Collider2D collision) //Checks for wall/ground detection { transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y); } }
I realized the issue. I had an animation, changing the scale of the enemy, which also kept moving the collider. I moved the animation/sprite to a child game object
a lot simpler than code i use (from Blathornprod guide) where i need to set 2 or more patrolpoints, and to make my enemy go back, i need to set rotation on my 2nd patrolpoint to 180 on y
u know , after a week of searching , luckily i found you , this script is really simple without that bs that other youtube does , 10 minutes perfect timing explained everything in it (i watched ur other vids too, love em), you made my day so here is a new subscriber ❤👌
Man I have been watching different videos for two hours. Your code has been the only one that has worked. Thank you so much
Somehow you said everything I needed in 10 minutes when my teacher gave me nothing over a half hour
it shouldve only taken 30 minutes of teaching to understand everything, AT MOST!
which means ur teacher sux so gl with him, many helpful yt tutorials out there
Your voice is soothing and your pace is on point.
After scrapping three different AI implementations, this video finally had it dawn upon me how I should've been doing it all along!
Great tutorial. THANK YOU!
This tutorial was extremely helpful. I've been looking everywhere for a code that I can actually understand and that doesn't seem unnessesarily cluttered. This was just what I've been hoping for. Thanks :)
Thank you GameDevTV to bring this tutorial to you :D
Thank you so much!! This is the only tutorial I've seen that actually works and isn't 2 fps :DDD
Hehe I think it's 30fps 😼
I saw many videos but all of them were so complicated but yours so simple loved it
This tutorial earned you at least one new subscriber.
Keep it up & thanks!
Glad it helped you! Thanks for the sub
A deep Thank you from Vietnam to you ;D
great tutorial, very simple and to the point
Thank you very much this code was helpful for my universal project.❤❤❤
How does the neemy detect they've hit a wall ?
nice tutorial but im having trouble understanding why this works with walls and edges and not JUST edges?
This tutorial is so helpful that i will give you a sub, thx bro
better guide than Brackeys!
great and effective code. Thanks a lot
Hey, so I have a couple of questions. So when the enemy turns, it gets really distorted for some reason. And is there a way I can use two different colliders for ground and wall detection? Thanks in advance
I understand the problem, When the enemy turns the problem is the code doesn't simply ROTATE the enemy by 180 deg. It changes the actual SCALE... so for example, if your enemy size is 5x, 5y, 5z, than when the code tells him to turn it takes the SCALE and ASSUMES it is 1x 1y 1z, and to rotate the enemy it takes the 5x and makes it -1x, so after he turns he probably would look like a stick
Hope this helps 👇
Here's the fix:
Your scale rotating code line probably looks like this
private void OnTriggerExit2D(Collider2D collision)
{
transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y)
}
1. First easy fix would be if it is a SPRITE and not a UI element than simply press on the sprite and in the inspector you'll see there is a "Pixels Per Unit" (default at 100) lower that number to make him bigger and go back to your enemy and set his scale back to (1x, 1y, 1z)
2. Second fix requires some code but here what you need to do -
private void OnTriggerExit2D(Collider2D collision)
{
//transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y) < CHANGE FROM THIS
//TO THIS 👇
transform.localScale = new Vector2(-transform.localScale.x, transform.localScale.y)
//All this does is flip our CURRENT SIZE, which the old line doesn't do, so now you can have any size
//All was done was I switched -(Mathf.Sign(myRigidbody.velocity.x)) with -transform.localScale.x
}
@@kapkoder4009 So the inital code only works when the character's scale is 1x,1y,1z ? because the Mathf.Sign structure returns the number (x value) to 1?
Therefore if my character has a different size than 1 it will get deformed. Is that correct?
@@violala8279 That is correct! And if your sprite is not your desired scale when it is scale 1 than all you have to do is go to your sprite in your assets and decrease the "Pixels per unit" from 100 to a lower number to make is bigger and vice versa, or maybe if your purposely stretching your sprite (say 1.5x and 1y) than you would have to use a different formula
@@kapkoder4009 Thank you very much, I wish you luck
@@IM-ws5if I know I am pretty late but I also found using transform.localScale*= new Vector2(-Mathf.Sign(myRigidbody.velocity.x),1); works too. It takes the sprites current scale and multiplies it by 1 or -1 to get the new scale.
Oh wait I think I found a problem with it, when you multiply the current scale by 1, it doesn't change so you would have to multiply it by -1 each time
I did find that transform.localScale*= new Vector2(-1,1); woks for now, but I may find an issue with it later on.
Great tutorial! But how can i make him ignore collision with player controlled object?
void OnTriggerExit2D(Collider2D other)
{
if (other.tag == "ground" || other.tag == "wall")
{
transform.localScale = new Vector2((Mathf.Sign(rb.velocity.x)), transform.localScale.y);
}
}
Thanks, it's really easy and useful.
There's a few correction I think you could make... For one, on line 33, I don't see why you'd use a mathematical constant where precise maths isn't needed; just use 0.001f, or even better, 0f. Another shortcut you could take is skipping the whole `if(IsFacingRight())` step anyway and just set the velocity to `new Vector2(moveSpeed * Mathf.Sign(myRigidBody.velocity.x), 0f)`, which is way more efficient.
...The edge detection is a smart idea tho
I made this video a year ago lol
@@kapkoder4009 then correct it
it worked, thanks for that.
That's great, I just don't understand why it also turns when it hit the wall if it's an OnTriggerExit.
When he walks to a ledge his collider exits the ledge's collider and turns, and for walls it works because the collider sticks out of the ground a little bit
I'd love a tutorial on bullets/objects bouncing off of walls and destroying once they hit a certain point cx
how can I use another collider for detecting
nice awesome great epic fantastic
Which compiler are you using?
Thank you thank you thank you!!!!🙇♀
great tutorial :)
Hi nice video very well made and simple code. I'm just having a problem, it detects the edge of a platform and turns around but its not turning back when it runs into a wall, what am I missing or where did my code go wrong??
I now changed the collider trigger box a bit in scale now it turns at edge of platform but when it runs into a wall its stationary and just spazms back and forth at the wall
@@dubcan4213 this is caused by the position and size of the collider, in the video I show how to set up the collider, You can also make a secondary collider to detect walls, also make sure your walls and floors are used by composite collider to decrease the amount of edges on painted tilemaps collider
@@dubcan4213 BTW if you ended up trying to use a second collider this is what you would do:
ColliderType2D collider; //Whatever type of collider you chose
void Start()
{
collider = GetComponent();
}
void OnTriggerEnter2D(Collider2D collision)
{
if(collider.IsTouchingLayers(LayerMas. k.GetMask("Layer name")))
{
//Do stuff
}
}
@@kapkoder4009 Thank you so much for the reply! the detection collider is getting messed up by my wall and floor colliders. Thank you so much for your help!!
@@kapkoder4009 Can I do the same thing with if(collision.gameObject.CompareTag("Wall"))? I have the problem that If I create a void OnTriggerEnter(Collider2D collision), it won't work unless I get rid of the OnTriggerExit function. What exactly do I have to write into the OnTriggerEnter so that it harmonizes with OnTriggerExit? Thanks in advance for all your efforts :)
thank you very much!
How would you do this with an overlapbox? I want to use layers to not allow the player to redirect the enemy.
A platform effector's collider mask works for now but is there a better way to do this?
I have 2D sprites but the environment is 3d. Right now the sprite is going through the 3d objects and not treating them as barriers. How could I make this work? Also, does it matter if the terrain is not completely straight. I have some diagonal slopes in the scene and I would like the patrol to continue up along the path until it hits a wall or edge like in your video. Thanks!
Even though I am 2 years late, if you or anyone else are still having this problem it's probably because BoxCollider 2Ds and Box Colliders (3d Box colliders) don't interact with each other.
the enemy is not only squished but just walks endlessly
That is GameDev 2D Game Dev Course on Udemy
Yup I just wanted to share it because the information isn't really accesable on youtube
@@kapkoder4009 ya, you are right .
but you could have give them credits .
i am sure Rick wouldn't mind but they deserve it xD
@@husseinrizk8933 I should put it in the description
@@kapkoder4009 I think you should
This Tutorial is Great! Just one thing, whenever my charactor turns his renderer disables.
void OnTriggerExit2D(Collider2D other)
{
if (other.tag == "ground" || other.tag == "wall")
{
transform.localScale = new Vector2((Mathf.Sign(rb.velocity.x)), transform.localScale.y);
}
}
very very thanks😀
it is helpful, but I got one problem, when the enemy walks away to a different direction from the no tile part, it just keep on bumping and switching between frames right to a wall,, even it it doesn't do that anymore, it goes right through the wall
why i cannot use serializefield? is there some kind of extension that I need?
I do not have an animation for my enemy, but the sprite that I am using is rotating on the z axis when moving and it won't come back to the original position. Any ideas how I can fix this? I tried to freeze the rotation from the RigidBody component but it did not work.
My character's scale needs to change on the y-axis. I did the opposite by putting y where you put x, x where you put y, but the code doesn't work, can you help?
How can i make an object wandering within the screen please help.🙏
its been a while since you posted this, but it all works fine. the only problem i have is when i place it on something that isnt a tilemap, it goes crazy between the two colliders. gotta fix?
hey man, did u happen to fix this issue?
nope, i went to something else after i couldnt fix this lmao
@@Narddz vur if you figured out a fix ide be happy to go back to my project
are you using a composite collider on the tilemap? that should fix the issue
dude you climbed up youtube
really good tutorial but changing my move speed value dosn`t do anything. can someone help me ?
OnTriggerExit2D is making problems for some reason does anyone know why?
hey can you help me with my enemy because the enemy didnt flip after hitting the wall and i dont know why
Nice video. I'm new to Unity/C#. Do you have any ideas for how to set up a patrol where an enemy will follow the player if they see them, before returning to a patrol?
Do you need this for a 2D platform type of enemy?
@@kapkoder4009 it's for a top down 2d
I put together this little script for you, put it on your enemy and it should work :)
make sure your player has a player script too cause that's how it's found,
i know how hard it is to start out coding i hope this helps.
{
[SerializeField] float enemySpeed = 1f; //HERE are the presets for your enemy! feel free to change any of the values here
[SerializeField] float startFollowRange = 5f; //only in the inspector though because the inspectors values override these values
[SerializeField] float damageRange = 0.5f;
[SerializeField] float damageAgainDelay = 1f;
float distance = 0f; //These check don't need to be changed anywhere cause its set by code
bool damagePlayerCalled = false;
bool damagedPlayer = false;
GameObject player;
void Start()
{
player = FindObjectOfType().gameObject; //Player MUST have a "Player.cs" script on it in order to find Player
//player = GameObject.FindGameObjectWithTag("TagName"); //If you want to find by Tag this is what you do
}
void Update()
{
CheckForPlayer(); //We check if player is in range every frame
}
private void CheckForPlayer()
{
distance = Vector2.Distance(transform.position, player.transform.position); //calculate the distance
if (distance < startFollowRange) //Check if player is in following range
{
MoveToPlayer();
}
}
private void MoveToPlayer()
{
transform.position = Vector2.MoveTowards(transform.position, player.transform.position, enemySpeed * Time.deltaTime); //simply moves from our position to player position
if (distance < damageRange && !damagePlayerCalled) //We say "&&" to say "and" in an if statement, and i check for if damagePlayerCalled == true
{ //so we don't call the coroutine multiple times
StartCoroutine(DamagePlayer());
}
}
private IEnumerator DamagePlayer()
{
damagePlayerCalled = true;
if (damagedPlayer) { yield return new WaitForSeconds(damageAgainDelay); damagedPlayer = false; } //If first time getting in range damage immediately
Debug.Log("Damage player!"); //You can put whatever you want here
damagedPlayer = true;
damagePlayerCalled = false;
}
}
Thank you so much! I've been struggling so hard. Haha. Will subscribe for more content!
Np 😂 when I first started off I spent hours and hours trying to make a 2D wandering object.. i could never find the answer on Google anywhere either lol I adventually figured it out
Hey there! So the velocity of my rigidbody is always 0 and doesn’t change when the enemy is moving. So it always rotates to the right. I tried fixing this since yesterday morning but i just don’t get it. I tried so many ways to flip the enemy but nothing works :( Maybe you could help me? Would be really great 😊
Show me da code
Hello I have a question, why is it sticking to my pillar/tower? Its flipping and moving but its stuck between it. Need help.
Make sure your ground check collider is set up properly, this does all your ground and wall detection
hi if I scale my enemy up when it rotates the x becomes -1 instead of -3 is there a fix for that?
Because your rotate code uses "Mathf.Sign", and mathf.sign only rounds up to the nearest value, so it can only be 1, or -1, to fix that you would need to replace it with your own variable
You could also fix this problem by just lowering the pixels per unit of your enemys sprite to make him bigger IF he is going to be a fixed size for your game
@@kapkoder4009 Thank you I will probably use pixels per unit method !
how do you do it so it has an animation when it moves?
Search for "Brackeys how to make animations 2d game in unity"
my problem is that the enemy doesn't really stop at the end of a platform. it goes some steps more as it should and flips too late, resulting him being in the air for some seconds. How can i fix this? I tried changing the box colliders and edge colliders on the ground but it still doesn't work :( My terrain has colliders too and my BoxCollider is marked as a trigger so I really don't see what i'm doing wrong
The only thing I can think of is your collider may be exiting your ground collider too late based on its size and shape or you tweaked your code in some way to delay it :/
Edit: Wow i didnt even see you replied! thank you so much!!
I just fixed it by putting the collider in the middle of the enemy instead of outside of it. My next problem ist that with my current script if I kill the enemy it keeps moving... the death animation takes places, so dying actually works. but the enemy well.. still moves. do you maybe have a "Die" and "Damage" method for the enemy?
I actually figuered out how to stop him from moving. I have another question. do you know how to disable multiple colliders of one GameObject? My Enemy contains of 2 box colliders, one that's a trigger like in your video and the other for detecting collision with the ground and other objects. do you know how to disable BOTH of them in a script? What I've done only works for the "trigger" collider... the other one is still enabled when he's dead
@@lynai8273 Get a reference to both of your colliders and disable them both at once, or you can also make a game object childed to the enemy and just get a reference to that object that has the collider components and just disable that game object, but I think the first option is easier
couldn't you just flip the sprite instead of negating the localScale?
My enemy just stops randomly and i don't see any problem with the code that i have.
I tried adjusting the size of the collider but still does not work
please help me how to fix this problem.
Hmm... I wouldn't know what to do unless I saw the code
hello my enemy doesn turn around he just goes forward what should i do ?
Never mind i fixed that but next problem my enemy changes scale when it first hits the edge
Someone also had a similar problem in the comment section... Check out MichealTheBot's comment, I replied to him the solution to the problem and also some code that you can copy/paste 👍 its very detailed
@@kapkoder4009 Thank you
@@kapkoder4009 and btw do you know a way to make enemy attack player ??
@@jaykztvn for a 2D platformer or top down?
My trigger hitbox is not wroking, hes just walking straight in the air any ideas why?
Check all your colliders
transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y);
"Mathf.sign" make my character change size into 1 or -1 scale, i use 0.1.... for my character scale. what should i do?
Well you need to cache your start scale so here's (A) way to do it
float xScale = 0f;
void Start()
{
xScale = transform.localScale.x
//Note that this assumes that the start scale is positive, if not than flip the xScale like this
xScale = -xScale;
}
And do this for the flip code
float x = myRigidbody.velocity.x > 0f ? xScale : -xScale;
Thats a pretty complicated line but its basically a cleaner if statement like this, if x > 0 (? Question mark) firstValMeansTrue : secondValMeansFalse;
transform.localScale = new Vector2(x, transform.localScale.y)
Hope this helps! 😁 have an amazing day
Hey my enemy makes that what he is supossed to do but he slowly sink in to the ground 😅
Maybe its rigidbody has gravity enabled? Or in your code your not adding 0 force on the y vector
@@kapkoder4009 i gonna try it
@@kapkoder4009 i dont check it cause its my first game can i have your insta or something like that so you could look at the code
@@kapkoder4009 but my rigidbody should be ok
@@SamiBeyondBorders my insta is paulkapitula if you want to message me there or you can just ask following questions here if you'd like... more comments 😉😉
I LOVE YOU
@@parker3739 😘
did i do it corectly bc my sprite doesnt stop from walls and when he changes direction he kinda goes thin
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemybehavior : MonoBehaviour
{
[SerializeField] float moveSpeed = 1f;
Rigidbody2D myRigidbody;
void Start()
{
myRigidbody = GetComponent();
}
void Update()
{
if(IsFacingRight())
{
myRigidbody.velocity = new Vector2(moveSpeed, 0f);
}else
{
myRigidbody.velocity = new Vector2(-moveSpeed, 0f);
}
}
private bool IsFacingRight()
{
return transform.localScale.x > Mathf.Epsilon;
}
private void OnTriggerExit2D(Collider2D collision)
{
transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y);
}
}
Your code looks completely fine... my you need to configure your colliders??
My Sprite is not moving and when my player hits the enemy object, the flip happens but it is weird, the sprite shrinks when the flip happens.
keep doing vids like this and you'll be raking subs in no time. Although, you might wanna add the code in git or somewhere else and leave a link along with the assets so that it'd be useful for those who are just starting with something.
If the sprite shrinks or grows, it means it's scale was set to more or less than 1, for the sprite not moving, no idea, follow step by step his guide, maybe you missed something? (three years ago but hey, who knows)
I prefer this way of flipping a sprite:
Vector3 localScale = transform.localScale;
localScale.x *= -1f;
transform.localScale = localScale;
for some reason, my enemy does not rotate and keeps walking through the tiles can somebody help ?
ok i fixed it i was missing the 2d on the OnTriggerExit2D
Please help me, my character don't turn back it just stay going forward, and the scale is 1x 1y 1z and
also I copy/pasted the script you put in the chat with all the requirements. PLEASE HELP MEEEEE.
Someone had this problem in the comment section, I copy and pasted my answer:
I understand the problem, When the enemy turns the problem is the code doesn't simply ROTATE the enemy by 180 deg. It changes the actual SCALE... so for example, if your enemy size is 5x, 5y, 5z, than when the code tells him to turn it takes the SCALE and ASSUMES it is 1x 1y 1z, and to rotate the enemy it takes the 5x and makes it -1x, so after he turns he probably would look like a stick
Hope this helps 👇
Here's the fix:
Your scale rotating code line probably looks like this
private void OnTriggerExit2D(Collider2D collision)
{
transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y)
}
1. First easy fix would be if it is a SPRITE and not a UI element than simply press on the sprite and in the inspector you'll see there is a "Pixels Per Unit" (default at 100) lower that number to make him bigger and go back to your enemy and set his scale back to (1x, 1y, 1z)
2. Second fix requires some code but here what you need to do -
private void OnTriggerExit2D(Collider2D collision)
{
//transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y) < CHANGE FROM THIS
//TO THIS 👇
transform.localScale = new Vector2(-transform.localScale.x, transform.localScale.y)
//All this does is flip our CURRENT SIZE, which the old line doesn't do, so now you can have any size
//All was done was I switched -(Mathf.Sign(myRigidbody.velocity.x)) with -transform.localScale.x
}
forget I fixed it
I just put a box collider in the floor XD
@@ultrabikeboy I was asleep, but glad you fixed it! And yeah I reply as much as I can 😂
this is code and make him ignore collision with player and Other objects
float speed = 1f;
Rigidbody2D rb;
BoxCollider2D bc;
// Start is called before the first frame update
void Start()
{
rb = GetComponent();
bc = GetComponent();
}
// Update is called once per frame
void Update()
{
if (isfacingright())
{
rb.velocity = new Vector2(-speed, 0f);
}
else
{
rb.velocity = new Vector2(speed, 0f);
}
}
bool isfacingright()
{
return transform.localScale.x > Mathf.Epsilon;
}
void OnTriggerExit2D(Collider2D other)
{
if (other.tag == "tilemap" )
{
transform.localScale = new Vector2((Mathf.Sign(rb.velocity.x)), transform.localScale.y);
}
}
Thanks for your help! It fixed my problem.
How would I change this code to make the enemy go up and down along the y axis instead? i tried changing the transform local scale to y but it did nothing
On the line
"myRigidbody.velocity = new Vector2(moveSpeed, 0f);"
this line sets the velocity (movement speed or direction) of the gameObject, the vector has an x and y axis "Vector2(x, y)" replace the x with 0f and put the moveSpeed in the y instead
Now of course after this you'll need to make sure your collider will be changed to find vertical walls instead so you may have to tweak that meanwhile making sure the walls have colliders aswell
Hope this helps sorry I'm tired rn lol
@@kapkoder4009 That's such a simple fix, thank you! As for the flipping, I got it to go up and flip and go back down, but it stops after that and doesn't flip again, any thoughts?
yeah my enemy is just going through everything. even with the box colliders......
Make sure the terrain has colliders too and the enemy collider is setup properly
Also make sure your enemy collider is set to trigger so it can call the OnTriggerEnter2D function
please help my enemy still not turn when he hits the wall :/
Try adjusting your wall detection collider, and make sure yours walls have colliders swell
This distorts my enemies resolution
we need downloadd scrept
Could you give me the code to put into my project? sorry, kinda lazy coder .-.
Sure thing xD gimme a sec
Heres the code for "Enemy Platformer patrol" hope it's what you need
{
//This isn't just cut and dry copy and paste code! here's the requirements:
//TODO - make sure you have a Rigidbody2D component on your enemy
//TODO - make sure you have a BoxCollider2D setup on the edge of your enemy (as
// - wall & ground detection, setup instruction in video)
[SerializeField] float moveSpeed = 1f; //This movement speed is tweakable in the inspector
Rigidbody2D myRigidbody;
private void Start()
{
myRigidbody = GetComponent();
}
private void Update()
{
if(IsFacingRight())
{
myRigidbody.velocity = new Vector2(moveSpeed, 0f);
} else
{
myRigidbody.velocity = new Vector2(-moveSpeed, 0f);
}
}
private bool IsFacingRight() //Automatically set direction
{
return transform.localScale.x > Mathf.Epsilon;
}
private void OnTriggerExit2D(Collider2D collision) //Checks for wall/ground detection
{
transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), transform.localScale.y);
}
}
Kap Koder Hey this is me from my second account, THANKS SO MUCH!! i’ll sub on both accounts when i get the chance!!
Haha thanks 😂
4:58
My guy never turns around, just keeps going straight. I even copied your code completely. What could I be doing wrong?
I realized the issue. I had an animation, changing the scale of the enemy, which also kept moving the collider. I moved the animation/sprite to a child game object
Make sure your ground and walls have a collider and you set up your enemies collider correctly
a lot simpler than code i use (from Blathornprod guide) where i need to set 2 or more patrolpoints, and to make my enemy go back, i need to set rotation on my 2nd patrolpoint to 180 on y