• 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 mrhussain0334 · Oct 17, 2013 at 03:34 PM · gravitysphere

How to move around a sphere?

The move includes simple movements and also a Jump movement. but How do I do it. Gravity is enabled.

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

1 Reply

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

Answer by sdgd · Oct 17, 2013 at 03:39 PM

Because I've been trying to figure this out for a while and Unity answers don't contain much of this kind of knowledge I'm giving you this what I wroted and gathered in a month, ... It's still a robust code but my updates are not in it yet

all you need is: GameObject with: Character controller (prefered sphere height), Movement script

child GameObject with: Graphics, MouseLookX script

child GameObject with: Camera, MouseLookY script

Scripts:

Mouse Look X

 using UnityEngine;
 using System.Collections;
 
 public class MouseLookX : MonoBehaviour {
     public float MouseSensitivityX = 1;
     void Update (){
         transform.localEulerAngles += new Vector3(    0, Input.GetAxis("Mouse X") * MouseSensitivityX, 0);
     }
 }


Mouse Look Y

 using UnityEngine;
 using System.Collections;
 
 public class MouseLookY : MonoBehaviour {
     public float MouseSensitivityY = 1;
     void Update(){
         transform.localEulerAngles += new Vector3 (Input.GetAxis("Mouse Y") * MouseSensitivityY, 0, 0);
     }
 }

Some added Math functions:

 using UnityEngine;
 using System.Collections;
 
 public struct MathFunctions {
     // always positive
     public float Positive (float FloatToChange){
         if (FloatToChange < 0){
             return (FloatToChange * (-1) );
         }
         return FloatToChange;
     }
     // always negative
     public float Negative (float FloatToChange){
         return Positive(FloatToChange) * -1;
     }
     // V3 Distance
     public float V3Distance (Vector3 From, Vector3 To){
         float TempX;
         float TempY;
         float TempZ;
         TempX = From.x - To.x; TempX *= TempX;
         TempY = From.y - To.y; TempY *= TempY;
         TempZ = From.z - To.z; TempZ *= TempZ;
         return Mathf.Sqrt(TempX + TempY + TempZ);
     }
     // V3 Point
     public Vector3 DirectionDistancePoint (Vector3 From, Vector3 To, float Length){
         return (From + (To.normalized * Length) );
     }
     // Distance / sec
     public float Vector3SpeedPerSec (Vector3 From, Vector3 To, float InTime){
         return Positive( (V3Distance(From, To) ) / InTime  );
     }
     // Direction
     public Vector3 Direction (Vector3 From, Vector3 To){
         return (To - From).normalized;
     }
     // V2 Angle
     public float V2Angle (Vector2 From, Vector2 To){
         
 //        float DotProduct = From.x * To.x + From.y * To.y;
 //        float MagnA = From.x * From.x + From.y * From.y;
 //        float MagnB = To.x * To.x + To.y * To.y;
 //        MagnA = Mathf.Sqrt(MagnA);
 //        MagnB = Mathf.Sqrt(MagnB);
         
         
         Vector3 Cross = Vector3.Cross(From, To);
         
         float ang = Vector2.Angle(From, To);//Mathf.Acos( (DotProduct / (MagnA*MagnB) )  ) * Mathf.Rad2Deg;
         if (Cross.z > 0){
             ang = 360 - ang;
         }
         return ang;
     }
 }
 

Movement Script

 using UnityEngine;
 using System.Collections;
 
 public class Movement : MonoBehaviour {
     // mathematic functions
     MathFunctions MF;
     // orientation transforms
     public Transform Planet; // to rotate to
     public Transform LocalOrientation; // graphics
     
     
     
     CharacterController Controller;
     Vector3 LookAtPlanet = Vector3.zero; // direction
     // Movement
     public bool AccelerationMovement = true;
     Vector3 TempInputVelocity = Vector3.zero;
     Vector3 MovementVelocity = Vector3.zero;
     float MovingTime = 0; // dinamic one in between start and stop movement
         // Start Moving
         public bool StillInMovement = false;
             // for bullet
             public bool MaxMovementVelocity = false;
         float MovingStartTime = 0;
         public float AccelerationTime = 1; // how much time till full speed
         // Stop Moving
         public bool StoppingMovement = false;
         float MovingStartStopTime = 0;
     // Jump
     public bool StillJumping = false;
     Vector3 JumpVelocity = Vector3.zero;
     float JumpStartDistance = 0; // distance from planet
     float PlanetDistance = 0; // our current distance to planet /*we only need it on jump function*/
     public float JumpStrength = 10; // how strong we jump
     public float JumpHeight = 20; // what's the max distance we can jump
     // Gravity
     public bool Grounded = false;
     public bool LandedOnSlope = false;
     Vector3 GravityVelocity = Vector3.zero;
     public Vector3 LastGroundTestPosition = Vector3.zero;
     public Vector3 LastSlopeTestPosition = Vector3.zero;
     float LastHitTime = 0; // CharacterController hit time
     public float GravityStrength = 10;
     // Move Char
     public float MovementSpeed = 9; // m/s || points/s
     // Complicated AI
     public bool AI = false;
     public bool AIForward = false;
     public bool AIBackward = false;
     public bool AIRight = false;
     public bool AILeft = false;
     public bool AIJump = false;
     // bullet
     public bool Bullet = false;
     public bool BulletFire = false; // How many frames will it fire it // - WHAT???
     public float BulletSpeed = 50; // m/s
     
     
     
     // I need to learn how to implement it
     public AnimationCurve slopeSpeedMultiplier = new AnimationCurve (new Keyframe(-90, 1), new Keyframe(0, 1), new Keyframe(90, 0));
     // actually I already have it since I'm walking through wall and going more through wall is slower than linear walking
     
     void Start(){
         Controller = GetComponent("CharacterController") as CharacterController;
         // so we don't end up teleporting at x0y0z0 if something unexpected happenes
         LastSlopeTestPosition = transform.position;
     }
 
     
     // why fixed update? had something in my mind that I need it forgot it why, ... seems to be working well with normal update too less calculations to be made with it
     // if I'm wrong something might not be sinhronized, ... don't know, ...
     void Update() {
         // Align to planet without south pole maddness :)
         Ray ray = new Ray(transform.position, -transform.up);
         RaycastHit hit;
         if (Planet.collider.Raycast(ray, out hit,
                                     MF.V3Distance(transform.position, Planet.transform.position) )  ){
             transform.rotation = Quaternion.LookRotation( Vector3.Cross(transform.right, hit.normal) , hit.normal);
             // south pole maddness    =    transform.rotation = Quaternion.FromToRotation (Vector3.up, -(Planet.position - transform.position) );
         }
         
         LookAtPlanet = -transform.up;
         
         if (Grounded){
             // 1/2 Grounded false if not colliding
             IsStillGrounded();
         }
 //DEBUG!!!
 //Grounded = true; // debug so if we are in air we can still move
         // we check if we are still grounded. // bullet needs a starter fire in mid air
         if (Grounded || BulletFire || LandedOnSlope){
             InputMoveMotion();
             // inside 2/2 Grounded false if press a key
             if (! Bullet && ! BulletFire && ! LandedOnSlope){
                 InputJumpMotion();
             }
         }
         // if we jump we are still not using gravity
         if (! StillJumping){
             GravityMotion();
         }
         if (StillJumping){
             ContinueJumpMotion();
         }
 //DEBUG!!!
 //IsStillGrounded(); // debug so gravity all the time works
         MoveChar();
     }
     void IsStillGrounded (){
         // we are not moving OR we are in air
         if (LastHitTime < (Time.time - Time.deltaTime * 2) ){
             // we are moving in mid air
             if (LastGroundTestPosition != transform.position){
                 // grounded was 100% true
                 Grounded = false;
                 // we start accelerationg from 0
                 GravityVelocity = Vector3.zero;
             }
           //else {we aren't in motion}
         }
         LastGroundTestPosition = transform.position;
     }
     
     public void InputMoveMotion(){
         Vector3 ImputVelocity = Vector3.zero;
         if (AI || BulletFire){
             if (AIForward){
                 ImputVelocity += ( LocalOrientation.transform.forward);
             }
             if (AIBackward){
                 ImputVelocity += ( -LocalOrientation.transform.forward);
             }
             
             if (AILeft){
                 ImputVelocity += ( -LocalOrientation.transform.right);
             }
             if (AIRight){
                 ImputVelocity += ( LocalOrientation.transform.right);
             }
             // we want to make only 1 time movement propably
             if (MaxMovementVelocity){
                 BulletFire = false;
             }
         }
         else if (! AI && ! Bullet) {
             if (Input.GetKey(KeyCode.UpArrow)){
                 ImputVelocity += ( LocalOrientation.transform.forward);
             }
             if (Input.GetKey(KeyCode.DownArrow)){
                 ImputVelocity += ( -LocalOrientation.transform.forward);
             }
             
             if (Input.GetKey(KeyCode.LeftArrow)){
                 ImputVelocity += ( -LocalOrientation.transform.right);
             }
             if (Input.GetKey(KeyCode.RightArrow)){
                 ImputVelocity += ( LocalOrientation.transform.right);
             }
         }
         // direction length to 1 unit
         ContinueMoveMotion(ImputVelocity.normalized);
     }
     void ContinueMoveMotion(Vector3 InputVelocity){
         if (! AccelerationMovement){
             MovementVelocity = InputVelocity;
             return ;
         }
         
         
         // seems to be working more tests need to be done, ...
         /****** "START" START MOVING ******/
         if (InputVelocity != Vector3.zero){
             TempInputVelocity = InputVelocity;
             // we didn't ended the stop
             if (StoppingMovement){
                 StoppingMovement = false;
                 MovingStartTime = Time.time - MovingTime;
             }
             // we are just starting to move
             else if (LastGroundTestPosition == transform.position && ! StillInMovement){
                 MovingStartTime = Time.time;
             }
             StillInMovement = true;
             // we've reached the top speed
             if (AccelerationTime > (Time.time - MovingStartTime)){
                 MovingTime = (Time.time - MovingStartTime);
                 MaxMovementVelocity = true; // needed for bullet
             }
             else {
                 MovingTime = AccelerationTime;
             }
             // where we will move, / AccelerationTime so moving time is a % of full throtle
             MovementVelocity = InputVelocity * MovingTime / AccelerationTime;
         }
         /****** "END" START MOVING ******/
         /****** "START" STOP MOVING ******/
         else {
             if (StillInMovement && ! StoppingMovement){
                 StoppingMovement = true;
                 MaxMovementVelocity = false; // don't need it ATM but I'll do it anyway since I need only the max for bullet
                 MovingStartStopTime = Time.time + MovingTime;
             }
             // I don't need this but so it doesn't calculate all the time but just veryfy the bool
             if (StoppingMovement){
                 MovingTime = MovingStartStopTime - Time.time;
             }
             // if we are inside stopping time
             if (MovingTime >= 0){
                 // AccelerationTime so moving time is a % of full throtle
                 MovementVelocity = TempInputVelocity * MovingTime / AccelerationTime;
             }
             // if we stopped totally
             else {
                 MovementVelocity = Vector3.zero;
                 StillInMovement = false;
                 StoppingMovement = false;
             }
         }
         /******"END" STOP MOVING******/
         
         
     }
     void InputJumpMotion(){
         // 2/2 if we jump we know we aren't grounded
         if ( (Input.GetMouseButton(2) && ! AI) || (AI && AIJump)){
             JumpVelocity = transform.up * JumpStrength;
             // grounded was 100% true
             Grounded = false;
             // we must start accelerationg from 0
             GravityVelocity = Vector3.zero;
             StillJumping = true;
             JumpStartDistance = MF.V3Distance(transform.position, Planet.position);
         }
     }
     void ContinueJumpMotion(){
         PlanetDistance = MF.V3Distance(transform.position, Planet.position);
         // if we stop pressing jump we stop getting in air
         if (Input.GetMouseButtonUp(2)){
             StillJumping = false;
             JumpVelocity = Vector3.zero;
         }
         // if we reached our jump height we stop getting more in height
         else if (JumpStartDistance + JumpHeight < PlanetDistance){
             StillJumping = false;
             JumpVelocity = Vector3.zero;
         }
         else if (StillJumping){
             JumpVelocity -= (-transform.up * 0.3f * Time.deltaTime);
         }
     }
     void GravityMotion (){
         ContinueGravityMotion(MF.Direction(transform.position, Planet.position).normalized);
 //        GravityVelocity = MF.Direction(transform.position, Planet.position).normalized * GravityStrength;
     }
     void ContinueGravityMotion(Vector3 GravityDirection){
         GravityVelocity += GravityDirection * GravityStrength * Time.deltaTime;
     }
     void MoveChar(){
         if (StillJumping){
             GravityVelocity = Vector3.zero;
         }
         if (Grounded){
             Controller.Move( (MovementVelocity * MovementSpeed) * Time.deltaTime);
         }
         else {
             Controller.Move(  ( (MovementVelocity * MovementSpeed) + JumpVelocity + GravityVelocity) * Time.deltaTime);
         }
     }
     private Vector3 LandedOn = Vector3.zero;
     void OnControllerColliderHit (ControllerColliderHit hit){
         // bullet stops
         if (Bullet){
             AIForward = false;
             AIBackward = false;
             AIRight = false;
             AILeft = false;
         }
         
         // the only indicator we are grounded
         // if it's less than 45° we are grounded
         float CurrentSlope = (Vector3.Angle(LookAtPlanet, hit.normal) -180 )*-1;
         if (Controller.slopeLimit > CurrentSlope){
             Grounded = true;
             LastHitTime = Time.time;
             LastSlopeTestPosition = transform.position;
             // we sucessfully went down from slope now we reset it so we don't teleport back to the end of slope
             if (LandedOnSlope){
                 LandedOnSlope = false;
                 LandedOn = Vector3.zero;
             }
         }
         // if we are still grounded and are on 45° + slope we must teleport back
         else if (Grounded && Controller.slopeLimit < CurrentSlope){
             // we need to teleport back to slope below 45°
             transform.position = LastSlopeTestPosition;
         }
         // if we aren't grounded means we landed on 45° + slope
         else if (! Grounded){
             LandedOnSlope = true;
             // we mark where we landed
             if (LandedOn == Vector3.zero){
                 LandedOn = transform.position;
             }
             // if we are trying to climb we teleport back
             else if (    MF.V3Distance(LandedOn,            Planet.position) <
                         MF.V3Distance(transform.position, Planet.position)    )    {
                 transform.position = LandedOn;
             }
             // we aren't climbing but are going down
             else {
                 LandedOn = transform.position;
             }
         }
         
         /****** START DEBUG Hit COMPONENTS ******
         // world point
 //        Debug.Log("Point: " + hit.point);
         // oposite of direction
 //        Debug.Log("Normal: " + hit.normal); // World Direction
         // direction witch was forced back
 //        Debug.Log("MoveDirection: " + hit.moveDirection); // Local Direction & something strange unexplained about it
         // more length that's stopped bigger number it'll return
 //        Debug.Log("moveLength: " + hit.moveLength);
 //        Platform = hit.transform;
         /****** END DEBUG Hit COMPONENTS ******/
     }
 }

I'm posting this because there's not even 1 complete answer on unity sites but just fractions of this code

like how to go around planet and 1 line, ...

I had to find all this fractions and combine everything in to 1 big script ALSO I helped my self with already done 1 java scripted (I hate java) and modified it in to 3D instead of 2D (standart asset character controllers)

I've wanted to go doing it several ways until I found correct way witch works

EDIT: AS promised I updated the code since you accepted my answer, BTW I still haven't finished my code so it's compleating each day more and more, ...

and thanks for a question like write me a script, ... DOH, ...

BTW I reject that kind of questions like yours

Comment
Add comment · Show 4 · 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 knuckles209cp · Oct 18, 2013 at 10:11 PM 0
Share

Wow your a legend .... 0.0

avatar image sdgd · Oct 18, 2013 at 10:20 PM 0
Share

humh I thought this script helped you, ... I thought I deserved thumbs up, ... @knuckles209cp

avatar image meat5000 ♦ · Oct 18, 2013 at 11:26 PM 0
Share

I'll give it to you ins$$anonymous$$d :P

avatar image the1cyrus · Jul 13, 2014 at 05:55 PM 0
Share

sdgd I've been trying to get in contact with you to get your code working. Do you happen to have a scene or project that you can provide with it working? Cant seem to get my character to move on the planet but it does get attracted to the sphere I'm using as the world. Also what is the math functions script for? Is it used at all by the movement script?

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

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

Problems with Gravity in Unity 4 2 Answers

slide sphere on a slope without rotating 1 Answer

how to make gravity in the center of a sphere 1 Answer

Sphere is noticeably not a sphere when dealing with large spheres? 1 Answer

how to Apply Gravity at Run time ..????????? 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