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
1
Question by Rxanadu · Jun 09, 2013 at 01:58 AM · gameobjectrigidbodyvector3.lerp

Creating a retractable grappling hook

I'm having trouble making a retracting grapple hook similar to the Hookshot featured in most Legend of Zelda games, where the hook retracts back to the Hookshot either if the player hits a button before the hook gets to its intended destination or if the hook reaches a specified distance without hitting a grapple point.

Right now, the hook I've created shoots out to a specified distance away from the player, then immediately 'snaps' into place when it's greater than that distance. Below is the FixedUpdate function where most of the action takes place:

 void FixedUpdate()
     {
         hookDist = Vector3.Distance(subItem.transform.position, hook.transform.position);
         
         Ray ray = Camera.mainCamera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
         RaycastHit hit;
 
         rotSpeed = Mathf.Clamp(rotSpeed, 0f, 1f);
         step = speed * Time.deltaTime;
         
         hook.transform.Rotate(Vector3.forward * (angle * rotSpeed), Space.Self);
 
         Debug.Log(rotSpeed);
         Debug.Log(hookDist);
 
         if (Input.GetMouseButton(0))
         {            
             if (Physics.Raycast(ray, out hit))
             {
                 GrappleToGrapplePoint();
             }
         }                    
 
         if (isSpinning) { 
             rotSpeed += .2f * Time.deltaTime;
         }
         else
             rotSpeed -= .5f * Time.deltaTime;
 
         if (Input.GetMouseButtonDown(0)) {
             isSpinning = true;
         }
 
         if (Input.GetMouseButtonUp(0)) {
             isSpinning = false;
             if (rotSpeed >= 1f) {
                 hook.rigidbody.velocity = subItem.transform.TransformDirection(new Vector3(0, 0, hookSpeed));
                 hook.transform.parent = null;
             }            
         }
 
         if (hookDist >= 18)
         {
             hook.rigidbody.velocity = Vector3.zero;
             hook.transform.position = Vector3.Lerp(hook.transform.position, subItem.transform.position, retractSpeed * Time.time);
             hook.transform.parent = subItem.transform;
         }
     }

If you read the script, you can see that I use Vector3.Lerp to retract the hook to its initial position without snapping into place. However, as stated before, the hook 'snaps' back to the empty GameObject's position.

As per usual, I may be missing something very small; I just can't figure out what it is at the time. Any relevant input would be much appreciated.

Thank you for taking the time to read this.

Comment
Add comment · Show 1
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 Rxanadu · Jun 10, 2013 at 02:11 AM 0
Share

Is there anyone out there that can help me?

1 Reply

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

Answer by Chronos-L · Jun 10, 2013 at 09:42 AM

Look at my answer in this question. The problem (at least what I can see right now) lies with the Vector3.Lerp in these:

 if (hookDist >= 18)
         {
             hook.rigidbody.velocity = Vector3.zero;
             hook.transform.position = Vector3.Lerp(hook.transform.position, subItem.transform.position, retractSpeed * Time.time);
             hook.transform.parent = subItem.transform;
         }

You should not use Time.time for any Lerp function. For Lerp( a, b, factor) (Vector3.Lerp reference), if factor is smaller than 0, you will get a, if it is larger than 1, then you will always get b.

When you use retractSpeed * Time.time, chances are the result will be way larger than 1, so the hook snaps right back to subItem.transform.position.

To fix this, you can use Vector3.MoveTowards, something like this:

 hook.transform.position = Vector3.MoveTowards(hook.transform.position, subItem.transform.position, retractSpeed * Time.deltaTime);



On a non-related but important issue, you should use a variable/state to store the current state of the hook, from what I can see:

 void FixedUpdate()
     {
         hookDist = Vector3.Distance(subItem.transform.position, hook.transform.position);
  
         ...
  
         if (Input.GetMouseButtonDown(0)) {
            //...
         }
  
         if (Input.GetMouseButtonUp(0)) {
             //Shooting the hook          
         }
  
         if (hookDist >= 18)
         {
            //Retract hook 
         }
     }

When your hook starts retracting ( no more snapping after you fixed it ), when the hook distance becomes shorter than 18, it will not fully retract. You need a state to record the current state of the hook: standby, shooting, stick(if applicable), retracting.

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 Rxanadu · Jun 11, 2013 at 08:02 PM 0
Share

Thanks for the help. I had forgotten there was a $$anonymous$$oveTowards function existed.

I just noticed the distance check wasn't working when the hook was < 18. All I did to fix it was set a Boolean value which sets to true when the hookDist is >= 18f; as long as the bool value is true, the hook will retract back to the subItem's position.

Unfortunately, I have another issue with resetting the hook's rotation where it's facing forward rather than the last rotation before launching. The only thing I know is that it requires me to rotate it back into position in the world space.

I've tried setting the rotation back to 'Quaternion.identity' and to 'Vector3.zero,' but nothing seems to work.

Edit: I just made a quick fix by setting the hook's rotation to that of the subItem when the hook starts retracting and setting the re-parenting to the subItem object after it retracts back to that position.

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

17 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

Related Questions

Why does IsSleeping() keep returning false? (Billiard Logic) 0 Answers

game object falling through plane when adding rigid body component 1 Answer

Attach rigidbody to ground below it 1 Answer

Issue with an object rotating strangely 2 Answers

Rigidbody: NullReferenceException: Object reference not set to an instance of an object 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