• 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 getyour411 · Jan 11, 2014 at 12:11 AM · charactercontrollergravityvector3.up

Apply a new/custom Vector3.up to adjust Player normal

Hello Community,

My player (using CharacterController, no rigidbody) is walking on a large somewhat spherical object (no Terrain, its in "space") which is slowly rotating on the its three axis. As I walk across this object, I want my Player's...normal?...to stay basically perpendicular to the asteroid surface so that I don't walk/fall off. I've done some Internet searches and have this so far:

 if (mmo.AsteroidWalking = true) {
                         
             desiredUp = Vector3.zero;
             for (int i=0; i <8; i++) {
                 Vector3 rayStart =
                     transform.position
                         + transform.up
                         + Quaternion.AngleAxis(360 * i / 8.0f, transform.up)
                         * (transform.right * 0.5f)
                         + desiredVelocity*0.2f;
                 
                 Debug.DrawRay(rayStart, transform.up * -5, Color.red);
                 // Debug.Log(Physics.Raycast(rayStart, transform.up*-48, out hit, 3.0f, groundLayers));
                 if ( Physics.Raycast(rayStart, transform.up*-5, out hit, 10.0f, groundLayers) ) {
                     
                     desiredUp += hit.normal;
                 }
             }
             Debug.Log (desiredUp);
             Debug.DrawRay(Vector3.zero,hit.normal,Color.blue);
 
         }


This shoots out 8 rays in a circle around my character to the "ground" and gets me desiredUp but I don't know what to do with desiredUp or how to apply this to set my Player upright compared to the surface.

I might have bungled the question title as I'm really learning the terms as I work through this, let me know addtional details are needed. 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

3 Replies

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

Answer by getyour411 · Jan 12, 2014 at 03:38 AM

Thanks both for your ideas.

Using the work done already in http://answers.unity3d.com/questions/155907/basic-movement-walking-on-walls.html I was able to get this working. To that thread, I added my C# translation. For anyone stumbling on this thread looking for similar info, follow the hyperlink.

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 robertbu · Jan 11, 2014 at 01:17 AM

I don't know if your desiredUp calculation is correct, but you can usually use the following code to align a character with a vector:

 transform.rotation = Quaternion.FromToRotation(transform.up, desiredUp) * transform.rotation;
Comment
Add comment · Show 5 · 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 getyour411 · Jan 11, 2014 at 05:46 AM 0
Share

Tried this and my Character is adhering better to the surface I can walk nearly 1/2 "down" it but my player isn't rotating perpendicular-like to the surface and eventually the angle becomes too steep and he just slides off. I'm looking into the CharacterController's collider and code to see if that thing or other move code is conflicting.

avatar image robertbu · Jan 11, 2014 at 06:12 AM 0
Share

I did not review your 'desiredUp' code. I'd do:

 Debug.DrawRay(transform.position, desiredUp*4);

...just to verify your calculations of 'desiredUp' is what you expect. The line of code I provided will align an the 'up' of the object to the supplied vector unless some other script is also acting on the object.

avatar image getyour411 · Jan 11, 2014 at 06:40 AM 0
Share

Yep, the desiredUp looks good. alt text Attach to my player is the standard CharacterController (which is responsible for the yellow collider in the pic) and a variant of the Third Person Controller script, only those 2 would have any influence on movement. I'll look to see what I can find in that.

space01.png (142.8 kB)
avatar image robertbu · Jan 11, 2014 at 07:08 AM 0
Share

You might try moving the line of code to LateUpdate() to see what happens.

avatar image getyour411 · Jan 11, 2014 at 07:59 AM 0
Share

@robertbu Tried that, same issue. Is 'CharacterController' exposed somewhere in Unity? I don't see anything in my third person script that looks related to rotation issues and I suspect there's something in CharacterController.

avatar image
0

Answer by sparkzbarca · Jan 11, 2014 at 01:32 AM

cast a ray down at the ground

 Ray ray;
 ray.origin = player.transform.position;
 ray.direction = player.transform.down;
 Raycasthit terrainhit;
 physics.raycast(ray,out terrainhit);
 
 Axis = Vector3.Cross(player.transform.down, terrainhit.normal);
 
 Angle = Mathf.Atan2(Vector3.Magnitude(Axis), Vector3.Dot(player.transform.down, -terrainhit.normal));
 
 Angle = Mathf.Rad2Deg * Angle;

 player.transform.RotateAround(terrainhit.point, Axis, Angle);

have a nice day

if you need a better understanding of why it works let me know

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 getyour411 · Jan 11, 2014 at 05:47 AM 0
Share

What is transform.down? I couldn't find a reference for that get an error on use

avatar image getyour411 · Jan 11, 2014 at 06:25 AM 0
Share

@sparkzbarca I attempted to translate the code into C# and had to make some guesses. I ended up with this but don't know if it's functionally equivalent to what you were suggesting. I broke up a few statements to help figure out the compiler errors re: float v Vector3. Anyway, I see no change in the behavior, I slide off at a certain point.

         ray.origin = transform.position;
         //ray.direction = transform.down;
         ray.direction = transform.TransformDirection(-Vector3.up);
         Vector3 pdown = transform.TransformDirection(-Vector3.up);


         RaycastHit terrainhit;
         Physics.Raycast(ray,out terrainhit);
         
         //Vector3 Axis = Vector3.Cross(pdown, terrainhit.normal);
         Vector3 Axis = Vector3.Cross (pdown,terrainhit.point).normalized;

         float parm1 = $$anonymous$$athf.Atan(Vector3.$$anonymous$$agnitude(Axis));
         float parm2 = Vector3.Dot (pdown, -terrainhit.normal);
         
         float Angle = $$anonymous$$athf.Atan2(parm1, parm2);
         
         Angle = $$anonymous$$athf.Rad2Deg * Angle;
         
         transform.RotateAround(terrainhit.point, Axis, Angle);
avatar image sparkzbarca · Jan 11, 2014 at 02:08 PM 0
Share
  //Vector3 Axis = Vector3.Cross(pdown, terrainhit.normal);
        Vector3 Axis = Vector3.Cross (pdown,terrainhit.point).normalized;

no i really did want you to cross the normal you shouldnt have commented that out.

a normal is not a normalized point. A point normalized is between 0 and 1 a normal is basically the direction going directly up from the ground.

pdown shoudl be crossed with -terrainhit.normal $$anonymous$$ADE AN ERROR earlier SHOULD BE - terrainhit.normal not just terrainhit.normal.

 float parm1 = $$anonymous$$athf.Atan(Vector3.$$anonymous$$agnitude(Axis));
        float parm2 = Vector3.Dot (pdown, -terrainhit.normal);
  
        float Angle = $$anonymous$$athf.Atan2(parm1, parm2)

not sure why you broke this up into that, you shouldnt atan the first parameter. you just want paramter one to be the vector3.magnitude not the arc tangent of the magnitude.

avatar image sparkzbarca · Jan 11, 2014 at 02:10 PM 0
Share

$$anonymous$$ADE AN ERROR SHOULD BE

Vector3.Cross(pdown, -terrainhit.normal);

notice the negative sign.

avatar image getyour411 · Jan 11, 2014 at 07:10 PM 0
Share

@sparkzbarca Thanks for the follow-ups; I corrected the code it now reads:

         ray.origin = transform.position;
         ray.direction = transform.TransformDirection(-Vector3.up);

         Vector3 pdown = transform.TransformDirection(-Vector3.up);

         RaycastHit terrainhit;
         Physics.Raycast(ray,out terrainhit);
         
         Vector3 Axis = Vector3.Cross (pdown, -terrainhit.normal);

         float parm1 = Vector3.$$anonymous$$agnitude (Axis);
         float parm2 = Vector3.Dot (pdown, -terrainhit.normal);
         
         float Angle = $$anonymous$$athf.Atan2(parm1, parm2);
         
         Angle = $$anonymous$$athf.Rad2Deg * Angle;
         
         transform.RotateAround(terrainhit.point, Axis, Angle); 

but my Player is still not orienting with the surface. Screenshot uploaded. alt text

space02.png (174.6 kB)
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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

19 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

Related Questions

2D Top Down Character being Pulled down and movement script not working? 2 Answers

Can I customise CharacterController Physics Module ? 0 Answers

Sphere + rigidbody + character controller 1 Answer

My characters in Unity float slightly above my ground I imported and made in Blender 0 Answers

When my player climb something, after a certain point it start to float 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges