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 MachCUBED · Oct 01, 2012 at 07:03 PM · ioscharactercontrollertouchswimming

My unfortunate swimmer endlessly sinks. Help!

"Dive controls for swimming character controller cause character to continue sinking or rising after button is released" ...

Hi guys,

I've implemented the following code to make a Character Controller-based character dive and rise in water. The code is intended to work wih BugZergArcade's method of making a character swim:

 function GetButtonInputs()
 {
     // Button inputs
     
     var tapCount = Input.touchCount;
     
     for ( var i = 0 ; i < tapCount ; i++ ) {
     
         var touch = Input.GetTouch(i);
         
         if (!swimming)
         {
             if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
             {
                 if ( character.isGrounded )
                        Jump();
                }
                if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
             {
                 if ( character.isGrounded )
                        Duck();
                }
            }
            else
            {
                // Jump button to rise, crouch button to dive
                
                if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
             {
                 bouyancy += diveRate * Time.deltaTime;
                 if (bouyancy > 20)
                     bouyancy = 20;
                }
                else if(touch.phase == TouchPhase.Began && duckButton.HitTest(touch.position))
             {
                 bouyancy -= diveRate * Time.deltaTime;
                 if (bouyancy < -20)
                     bouyancy = -20;
                }
                else if(touch.phase == TouchPhase.Ended && jumpButton.HitTest(touch.position))
             {
                 bouyancy = 0;
                }
                else if(touch.phase == TouchPhase.Ended && duckButton.HitTest(touch.position))
             {
                 bouyancy = 0;
                }
            }
            //TODO: Add use buttons
     }
 }
 
 function Update()
 {
     ...
     
     // Tap rotation stick to orient towards movement
     
     if (rotateJoystick.tapCount == 2 )
     {
         FaceMovementDirection();
     }
     
     // Check for jump using right stick
     if ( character.isGrounded )
     {
         if ( !rotateJoystick.IsFingerDown() )
             canJump = true;
     }
     else
     {            
         // Apply gravity to our velocity to diminish it over time, only do so when not in water.
         if (!swimming)
             velocity.y += Physics.gravity.y * Time.deltaTime;
         else
             velocity.y += bouyancy * Time.deltaTime;
         
         // Adjust additional movement while in-air
         movement.x *= inAirMultiplier;
         movement.z *= inAirMultiplier;
     }
     
     GetButtonInputs();
     
     // Move player
     
     movement += velocity;
     
     if (!swimming)
         movement += Physics.gravity;
         
     movement *= Time.deltaTime;
     
     ...
 }

The jump button maks you rise in water, while the duck button makes you dive. Unfortunately, if you take your finger off of either button while you're swimming, the player character continues to rise or fall instead of staying at whatever depth you've gone to. What is the mistake?

MachCUBED

Comment
Add comment · Show 2
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 Mander · Oct 01, 2012 at 07:43 PM 0
Share

velocity.y += bouyancy * Time.deltaTime;

is ur bouyancy ever set to 0?. i mean is the if working

avatar image MachCUBED · Oct 01, 2012 at 09:22 PM 0
Share

It sets the bouyancy to 0 in the latter two else if blocks in the touch code, where it checks to see if the buttons are being touched during the swim$$anonymous$$g state.

3 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by kmeboe · Oct 01, 2012 at 08:09 PM

I've heard of problems with TouchPhase.Ended not firing in some cases. Here's what I would suggest: when you record that a jump or duck touch has started (via TouchPhase.Began), store the unique index of this touch (touch.fingerId). Then, on subsequent passes through GetButtonInputs, if you ever DO NOT see a touch with this fingerId (after looping through all touches), you can assume the touch has ended.

This will have the additional benefit that, if the user accidentally moves their finger off of the buttons while touching, you'll still handle this case correctly. The code you have here would never remove the buoyancy, because when they released their finger it wouldn't be over the button anymore.

Good luck, and let me know if you need more help in figuring out how to implement this.

Comment
Add comment · Show 8 · 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 MachCUBED · Oct 01, 2012 at 09:58 PM 0
Share

$$anonymous$$odifying the function to check for the fingerId like this:

function GetButtonInputs() { // Button inputs var tapCount = Input.touchCount; for ( var i = 0 ; i < tapCount ; i++ ) { var touch = Input.GetTouch(i);

     // Check to see if its the same touch as before
     if (!touchId)
         touchId = touch.fingerId;
     
     // Now handle button touches
     
     if (!swim$$anonymous$$g)
     {
         if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
         {
             if ( character.isGrounded )
                    Jump();
            }
            if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
         {
             if ( character.isGrounded )
                    Duck();
            }
        }
        else
        {
        
            if (touchId != touch.fingerId)
         {
             bouyancy = 0;
         }
     
            // Jump button to rise, crouch button to dive
            
            if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
         {
             bouyancy += diveRate * Time.deltaTime;
             if (bouyancy > 20)
                 bouyancy = 20;
            }
            else if(touch.phase == TouchPhase.Began && duckButton.HitTest(touch.position))
         {
             bouyancy -= diveRate * Time.deltaTime;
             if (bouyancy < -20)
                 bouyancy = -20;
            }
            else if(touch.phase == TouchPhase.Ended && jumpButton.HitTest(touch.position))
         {
             bouyancy = 0;
            }
            else if(touch.phase == TouchPhase.Ended && duckButton.HitTest(touch.position))
         {
             bouyancy = 0;
            }
        }
        //TODO: Add use buttons

} }

$$anonymous$$erely causes the diving and surfacing actions t become painfully slow, without any changes to the stopping behavior. Will try a new approach now.

avatar image kmeboe · Oct 01, 2012 at 10:09 PM 0
Share

You're getting close. Here's what needs to change for your new script:

1) "touchId" is an int, therefore "!touchId" doesn't make sense. It essentially checks for 0, which is a valid touch ID. I suggest you set touchID to -1 to start (and don't forget to set it to -1 again if the touch ends).

2) Do you allow multiple touches? If not, your code should check to see if the touch equals the touchID; if it doesn't, you don't want to do anything. If you do allow multiple touches, then you should also have multiple touchIDs to account for this.

3) You'll also want to see if the touchID that you recorded doesn't show up. You can do this by setting a bool at the beginning of the method (something like "bool foundTouch = false;"). Then, if you find a touch that's the same as your touchID, you can set foundTouch to true. At the end of your method, if foundTouch is still false, you should set buoyancy to 0.

As far as the slow rising/falling, I'm not sure what the difference is. Do you maybe want to modify the buoyancy with every update frame, rather than just during TouchPhase.Began (this only happens once)? Using deltaTime with touchPhase.Began is a little odd, since deltaTime is normally used for things that happen over multiple frames.

avatar image MachCUBED · Oct 03, 2012 at 04:38 AM 0
Share

I tried this code:

function GetButtonInputs() { // Button inputs var foundTouch : boolean = false; var tapCount = Input.touchCount; for ( var i = 0 ; i < tapCount ; i++ ) { var touch = Input.GetTouch(i);

     // Check to see if its the same touch as before
     if (touchId == -1)
         touchId = touch.fingerId;
     
     // Now handle button touches
     
     if (!swim$$anonymous$$g)
     {
         if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
         {
             if ( character.isGrounded )
                    Jump();
            }
            if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
         {
             if ( character.isGrounded )
                    Duck();
            }
        }
        else
        {
        
            if (touchId != touch.fingerId)
         {
             bouyancy = 0;
         }
     
            // Jump button to rise, crouch button to dive
            
            if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
         {
             bouyancy += diveRate * Time.deltaTime;
             if (bouyancy > 20)
                 bouyancy = 20;
            }
            else if(touch.phase == TouchPhase.Began && duckButton.HitTest(touch.position))
         {
             bouyancy -= diveRate * Time.deltaTime;
             if (bouyancy < -20)
                 bouyancy = -20;
            }
            else if(touch.phase == TouchPhase.Ended && jumpButton.HitTest(touch.position))
         {
             bouyancy = 0;
             touchId = -1;
            }
            else if(touch.phase == TouchPhase.Ended && duckButton.HitTest(touch.position))
         {
             bouyancy = 0;
             touchId = -1;
            }
            
            if (touch.fingerId == touchId);
                bouyancy = 0;
        }
        //TODO: Add use buttons

} }

And it won't let me dive at all. That's my attempt to fix my script so far. And yes, I ned multi-touch support because of my on-screen joystick and need for an adjustable camera.

avatar image kmeboe · Oct 03, 2012 at 04:58 AM 0
Share

Your "if" near the end has a semi-colon, meaning that the line following (buoyancy = 0) will ALWAYS happen. I'm making some changes to your script for you to try.

avatar image kmeboe · Oct 03, 2012 at 05:00 AM 0
Share

Do you want the buoyancy to increase/decrease as they hold down the button (longer holding means faster change, to a point) or all at once?

Show more comments
avatar image
0

Answer by lokeshvt · Oct 01, 2012 at 08:15 PM

when u are not pressing any button down, try removing the forces acting on the swimmer that causes it to rise or dive.

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

Answer by kmeboe · Oct 03, 2012 at 05:05 AM

I'm going to assume you want the sinking/swimming to gradually increase as the user holds down the button. In that case, we want to process EVERY touch (and not just touch.began). We also take note if the user is not holding either touch, and in that case we reset the buoyancy.

As I don't have your external variables defined, I wasn't able to ensure complete correctness; please excuse compilation errors.

 function GetButtonInputs()
 {
     // Button inputs
     
     var sinkingOrSwimming : boolean = false;
     
     var tapCount = Input.touchCount;
     
     for ( var i = 0 ; i < tapCount ; i++ ) {
     
         var touch = Input.GetTouch(i);
             
         // Now handle button touches
         
         if (!swimming)
         {
             if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
             {
                 if ( character.isGrounded )
                        Jump();
                }
                if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
             {
                 if ( character.isGrounded )
                        Duck();
                }
            }
            else
            {
                // Jump button to rise, crouch button to dive
                
                if(jumpButton.HitTest(touch.position))
             {
                 sinkingOrSwimming = true;
                 bouyancy += diveRate * Time.deltaTime;
                 if (bouyancy > 20)
                     bouyancy = 20;
                }
                else if(duckButton.HitTest(touch.position))
             {
                 sinkingOrSwimming = true;
                 bouyancy -= diveRate * Time.deltaTime;
                 if (bouyancy < -20)
                     bouyancy = -20;
                }
            }
            //TODO: Add use buttons
     }
     
     if (!sinkingOrSwimming)
     {
         // No dive or swim touch was found; reset buoyancy.
         bouyancy = 0;
     }
 }
Comment
Add comment · Show 3 · 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 kmeboe · Oct 03, 2012 at 05:08 AM 0
Share

You can get a little fancier, if you want, by using $$anonymous$$athf.Clamp ins$$anonymous$$d of checking for <-20 and >20. In this case you would perform the clamp in one spot, probably in the "else" clause of "if (!sinkingOrSwim$$anonymous$$g)".

But try the above script first, and make sure it works properly, before getting fancy with Clamp.

avatar image MachCUBED · Oct 03, 2012 at 11:25 PM 0
Share

The posted code worked with no compile errors whatsoever. I had to add the following else block to the button hit tests though. The choppiness was resolved with $$anonymous$$athf.Clamp, but the fundamental problem is that the swimmer still doesn't stop moving up or down when the player lets their finger off of the button. The swimmer appears to have a constant inertia that is set when by the bouyancy of the script.

Current code:

function GetButtonInputs() { // Button inputs

 var sinkingOrSwim$$anonymous$$g : boolean = false;

 var tapCount = Input.touchCount;

 for ( var i = 0 ; i < tapCount ; i++ ) 
 {

     var touch = Input.GetTouch(i);

     // Now handle button touches

     if (!swim$$anonymous$$g)
     {
        if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
        {
          if ( character.isGrounded )
              Jump();
         }
         if(touch.phase == TouchPhase.Began && jumpButton.HitTest(touch.position))
        {
          if ( character.isGrounded )
              Duck();
         }
     }
     else
     {
         $$anonymous$$athf.Clamp(bouyancy, -20, 20);
         // Jump button to rise, crouch button to dive

         if(jumpButton.HitTest(touch.position))
            {
              sinkingOrSwim$$anonymous$$g = true;
              bouyancy += diveRate * Time.deltaTime;
         }
         else if(duckButton.HitTest(touch.position))
            {
                sinkingOrSwim$$anonymous$$g = true;
             bouyancy -= diveRate * Time.deltaTime;
         }
         else
         {
             sinkingOrSwim$$anonymous$$g = false;
         }
     }
     //TODO: Add use buttons
 }

 if (!sinkingOrSwim$$anonymous$$g)
 {
     // No dive or swim touch was found; reset buoyancy.
        bouyancy = 0;
 }

}

avatar image kmeboe · Oct 08, 2012 at 07:53 PM 0
Share

Sorry it took so long to get back to you; I didn't see your reply for some reason.

Your "else" clause shouldn't be necessary, as "sinkingOrSwim$$anonymous$$g" starts out false.

It seems odd that your posted script doesn't work at this point. What does your "Update" look like now? You need to be calling your GetButtonInputs at the beginning of Update(); are you doing this?

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

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

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

Change Player object at touch 1 Answer

Sometimes, a touch can not be determined 0 Answers

Input.touchCount do not detect multitouch in iOS, but works fine for android 0 Answers

Detect the swipe and add force respective to it? 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