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 dl_studios · Jun 03, 2013 at 10:10 PM · character controllerclimbingclimbsticky

Character that Climbs Everything Including On Ceiling

We have been collectively banging our heads against this particular problem for a month or two now. We get results that are almost there but nothing is working perfectly.

The goal is to get our character to scramble over and around any surface at any angle in the level, much like a spider is able to do. This includes over uneven surfaces and around protruding cliff edges.

The main problem is keeping the guy grounded:

We can't seem to keep the rigidbody glued to the ground--addForce isn't controlled enough for ground hugging. CharacterControllers are awesome for ground hugging, but unfortunatly world Y up seems to be very important to it--any time we rotate our CharacterController, it wigs out. So we sigh and go back trying to get the rigid body to work.

Our main approach with the rigid body character is to use raycasting to detect ground/cliff normal's angle and orient our character to the angle. We then apply fake gravity on the local y axis to keep him on the surface, and lerp between any change in angle as our character moves over terrain.

The main problem we've encountered is that a rigidbody moved by addForce is very prone to leaving the ground because our character likes to ramp off of bumps. This leads to grounded state issues and a character with weird floating behavior when on a cliff face. We've attempted to add more local downward force when he leaves the ground to push him back to the surface, the results have been uneven motion and a bit of a jitter and he still leaves the ground a little bit, which means its not really accomplishing the goal anyway.

We have also tried the Locomotion System which has a planet walking demo where the character(rigid body) walks on all angles. For performance reasons(we are launching on iOS), and for the sake of simplicity, we'd prefer not to go this route. At any rate, the character flys off the planet when you round any sharp corners because of the local y down gravity they use to keep it stuck to the surface.

We've experimented with translate to move our character about, but the rigid body tended to ignore the terrain and go through the mesh. I've heard movePosition has been used, but it sounds like it would have the same collider ignoring problems of translate. Perhaps by directly manipulating velocity we could gain a bit more control, but regardless none of those solutions alone would solve our need to hug a bumpy ground--please correct me if I'm wrong there.

Perhaps there is a way of using velocity to move forward while using ray casts to translate my character to the surface, kind of like a match target?

I wish unity had a stick-to-any-surface-like-glue-while-moving-forward function :).

Any suggestions would be greatly appreciated. Thanks.

Comment
Add comment · Show 6
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 Benproductions1 · Jun 04, 2013 at 12:01 AM 0
Share

Just FYI you can't rotate a character controller.
Just an idea: is it possible for you to rotate the world ins$$anonymous$$d of the player? It's just a way around rotation a character controller :)

avatar image dl_studios · Jun 04, 2013 at 03:25 AM 0
Share

I wish that were a possibility, but unfortunately the world is far too complex. Thanks for the suggestion though:)

avatar image Benproductions1 · Jun 04, 2013 at 04:27 AM 2
Share

Well, you could write your own character controller, I think thats your only option. Using inbuilt physics is to inaccurate for what your looking for

avatar image Mr-JWolf809 · Jun 04, 2013 at 10:22 AM 0
Share

How do you know what the "down" direction is? Is it when the character touch a surface, then that is the new ground, or you have set up alot of trigger boxes? And, is it 2D game or 3D game?

avatar image dl_studios · Jun 04, 2013 at 03:20 PM 0
Share

@$$anonymous$$r. JWolf, Down is the characters local Y axis as opposed to world Y. We ray cast to the surface, grab the hit normal angle and orient our character to the angle. We then apply fake gravity down characters local y axis, effectively making the new angle "Down" as far as he is concerned.

Show more comments

1 Reply

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

Answer by dl_studios · Jun 05, 2013 at 05:01 AM

Well as luck would have it we found the answer. By directly controlling the rigid body velocity to move our character and using a downward local y velocity to keep him on the surface we oriented him to our character sticks like glue. This worked much better than addForce.

Modified this slightly. Controls velocity. http://answers.unity3d.com/questions/61089/how-to-properly-move-a-rigidbodycollider.html

We got the character orienting code from another forum thread that I can't find anymore. We put it in our series of ray casts to orient character to normal face should raycast hit.

 private Vector3 curNormal = Vector3.zero;
 private Vector3 usedNormal = Vector3.zero;
 private Quaternion tiltToNormal;
 public float turnSpeed = 2f;
 public float MoveSpeed = 20f
 
 moveDirection = transform.TransformDirection (moveDirection);        

            //rotates character
             rotationAmount = Input.GetAxis ("Horizontal") * turnSpeed * Time.deltaTime;
         transform.RotateAround (transform.up, rotationAmount);
         
         //set up a variable to manipulate velocity directly. 
         Vector3 velocityAllAxis = transform.rigidbody.velocity;
         velocityAllAxis.x = moveDirection.x;
         velocityAllAxis.z = moveDirection.z;
             velocityAllAxis.y = moveDirection.y;
         transform.rigidbody.velocity = velocityAllAxis;    
 
 //now for detection and orientation.
 
         RaycastHit outhit;
         if (Physics.Raycast (transform.position, transform.forward, out outhit, 3f)) {
         
             Debug.DrawRay (transform.position, transform.forward, Color.blue, 2f);
         
             usedNormal = outhit.normal;
             curNormal = Vector3.Lerp (curNormal, usedNormal, 6.0f * Time.deltaTime);
             tiltToNormal = Quaternion.FromToRotation (transform.up, curNormal) * transform.rotation;
             transform.rotation = tiltToNormal;
         
         } else { 
             if (Physics.Raycast (transform.position, -transform.up, out outhit, 3f)) {
             
                 Debug.DrawRay (transform.position, -transform.up, Color.green, 2f);
                 usedNormal = outhit.normal;
                 curNormal = Vector3.Lerp (curNormal, usedNormal, 6.0f * Time.deltaTime);
                 tiltToNormal = Quaternion.FromToRotation (transform.up, curNormal) * transform.rotation;
                 transform.rotation = tiltToNormal;
             
             } else {
  
                 if (Physics.Raycast (transform.position + (-transform.up), -transform.forward + new Vector3 (0, .3f, 0), out outhit, 3f)) {
     
     
                     Debug.DrawRay (transform.position + (-transform.up), -transform.forward + new Vector3 (0, .3f, 0), Color.green, 2f);
                     usedNormal = outhit.normal;
                     curNormal = Vector3.Lerp (curNormal, usedNormal, 6.0f * Time.deltaTime);
                     tiltToNormal = Quaternion.FromToRotation (transform.up, curNormal) * transform.rotation;
                     transform.rotation = tiltToNormal;
     
                 } else {
         
                     curNormal = Vector3.Lerp (curNormal, Vector3.up, 6.0f * Time.deltaTime);
                     tiltToNormal = Quaternion.FromToRotation (transform.up, curNormal) * transform.rotation;
                     transform.rotation = tiltToNormal;
         
                 }
  
  
             }
 
         }
Comment
Add comment · Show 6 · 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 Mr-JWolf809 · Jun 05, 2013 at 05:38 PM 0
Share

Good job. Could you post the code that solved the problem? So others with the same problem might get some ideas :3

avatar image ruffledfeathers · Jun 06, 2013 at 01:54 AM 0
Share

Good job solving this. I have a very similar problem, so I for one would very much appreciate seeing the code snippet that did the trick for you!

avatar image Benproductions1 · Jun 06, 2013 at 02:00 AM 0
Share

Personally I think @dl_studios has supplied sufficient explanation for someone to get the right idea of what to do :)

avatar image ruffledfeathers · Jun 12, 2013 at 02:32 PM 0
Share

Thanks for updating with example code dl_studios - much appreciated.

avatar image Skar_Universe · Sep 19, 2016 at 08:26 PM 0
Share

Hello I know this topic is closed but I'm in a ditch here... So I have no idea what you did in the first half of this code. The commands mentioned here aren't even showing up in $$anonymous$$onodevelop.. total noob here ... I got the raycasting part but don't understand how to implement the gravity. Any help appreciated.

Show more comments

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

23 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

Related Questions

Best climbing system! 1 Answer

Using Vector3.lerp to climb 0 Answers

climbing ladders script, help 0 Answers

MatchTarget Help 1 Answer

Can the Locomotion System be adapted to climb vertical surfaces? 2 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