Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by MrCalavera · Apr 21, 2013 at 08:24 PM · c#2dcollision detectiontransform.translateroguelike

2D movement with transform.translate and collision detection...?

Hi there, this might end up as a long question but I'll try to provide as much information as possible.

I'm looking for a bit of help with collision detection. I'm prototyping a 2D top down roguelike. At the moment I have a Player cube that can move up, down, left and right, one square at a time. Every time they move there is a chance to spawn an enemy from an enemyPrefab. If the enemy is within a certain distance of the player, the enemy will move towards the player one square at a time every time the player moves (every turn). This all works reasonably well but all movement is done with transform.translate.

At present the enemies will move towards the player and then come to occupy the same square as the player. What I would like them to do is stop in the adjacent square instead and then spend subsequent turns attacking the player, additionally if the player attempts to move onto the square occupied by the enemy I want them to instead attack the enemy. Once the enemy is dead the player can move over their square.

I'm assuming to do the things I want, I'm going to need collision detection, am I right? After doing some research it would appear that collision detection doesn't seem to work with transform.translate, is that correct?

Does anyone have any advice for how I could proceed?

Thanks.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by DESTRUKTORR · Apr 21, 2013 at 09:16 PM

Check if the distance between the player's position and the enemy's position is equal to the distance for one square. This check will be different, depending on whether diagonal moves are legal, in your game. If they are, it should look something like this:

 if(Vector2.Distance(transform.position, player.transform.position) > gridDistance)
 {
     //move toward player
 }

if diagonal movements are -illegal- (in other words, you only want the units moving along the cardinal directions), simply check distance like this:

 float xDist = Mathf.Abs(transform.position.x - player.transform.position.x);
 float yDist = Mathf.Abs(transform.position.y - player.transform.position.y);
 if((xDist > gridDistance && yDist < 0.01f) 
     || (yDist > gridDistance && xDist < 0.01f))
 {
     //move toward player
 }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image MrCalavera · Apr 22, 2013 at 10:34 AM 0
Share

Your second suggestion works excellently for my enemies. They now stop in whatever player adjacent square they land in and i've added a debug log for the moment to say they're attacking. So thank you very much.

$$anonymous$$y problem now is that if I move my player towards the enemy, they will land in the same square as the enemy.

So would I be able to use oncollisionenter to block movement onto an enemy square and ins$$anonymous$$d attack? Or do I need to find a different code solution for my player?

avatar image DESTRUKTORR · Apr 28, 2013 at 08:28 PM 0
Share

There's a good number of ways you could handle that, just as there are likely several ways to handle the problem I discussed in my answer. Just checking distances tends to be easier, and more reliable than collision checks, I$$anonymous$$O. However, I'm guessing you're saying that if you select the adjacent square (or one within attack range) that is occupied by an enemy, that you want to attack them, in s$$anonymous$$d of moving to that square? Assu$$anonymous$$g you're running this with a 2-directional grid, you may want to use the "On$$anonymous$$ouseDown" method from within a monobehaviour attached to the grid tile. As well, it would simplify the problem if each tile kept track of whether or not a unit occupied its space (and had an object reference to that unit). For example:

 void On$$anonymous$$ouseDown()
 {
     float distance = Vector3.Distance(transform.position, player.transform.position);
     if(Input.Get$$anonymous$$ouseDown(0) && distance  <= maxDistancePlayerCanTravel)
     {
         if(occupyingUnit && occupyingUnit is Enemy && distance <= player.maxAttackRange)
         {
             //Player attacks enemy
         }
         else if(!occupyingUnit)
         {
             //Player moves to space
         }
         else
         {
             //You would only need this else if there was 
             //something else to do, here.  Otherwise, omit it.
         }
     }
 }

[edit] However, to calculate the distance the player would need to travel, if you're using a 2-directional grid, this can be a bit easier. It would look roughly like this (just calculating distance, not including the rest of the above code):

 int distance = (int)$$anonymous$$athf.Abs(this.x - player.currentTile.x + this.y - player.currentTile.y);


Be aware that this will give you the number of tiles needed for the player to move from their current position to the target tile, not the euclidian distance between those tiles (which is what Vector3.Distance(Vector3 start, Vector3 end) gives us, which is not accurate if diagonal movements are illegal, or if movements are incremented by grid spaces, and not decimal distance).

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Enemies Jump at Random with Coroutines 2d (C#) Error. 0 Answers

OnCollision2D will not work for me 1 Answer

Bullet hit the collider of a child object 1 Answer

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges