• 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 Cherno · Apr 08, 2013 at 05:57 PM · movementupdate

Double movement on key down (Update/frame problem?)

I am creating a tile-based 3D FPS, similar to Legend of Grimrock. So I have the player move 1 unit (=1 tile) forward etc. every time the wasd keys are pressed down.

It behaves nicely when playing it in Unity, but when I play the compiled game it performs the movement function twice. I suspect it has something to do with the place where I put the code sections (Java).

In my Update part, I register for KeyDown which sets the movement direction, then declare movement variables and then comes a complicated "if..." statement that checks which movement direction is active, then checks if there's anything blocking via raycast and then calls the actual transform.position function which is declared at the end of the code. Is there the correct use of the Update part of the code?

A related problem is that if I use onKey instead of onKeyDown, I can keep the key pressed down and it continues to move forward like it should but if I only press it once it performs two moves as well, even in in-engine play.

So my questions are:

  1. Why does the game perform one movement step when testing in the engine, but two in the compiled version?

  2. Why does onKey perform two movement steps if the key is only tapped quickly, even in-engine?


EDIT :

 I was hoping to avoid it as it's all very primitive, clunky and excessively un-optimized, but at least it basically works as it should (in the editor), so here it goes...

 (It was pretty much the first code I created, based on the script of another user. In the days since I learned a lot and would probably write it far more efficient, but for now I'll just go with it :) )

     var MakeMove : int = 0;
     var IsMoving : boolean = false;
     var Facing : int = 2;
     var WalkSpeed : float = 7.0;
     var TurnSpeed : float = 7.0;
     var GridSize : float = 1.0;
     var StartPosition : Vector3;
     var EndPosition : Vector3;
     var Inputer = Vector3.zero;
     var t : float;



     function OnGUI() {
             if (Input.GetKeyDown(KeyCode.W))
                 MakeMove = 1;
     }

 function Update() {

     var localOffset = transform.position + transform.up * 0.5;
     var hitCollision : RaycastHit;


         //move forward        
         if (MakeMove == 1 && !IsMoving)

        {            
             if (Physics.Raycast (localOffset, transform.forward, hitCollision, 1.1)) 
              {
               print(hitCollision.collider); //oh yeah, I am hitting stuff such as, UnityEngine.MeshCollider
                Debug.DrawLine (transform.position, hitCollision.point);//I can also see that the rays work, awesome.
               if (hitCollision.collider.gameObject.CompareTag("walls-blocks"))
               {
                   print("front blocked");
                  }

              }
              else {GoForward();}

         }  


 function GoForward() {
         MakeMove = 0;
         IsMoving = true;

         StartPosition = transform.position;

         if (Facing == 0)
             EndPosition = transform.position - Vector3(0.0, 0.0, GridSize);

         if (Facing == 1)
             EndPosition = transform.position - Vector3(GridSize, 0.0, 0.0);

         if (Facing == 2)
             EndPosition = transform.position - Vector3(0.0, 0.0, -GridSize);

         if (Facing == 3)
             EndPosition = transform.position - Vector3(-GridSize, 0.0, 0.0);

         t = 0.0;

         while (t < 1.0) {
         t += Time.deltaTime * (WalkSpeed/GridSize);
         transform.position = Vector3.Lerp(StartPosition, EndPosition, t);
         yield;
         }

         IsMoving = false;

     }
Comment
Add comment · Show 5
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 Dracorat · Apr 08, 2013 at 06:11 PM 0
Share

Code. Post please.

avatar image MrSteve1 · Apr 08, 2013 at 06:26 PM 0
Share

can we see the code you're using?

avatar image Cherno · Apr 08, 2013 at 06:39 PM 0
Share

I was hoping to avoid it as it's all very primitive, clunky and excessively un-optimized, but at least it basically works as it should (in the editor), so here it goes...

(It was pretty much the first code I created, based on the script of another user. In the days since I learned a lot and would probably write it far more efficient, but for now I'll just go with it :) )

     var $$anonymous$$ake$$anonymous$$ove : int = 0;
     var Is$$anonymous$$oving : boolean = false;
     var Facing : int = 2;
     var WalkSpeed : float = 7.0;
     var TurnSpeed : float = 7.0;
     var GridSize : float = 1.0;
     var StartPosition : Vector3;
     var EndPosition : Vector3;
     var Inputer = Vector3.zero;
     var t : float;
     
 
      
     function OnGUI() {
             if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.W))
                 $$anonymous$$ake$$anonymous$$ove = 1;
     }
 
 function Update() {
     
     var localOffset = transform.position + transform.up * 0.5;
     var hitCollision : RaycastHit;
         
        
         //move forward        
         if ($$anonymous$$ake$$anonymous$$ove == 1 && !Is$$anonymous$$oving)
         
         {             
             if (Physics.Raycast (localOffset, transform.forward, hitCollision, 1.1)) 
                 {
                     print(hitCollision.collider); //oh yeah, I am hitting stuff such as, UnityEngine.$$anonymous$$eshCollider
                      Debug.DrawLine (transform.position, hitCollision.point);//I can also see that the rays work, awesome.
                     if (hitCollision.collider.gameObject.CompareTag("walls-blocks"))
                     {
                         print("front blocked");
                        }
     
                 }
                 else {GoForward();}
             
         }  
 
 
 function GoForward() {
         $$anonymous$$ake$$anonymous$$ove = 0;
         Is$$anonymous$$oving = true;
        
         StartPosition = transform.position;
            
         if (Facing == 0)
             EndPosition = transform.position - Vector3(0.0, 0.0, GridSize);
                
         if (Facing == 1)
             EndPosition = transform.position - Vector3(GridSize, 0.0, 0.0);
                
         if (Facing == 2)
             EndPosition = transform.position - Vector3(0.0, 0.0, -GridSize);
                
         if (Facing == 3)
             EndPosition = transform.position - Vector3(-GridSize, 0.0, 0.0);
                
         t = 0.0;
            
         while (t < 1.0) {
         t += Time.deltaTime * (WalkSpeed/GridSize);
         transform.position = Vector3.Lerp(StartPosition, EndPosition, t);
         yield;
         }
        
         Is$$anonymous$$oving = false;
     
     }
 
 
avatar image AlucardJay · Apr 08, 2013 at 06:41 PM 1
Share

Comments should be posted as comments , not answers. If you have more information you need to add, simply edit your question.

Post comments by clicking the [add new comment] button, a window then open for you to type in. Answer fields are for answers only, as this is a knowledge base.

Here at Unity Answers, Answer means Solution, not Response.

Please watch : http://video.unity3d.com/video/7720450/tutorials-using-unity-answers

I will convert this one this time, but now you are aware and will use the correct response procedure.

http://answers.unity3d.com/page/newuser.html

avatar image AlucardJay · Apr 08, 2013 at 06:41 PM 0
Share

@$$anonymous$$rSteve1 : Please don't post comments as answers. Post comments by clicking the [add new comment] button, a window then open for you to type in. Answer fields are for answers only, as this is a knowledge base.

Here at Unity Answers, Answer means Solution, not Response.

Please watch : http://video.unity3d.com/video/7720450/tutorials-using-unity-answers

I have converted this to a comment for you , but now you know.

Please read : http://answers.unity3d.com/page/newuser.html

1 Reply

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

Answer by Dracorat · Apr 08, 2013 at 06:43 PM

You should be checking input only in the Update loop, not in the OnGui loop. The calling rate of OnGui depends on FPS while Update is dependent upon the game logic rate.

Comment
Add comment · Show 1 · 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 Cherno · Apr 08, 2013 at 06:56 PM 0
Share

Wow, that fixed it! Thank you so much!

The OnGUI function was an artifact from the original code form the other user, he didn't call movement by keys but by buttons on the hut, so I just changed that to keyboard commands and left everything else in place. Now I know how to do it.

Strangely enough, it doesn't fix the secondary issue (two steps when on$$anonymous$$ey is used ins$$anonymous$$d of on$$anonymous$$eyDown), but it's not that important at the moment.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

14 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

Related Questions

Problem using a position determined from onTrigggerEnter in Update 2 Answers

Choppy movment for even the most basic stuff 2 Answers

How to synchronize translation with physics? 1 Answer

Multiplayer Rotation is really slow 1 Answer

Movement lag, jitery every few seconds 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