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 kakasss · Jun 05, 2021 at 11:35 PM · unity 2dmovement scriptsnake

2D Snake Movement

Hi guys, I'm trying to make simple 2d snake clone. My problem is about snake movement, here is my movement code

 private void Movement2()
     {
                   
         if (Input.GetKeyDown(KeyCode.W))
         {
             if(direction != Vector3.down)
                 direction =  Vector3.up;
         }            
         if (Input.GetKeyDown(KeyCode.S) )
         {
             if(direction != Vector3.up)
                 direction = Vector3.down;
         }         
         if (Input.GetKeyDown(KeyCode.A) )
         {
             if(direction != Vector3.right)
                 direction = Vector3.left;
         }           
         if (Input.GetKeyDown(KeyCode.D) )
         {
             if(direction != Vector3.left)
                 direction = Vector3.right;
         }
             
 
         if (timer >= timetogo)
         {
             this.transform.position = new Vector3(Mathf.Round(this.transform.position.x) + direction.x,Mathf.Round(this.transform.position.y) + direction.y) ;
             
             timer = 0;
         }
 
     }

problem is as you know snake can't move opposite direction but whenever I press 2 inputs same time it can move, if I press one by one It can't.

So any idea will be helpful, thank you.

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

2 Replies

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

Answer by Earthshine · Jun 06, 2021 at 11:50 AM

Easiest way to solve the problem without dramatically changing your code would be changing all the ifs except the first one in outer layer of the if statement sequence to else ifs. I would also bring conditions from the inner layer of if statements to the outer layer and check for direction that matches the input too. Like this:

  if (Input.GetKeyDown(KeyCode.W) && direction != Vector3.down && direction != Vector3.up)
  {
          direction =  Vector3.up;
  }            
  else if(Input.GetKeyDown(KeyCode.S) && direction != Vector3.down && direction != Vector3.up)
  {
          direction = Vector3.down;
  }         
  else if(Input.GetKeyDown(KeyCode.A)  && direction != Vector3.right && direction != Vector3.left)
  {
          direction = Vector3.left;
  }           
  else if(Input.GetKeyDown(KeyCode.D)  && direction != Vector3.right && direction != Vector3.left)
  {
          direction = Vector3.right;
  }


Edit: blocking simultaneous inputs didn't solve the problem however. It became clear that the main issue is that the game passes input to direction more often than it should.

This is the actual answer: You call Movement2() in Update() every frame and pass new value to direction every frame. Then when time is >= timetogo the snake moves in direction direction.

It means you can feed several inputs to snake between two moves. It shouldn't even be simultaneous to pass. And it may be opposite to previous direction if there is an allowed input between the previous move and previously unallowed input.

It can be fixed by adding another variable for the next direction so the direction variable is constant between moves. It should work like this:

   if (Input.GetKeyDown(KeyCode.W) && direction != Vector3.down && direction != Vector3.up)
   {
           nextDirection =  Vector3.up;
   }            
   else if(Input.GetKeyDown(KeyCode.S) && direction != Vector3.down && direction != Vector3.up)
   {
           nextDirection = Vector3.down;
   }         
   else if(Input.GetKeyDown(KeyCode.A)  && direction != Vector3.right && direction != Vector3.left)
   {
           nextDirection = Vector3.left;
   }           
   else if(Input.GetKeyDown(KeyCode.D)  && direction != Vector3.right && direction != Vector3.left)
   {
           nextDirection = Vector3.right;
   }
 
  if (timer >= timetogo)
  {
 
  direction = nextDirection;
 
  this.transform.position = new Vector3(Mathf.Round(this.transform.position.x) + direction.x,Mathf.Round(this.transform.position.y) + direction.y) ;
      
      timer = 0;
  }


Comment
Add comment · Show 7 · 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 kakasss · Jun 06, 2021 at 03:39 PM 0
Share

thanks for answering, I already tried to else if statemant but result was same as here, now I tried to your code but still not working.

avatar image Earthshine kakasss · Jun 06, 2021 at 03:49 PM 0
Share

What exactly do you mean by still not working? The next if else condition wouldn't even be checked in case the previous one were met. It makes me think there's another error outside of Movement2() function. I'll test the script several hours later to be sure.

In classic snake the level is divided into squares and the game listens for the input once every time the snake's head moves to the next square. Is it the case in your project?

avatar image kakasss Earthshine · Jun 06, 2021 at 04:25 PM 0
Share

I mean its still have that bug, if snake moving right side, I press "S" and "A" same time and snake moves to left side.

Movement2 there is no error.

not exactly, but I made up something like that, I mean my player moves one by one and borders line is x 10 y 10.

Show more comments
avatar image
1

Answer by DenisIsDenis · Jun 07, 2021 at 10:39 AM

As I understand it, it is necessary that the snake cannot turn more than 90 degrees in one step. To do this, you need to introduce a variable that will store the last direction of movement of the snake. Also we need to modify the conditions.

Sample code:

     Vector3 lastDirection = Vector3.up; // "Vector3.up" if the snake looks up at the start
     private void Movement2()
     {
         if (Input.GetKeyDown(KeyCode.W) && Vector3.Angle(Vector3.up, lastDirection) == 90)
         {
             direction = Vector3.up;
         }
         if (Input.GetKeyDown(KeyCode.S) && Vector3.Angle(Vector3.down, lastDirection) == 90)
         {
             direction = Vector3.down;
         }
         if (Input.GetKeyDown(KeyCode.A) && Vector3.Angle(Vector3.left, lastDirection) == 90)
         {
             direction = Vector3.left;
         }
         if (Input.GetKeyDown(KeyCode.D) && Vector3.Angle(Vector3.right, lastDirection) == 90)
         {
             direction = Vector3.right;
         }
 
         if (timer >= timetogo)
         {
             lastDirection = direction;

             this.transform.position = new Vector3((int)this.transform.position.x + direction.x, 
                                                   (int)this.transform.position.y + direction.y);
 
             timer = 0;
         }
     }

By the way, using (int) is easier than using Mathf.Round () and differs slightly in this case.

Comment
Add comment · 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

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

131 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image 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

Enemy shakes on Y-axis when is moving straight on the X-axis 0 Answers

Unity 2D movement and rotate sprite to the direction it is moving in 1 Answer

Player Movement doesn't work, but Debug.Log shows that it should 1 Answer

How do i make a cube move (Continuosly without stopping) when i press a button once in unity 2D 2 Answers

How To Make a Snake-like Movement without Food ? [UNITY 2D] 1 Answer


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