Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

Faux Gravity making my brain spin... Help!

Discussion in 'Scripting' started by podperson, Feb 12, 2008.

  1. Broken-Toy

    Broken-Toy

    Joined:
    Jan 16, 2010
    Posts:
    455
    Having your gravity be influenced by the terrain's normal à la Mario Galaxy might be closer to what you're looking for. See Rune's Locomotion demo project, it has code for that kind of gravity.
     
  2. jdams

    jdams

    Joined:
    Sep 13, 2010
    Posts:
    64
    Hey First Post!

    I tried all of the codes posted inside this thread and I must be missing something. I too am having the equator problem.
    I am using the FPS character prefab from standard assets and as soon as he passes the equator he falls off of my spherical object.
    I have set my First person character with a rigid body and the FauxGravityBody, with the attractor set to my sphere. My sphere is set with the FauxGravityAttractor. I have turned off use gravity on my player, and set freeze rotation.

    Am I missing a component or script error somewhere?

    Any help would be greatly appreciated.
     
  3. animalfarm

    animalfarm

    Joined:
    Dec 16, 2010
    Posts:
    3
    I would also appreciate some help. Did the same as JDAMS and not working :-(

    edit

    after removing the character controller components in the FPS Controller prefab and replacing it aaronC's first person controller, things worked a bit better. While I don't fall off the planet anymore, the camera doesn't seem to follow the planets curvature, and nor do the movement inputs. pressing forward starts to create jumping movements the steeper i walk down the planet, my character is basically hopping down the planet.

    I'm really new to unity scripting... It's be great if someone could upload an example scene where the scripts in this thread were applied, with character controllers and cameras setup!
     
    Last edited: Dec 19, 2010
  4. towski

    towski

    Joined:
    Dec 30, 2010
    Posts:
    1
    This worked great for me.

    I was trying to rotate the "Planet" too, but I run into problems with camera rotation when you unfreeze the rotation.
     
  5. raymix

    raymix

    Joined:
    Aug 25, 2010
    Posts:
    192
    hi dakungfu, welcome to forums. Thanks for sharing your code will look at it tonight.
    Could you please put your code into [ code ] yourCodeHere [ / code ] tags? Without spaces. That will make it more visible in forum, make smaller post and allow to display your code with spaces and tabs. Thank you :)
     
  6. dakungfu

    dakungfu

    Joined:
    Feb 28, 2011
    Posts:
    2
    Hi raymix,

    Sure thing, I just didn't know how to do it and didn't want to waste time searching for it, I thought it could be something automatic... That's ashaming for someone supposed to know html hehe....
    Ah, keep in mind Unity is something about sizes, so my script works great with a 20 radius planet and a box 1x1 as character. If you change that, you will have to adjust all other variables...

    Here goes:

    Code (csharp):
    1.  
    2. private var speed:float;
    3. var maxSpeed=0.08;
    4. var jumpSpeed = 10.0;
    5. var gravity = 15.0;
    6. private var friction:float;
    7. var floorFriction:float=0.15;
    8. var airFriction:float=0.001;
    9. var aceleration:float=10;
    10.  
    11. var turnSpeed=1.5;
    12. var perceptibleSpeed=0.001;
    13.  
    14. private var normalDirection:Vector3;
    15. var currentPlanet:GameObject;
    16. private var oriented:boolean;
    17. private var tanMove:Vector3;
    18. private var isGround:boolean=false;
    19.  
    20.  
    21. function Start(){
    22. rigidbody.centerOfMass=Vector3(0,-1,0); //this line makes it a little more realistic, allowing it to reorient automatically
    23. //I would use the next line to align the character manually, by maths, but for unknown reasons all my attempts //failed...
    24. //rigidbody.freezeRotation = true;
    25. rigidbody.useGravity=false;
    26. }
    27. function FixedUpdate() {
    28.  
    29. var hit:RaycastHit;//obtaining the normal direction of the planet
    30. if(Physics.Raycast(transform.position,currentPlane t.transform.position-transform.position,hit)){
    31. normalDirection=hit.normal;
    32. }
    33.  
    34. if(Input.GetAxis("Horizontal")){//rotating it in the y axis
    35. transform.Rotate(0,Input.GetAxis("Horizontal")*tur nSpeed,0);
    36. oriented=false;
    37. }
    38.  
    39. if (isGround) {
    40. rigidbody.velocity=Vector3.zero; //assuring the character stop
    41. rigidbody.angularVelocity=Vector3.zero;
    42.  
    43. if(Input.GetAxis("Vertical")){//Here he's able to walk or run to go forward/backward
    44. speed+=Input.GetAxis("Vertical")*aceleration*Time. deltaTime;//I increase/decrease the speed gradually
    45. if(Mathf.Abs(speed)>maxSpeed)
    46. speed=Mathf.Sign(speed)*maxSpeed;
    47. }
    48.  
    49. //Reorient the character once he's back on the ground, this actually just prevent some of the camera shaking
    50. if(!oriented)
    51. Reorient();
    52.  
    53. if (Input.GetButton ("Jump")) {//jumping
    54. rigidbody.velocity= jumpSpeed*normalDirection;
    55. }
    56.  
    57. }
    58. else{
    59. Mygravity();
    60. }
    61.  
    62. // Move the character
    63. tanMove=speed*transform.TransformDirection(Vector3 .forward);//tanMove is the amount of movement tangent to the //planet
    64. if(tanMove.magnitude){
    65. transform.position+=tanMove; //other doubt here, rigidbody.MovePosition() didn´t work at all, anyone knows why?
    66. }
    67.  
    68. if(speed){
    69. Mygravity();
    70. oriented=false;
    71. Desacelerate(); //a simulation of inertia
    72. }
    73. }
    74.  
    75. function Desacelerate(){
    76. speed-=Mathf.Sign(speed)*friction*Time.deltaTime;
    77. if(Mathf.Abs(speed)<perceptibleSpeed)//stopping it if it´s too slow
    78. speed=0;
    79.  
    80. }
    81.  
    82. function OnCollisionEnter(collision:Collision){
    83. if(currentPlanet){
    84. if(collision.gameObject.name==currentPlanet.name){
    85. isGround=true;
    86. friction=floorFriction;
    87. print("hit!"+"data: "+speed);
    88. }
    89. }
    90. }
    91. function OnCollisionExit(collision:Collision){
    92. if(currentPlanet){
    93. if(collision.gameObject.name==currentPlanet.name){
    94. isGround=false;
    95. friction=airFriction;
    96. print("in the air"+"normal: "+normalDirection.magnitude);
    97. }
    98. }
    99. }
    100.  
    101. function Mygravity(){
    102. //Aplying gravity, note that it's applied every frame, without it, our character would escape in the tangent direction every time it moved
    103. gravForce= -gravity*normalDirection;
    104. rigidbody.AddForce(gravForce);
    105. }
    106.  
    107. function Reorient(){//this is just to prevent some of the shaking you see when you have a camera attached to your //character
    108. Vector3.Slerp(transform.TransformDirection(Vector3 .up),normalDirection,1);
    109. oriented=true;
    110. }
    111.  
    112. function AlternativeReorient(){ //it should be the exact calculus.... but it doesn´t work!!!
    113.  
    114. var yproj=Vector3.Project(normalDirection,transform.Tr ansformDirection(Vector3.up));
    115. var xproj=Vector3.Project(normalDirection,transform.Tr ansformDirection(Vector3.right));
    116. var proj=yproj+xproj;
    117.  
    118. var zrot=Mathf.Acos(Vector3.Dot(proj,transform.Transfo rmDirection(Vector3.up))/(proj.magnitude*transform.TransformDirection(Vecto r3.up).magnitude));
    119. //another option:
    120. //var zrot=Vector3.Angle(proj,transform.TransformDirecti on(Vector3.up));
    121.  
    122. transform.Rotate(0,0,zrot);
    123.  
    124. var xrot=Mathf.Acos(Vector3.Dot(normalDirection,transform.TransformDirection(Vector3.up))/(normalDirection.magnitude*transform.TransformDire ction(Vector3.up).magnitude));
    125. //another option:
    126. //var xrot=Vector3.Angle(normalDirection,transform.Trans formDirection(Vector3.up));
    127.  
    128. transform.Rotate(xrot,0,0);
    129. oriented=true;
    130. }
    131. @script RequireComponent(Rigidbody)
    132.  
    133.  
    Attach it to a non kinematic rigid body box to be your character and use a kinematic rigid body sphere as a planet, I haven't tested it with something other than a sphere, but once I used the raycast to have the normal vector, I think it works for other geometries too, just don't forget to use the rigid bodies, otherwise the collision won't work and the script will never detect when you are "grounded".

    thanks for the feedback
     
    Last edited: Mar 1, 2011
  7. alex.loren

    alex.loren

    Joined:
    Jan 7, 2011
    Posts:
    83
    In regards to the posts regarding not being able to get the majority of the scripts posted in this topic to work as intended, albeit the posts are slightly aged, I had 10 minutes of time to spare this evening and have put together a working sample of the system working, with an included scene, camera and player script. You can fetch the Unity package here on DropBox. Feel free to let me know if there are any issues found within the package or if you have any questions as to the functionality. Have fun!
     
  8. Asterisk

    Asterisk

    Joined:
    Feb 10, 2011
    Posts:
    1
    Awesome. This provides clarity on the entire situation. Thanks alex.loren. Really helps!
     
  9. alex.loren

    alex.loren

    Joined:
    Jan 7, 2011
    Posts:
    83
    Asterisk, I am glad that I was able to provide you with the insight needed. I do hope that it was able to give you that extra push needed to assist with finishing your current project.
     
  10. zbell91

    zbell91

    Joined:
    Apr 3, 2011
    Posts:
    4
    @ alex.loren: I loved the sample that you produced to display how the fauxGravity works. Your example works a bit better than mine and I was wanting to use it. If it isn't too much trouble, do you think that you could convert it into JavaScript for me?

    I'm not sure how much of a hassle that is for you, but I was hoping that I wouldn't have to use the Cs scripts along with my other Js stuff!
     
  11. synapsemassage

    synapsemassage

    Joined:
    Jul 27, 2009
    Posts:
    333
    you could get the javascript converter from unity's assetstore
     
  12. zbell91

    zbell91

    Joined:
    Apr 3, 2011
    Posts:
    4
    I'll look into that. Thanks!

    EDIT: I was only able to find Js to C# converters, not the other way around.
     
    Last edited: Apr 4, 2011
  13. Magicpickle97

    Magicpickle97

    Joined:
    Feb 19, 2011
    Posts:
    89
    Great job with the scripts
     
    Last edited: Aug 4, 2011
  14. Magicpickle97

    Magicpickle97

    Joined:
    Feb 19, 2011
    Posts:
    89
    Can I use this In a Commercial Game?
     
  15. poptart

    poptart

    Joined:
    Aug 7, 2011
    Posts:
    4
    This is an awesome example... But how can this be used for AI? I am very curious...
     
  16. kodagames

    kodagames

    Joined:
    Jul 8, 2009
    Posts:
    488
    First off THANK YOU VERY MUCH! for the code help using Faux Gravity its amazing!

    I was wondering if anyone could help me with another part of it and thats Shooting. How would I shoot a bullet and have it go around the world? I have this bullet script:

    Code (csharp):
    1.  
    2. var singleBullet : Transform;
    3. var singleSpeed : int = 2000;
    4. var shootPos : Transform;
    5.  
    6. private var nextFireTime : float; //when can we shoot again
    7. static var rapidFireDelay : float = 0.5; //delay between shots
    8. var reloadTime : float = 1.0; //time it takes to reload :)
    9.  
    10. private var theClip : int; //ammo remaining in clip
    11. var ammoPerClip : int = 5;
    12.  
    13.  
    14. function Start()
    15. {
    16.     theClip = ammoPerClip;
    17.     //rapidFireDelay = 0.5;
    18. }
    19.  
    20.  
    21. function Update()
    22. {
    23.     //If I make it GetMouseButton without the down it will fire automatically :)
    24.     if(Input.GetMouseButton(0))
    25.     {
    26.         if ( nextFireTime <= Time.time )
    27.             {
    28.                 nextFireTime = Time.time + rapidFireDelay;         
    29.        
    30.                 SingleShot();
    31.             }      
    32.     }
    33. }
    34.  
    35. function SingleShot()
    36. {
    37.     theClip--;//I made the clip soze 0 in the inspector, if I need clip sizes Dont forget to add them to controlspray, random, 3-way
    38.    
    39.     if(theClip < 0)
    40.     {
    41.         Reload();  
    42.     }
    43.     else
    44.     {
    45.         var bullet = Instantiate(singleBullet, shootPos.transform.position, shootPos.transform.rotation);
    46.         bullet.rigidbody.AddForce(bullet.transform.forward * singleSpeed);
    47.         bullet.name = "iBullet";
    48.        
    49.         //rapidFireDelay = 0.15;
    50.     }  
    51. }
    52. function Reload()
    53. {
    54.     theClip = ammoPerClip;
    55.     nextFireTime = Time.time + reloadTime;
    56. }
    57.  
    So that the bullet would also use the Faux Gravity but above the sphere (not grounded) and go around the sphere back to its starting place.
     
  17. xtunafishx

    xtunafishx

    Joined:
    Jul 2, 2011
    Posts:
    38
  18. kodagames

    kodagames

    Joined:
    Jul 8, 2009
    Posts:
    488
    EDIT: ALMOST THERE

    Ok Im getting a whole lot closer but just cant figure the rest out I added this
    Code (csharp):
    1.  
    2. var degrees = 10;
    3. var target : Transform;
    4.  
    5. function Update()
    6. {
    7.     transform.RotateAround (target.position, Vector3.forward, degrees * Time.deltaTime);//Vector3.up
    8. }
    9.  
    But the problem is at the (East West) poles of the sphere the bullet will make little circles? anywhere else on the sphere its nice if I change the code to Vector3.up I get the same results but at the (North South) poles of the sphere.

    So Problems with this bullet so far:
    1) small circles at 2 poles
    2) bullet always goes one direction and not where the player is facing

    This is as close as I've gotten if anyone wants to jump in and help that would be AWESOME!
     
    Last edited: Aug 27, 2011
  19. emannazir

    emannazir

    Joined:
    Jan 28, 2012
    Posts:
    138
    alex.loren i have a problem when i apply your script on multiple shapes they wont work as planet like in rectangle square etc and i want to place
    2 shapes with some distance and want character jump from one shape to other how it will be possible? and what if i want to make FPS or 3PS character or want to apply character controller script? please help me in scripting.
     
    Last edited: Feb 2, 2012
  20. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,923
    So essentially you're asking someone to make your game for you. No dice.
     
  21. emannazir

    emannazir

    Joined:
    Jan 28, 2012
    Posts:
    138
    no am just asking help me to do this
     
  22. kurai

    kurai

    Joined:
    Jan 9, 2012
    Posts:
    110
    Hi there. I'm trying to do exactly that, but... How can I implement the player movement? I tried to add a character controller to my player object but... It ends up fired into outer space. I'm clueless.

    Then I tried manually scripting the movement, and I modified the fixedupdate of the FauxGravityBody like this:
    Code (csharp):
    1. function FixedUpdate () {
    2.  
    3.     if(attractor){
    4.  
    5.         attractor.Attract(this);
    6.  
    7.         if (grounded)
    8.         {
    9.             moveDirection = Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
    10.  
    11.  
    12.             if (moveDirection != Vector3.zero) {
    13.                 var rotation = transform.rotation;
    14.                 rotation.SetLookRotation(moveDirection);
    15.                 rigidbody.rotation = rotation;
    16.             }
    17.             moveDirection *= speed;
    18.             rigidbody.position= moveDirection;
    19.         }
    20.  
    21.     }
    22.  
    23. }
     
    Last edited: Apr 21, 2012
  23. Wildpepper

    Wildpepper

    Joined:
    Dec 15, 2009
    Posts:
    30
    Hey there !
    I'm sorry for digging out this old post, but it's the only way I won't be addressed here, or using search keywords like "mario galaxy" "spherical gravity" and so on.

    I've been playing around with all of the code posted here, and looks like I can't find a way of having a character controller moving on an uneven spherical surface, like the one in the image on the first post.

    The closer thing is the example scene posted by alex.loren, but there is no way of making the character walk on anything different from a sphere.

    did anybody find a solution ?

    thank you for your time :)
     
  24. halowiz

    halowiz

    Joined:
    Jul 1, 2012
    Posts:
    5
    Hey all, so I'm using this code for a 2D game which doesn't even require use of the Y axis in this case, but that's just a different story. My real question that I need help with is, is that I have a small 2D planet demo (kinda like Asteroids) and there is a ship with multiple planet gameobjects floating around with the FauxGravityAttractor script on them, the thing is I want it to work like this: when the player presses "spacebar" the ship will turn on the attractor script of the nearest planet within a set range of the ship and modify the ship's gravity to the planet until the player hits "spacebar" again at which point the planet will deactivate the attractor and the player can then fly away. Can anybody PLEASE help with accomplishing this?
     
  25. SJames

    SJames

    Joined:
    Nov 6, 2012
    Posts:
    1
    So far all of the code posted doesn't include the character movement, which is the hard part, so none of this is actually functional for "Super Mario galaxy" style games. Does anyone have an example of gravity code for planet walking that includes movement around this planet?
     
  26. kaedmon

    kaedmon

    Joined:
    Jan 28, 2010
    Posts:
    25
    For any developers out there who would like to implement this really easily, try out:


    World Physics System ~ http://nimbusgarden.com/worldphysicssystem

    The World Physics System is a celestial body point gravity scripting interface for Unity, intended as a replacement for the stock downward gravity. WPS can be used to simulate planetary orbits, body-body attraction, or "snowballing" effects. You may use it to create spherical worlds "out-of-the-box," but World Physics System is implemented robustly and is lightweight, providing you complete freedom in expressing your point gravitation creativity, complex and repulsive forces, allowing you to use the system as a subcomponent for other effects, such as spells, powerups, or goal-based Artificial Intelligences for NPC's. With the WPS, the sky is truly the limit!

    Available from the Unity Asset Store, here.

    More information, here.

    Happy New Year!!!

    ~ The Nimbus Garden Team
     
  27. codemypantsoff

    codemypantsoff

    Joined:
    Jan 23, 2013
    Posts:
    8
    @kaedmon - Do you have an example of using the WPS as a Mario Galaxy style platform engine - I have the system and am having issues even getting a cube to be attracted to another cube
     
  28. alexispolak

    alexispolak

    Joined:
    Mar 3, 2013
    Posts:
    32
    Thanks a LOT !
     
  29. kodagames

    kodagames

    Joined:
    Jul 8, 2009
    Posts:
    488
    its been a long while but someone had PM'ed me asking:

    1) Somewhere in this thread is what I used to get the character working correctly traveling around a sphere.

    2) For the shooting of the bullets it was quite simpler than I had thought (its been a while I'll do my best to remember get it right), all I did was focus on the sphere to make sure you centered on it, create an empty gameObject and check in all directions that it is centered. Then create a simple rotate script that is always rotating attach it to this gameObject. Then I created another empty gameObject or prefab for my bullet which is a child of the empty gameObject created earlier. Last when I hit fire to shoot the bullet I call instantiate to instantiate the rotating element not just the bullet and it worked great for me.

    The speed of the rotation can be adjusted to look good and give distance between each bullet as well as oncollision destroy the rotating element not just the bullet. Hope if helps.

    Sincerely,
    Michael
     
    Last edited: May 22, 2013
  30. zephjc

    zephjc

    Joined:
    May 16, 2013
    Posts:
    2
    Issues I've noticed trying to make this work:
    - Mass on the attractor's rigidbody must be set to a very high value or else other bodies colliding with it will knock it around. This one makes sense given AddForce is being used. A lower mass could add realistic opposing-force motions to bodies, which could make for interesting gameplay, e.g having to jump between small planetoids in a careful way!
    - The stock Character Motor/FPSInput Controller scripts are pretty much totally incompatible with this; new ones need to be used that work with it a moving up vector.
    - The Mouse Look script does not work correctly with it: "up" needs to be whatever the attractor/camera vector is, but it currently uses the global "up"
     
  31. enyon

    enyon

    Joined:
    Sep 11, 2013
    Posts:
    5
    @alex.loren

    This is great, everything one needs, even a player control script. Thanks! Unfortunately the switch was only on TODO list
    I know it is old post but did you got around making that switch and have it somewhere by chance?
     
  32. enyon

    enyon

    Joined:
    Sep 11, 2013
    Posts:
    5
    Your edit is nice. Problem is that it works only for one FauxGravityAttractor. If you use multiple attractors it always rotate towards the last target added to FauxGravityBody. I am trying to figure out how to change that...
     
  33. lorenalexm

    lorenalexm

    Joined:
    Dec 14, 2012
    Posts:
    301
    @enyon

    It has been years since I have posted the original package, and haven't looked at it since that time. Some months ago I retouched the idea, are you looking for something similar to the attached video? Please note that it is in a very rough stage as I never spent much time on it. If there is a large enough need, I might entertain cleaning up the source and writing up some documentation and releasing it on the Asset Store.

     
  34. Guliavan

    Guliavan

    Joined:
    Sep 16, 2013
    Posts:
    3
    Hi there, great scripts, thanks for sharing all this. I'm wondering if it would be very complicated to do a switch of planets by simply jumping ? I'm thinking of putting an attraction "aura" around the planets and do switch of attractor when the player enters another aura. I'm new to unity and I'm not sure how to do this o_O...

    Thanks
     
  35. lorenalexm

    lorenalexm

    Joined:
    Dec 14, 2012
    Posts:
    301
    Depending on how you handle your controller, you could always use Physics.OverlapSphere for each object that needs to attract others, then check the distance to each planet and have the closest one attract your object. This could cause a lot of overhead though, and you may be better off simulating a gravitational field from each planet.
     
  36. enyon

    enyon

    Joined:
    Sep 11, 2013
    Posts:
    5
    @lorenalexm

    Well I end up using previous code from website, but still have problem switching from planet to planet... its project for class, deadline is this week so I ll probably go just with simple platformer since I did not figure out the switching yet and already need to start modeling some assets.
     
  37. Guliavan

    Guliavan

    Joined:
    Sep 16, 2013
    Posts:
    3
    Thanks for the answer. This is interesting, I will check out the OverlapSphere. I recently checked another project that used this technique. I think I can live with the fact that the player "decides" which planet he is attracted to, ultimately, as it is right now. What I'd like, though, is being able to do a switch of attractor while the player enters a planet's "aura". I don't necessarily have to do a distance calculation then, do it ? Maybe the overlapsphere can help me do this detection? Or there might be a better way?
     
  38. enyon

    enyon

    Joined:
    Sep 11, 2013
    Posts:
    5
    @Guliavan

    I am using the script on the second page of this post by @techmage with the edit by @Broken Toy couple replays later.

    With this you are getting attracted to all the attractors you plug in to script and with fade distance you are getting attracted to ones you are closest to. Only thing I need to solve right now is to figure out correct UP direction to rotate the player head up feet down to current gravity :) Right now It only works for the last added attractor.
     
  39. Guliavan

    Guliavan

    Joined:
    Sep 16, 2013
    Posts:
    3
    Thanks enyon. I already checked and tried the code you mentioned. I'm trying to make it work using an OverlapSphere first. I'm trying to make it work on the FauxGravityAttractor. I got two questions though. First, I got 4 objects in my scene: 2 planets, a player and a cube. I'd like the first planet to attract the cube and the player in it's range. However, it seems that whatever range I set in the OverlapSphere, it will always return to me all 4 objects in the scene. I made a Gizmos.DrawSphere to give me an idea of the range values. Does anyone know why this happens ? I googled a bit and I didn't find a good answer...

    Next, I worked around that problem temporarily by selecting only items with the tag "Attractee" and I tagged the cube and the player... now I want the Attractor to attract these object, but I need to cast them so they are recognized as FauxGrabityBodies and not gameobjects. Do anyone know how to do this in Unity ?

    Thanks, here's my draft code (the cast doesn't work offcourse)

    Code (csharp):
    1. void FixedUpdate()
    2.     {
    3.         Collider[] cols  = Physics.OverlapSphere(transform.position, m_AttractionRange);
    4.        
    5.         foreach(Collider c in cols)
    6.         {
    7.             if(c.tag == "Attractee") {
    8.                 Debug.Log(c.gameObject.name);
    9.                 this.Attract(c.gameObject as FauxGravityBody);
    10.             }
    11.         }
    12.     }
     
  40. enyon

    enyon

    Joined:
    Sep 11, 2013
    Posts:
    5
    @Guliavan I am not sure what you are trying to do. I wont be much help since I am new to .js

    Here is what I got by editing previous script (aimed for side-scrolling view), it works if Attractros are in some "correct" order and you can jump from one to another. (Move script is really rough) FauxGravityBody (FGB) and Move apply to player, FauxGravityAttractor (FGA) to a planet, plug all Attractors into Body and check that you want snap Y axes in Body as well. The script show gizmos for gravity area and gravityFade area.

    What I changed is only that FGA: Add parameter Planet to Attract function, and use Planet in calculating the playerUp vector and rotate player to it instead of gravityUp. FGB: Add function to find nearest game object with tag planet and call function attract with this parameter as well.

    https://www.dropbox.com/sh/ptq62zdj1hvmjoa/-JrGLC_8jV
     
  41. windkeeper4

    windkeeper4

    Joined:
    Sep 27, 2013
    Posts:
    1
    Would it be possible to modify this script so movement is accomplished on a torus shape instead of a sphere, or failing that so that movement is accomplished inside of a sphere?
     
  42. Marsupilami

    Marsupilami

    Joined:
    Sep 22, 2013
    Posts:
    21
    I've seen many versions of this code. I thought I would post my solution. I believe my code is pretty straight forward and simplified as far as I ccan make it.

    Create a sphere of just about any size and create a tag called "Planet" for it. The bigger the better. I've tested with scale sizes from 5-250. Attach an empty child game object and add a sphere collider component set the "is Trigger" flag and change the radius to 1. Create a script for the child and use the code below. This will give you a gravity trigger with 2x the radius of the planet with a modifiable gravity magnitude that will attract all rigid bodies within range.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Planet_Gravity : MonoBehaviour {
    6.  
    7.     public float gravityMagnitude = 100;
    8.    
    9.     private Vector3 vectorNormal;
    10.    
    11.     void OnTriggerStay (Collider other)
    12.     {
    13.         if (other.rigidbody != null)
    14.         {
    15.             vectorNormal = transform.position - other.transform.position;
    16.             other.rigidbody.AddForce(vectorNormal * Time.deltaTime * gravityMagnitude);
    17.         }
    18.     }
    19. }
    20.  
    Create a player. I used a capsule of standard size. Add a rigid body, turn off gravity and freeze rotation. Add a script with the code below. Reference your planet to the targetPlanet variable. Child your main camera to the player object and adjust to your liking. Your player can move forward, move backward, move left, move right, turn left, turn right and jump. The lower the planet's gravity the higher you can jump. Adjust public variables to your liking. Create input variables for "Sprint" and "Strafe" to use those controls.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Planet_PlayerController : MonoBehaviour {
    6.    
    7.     public Transform targetPlanet;
    8.    
    9.     public float walkSpeed = 5.0f;
    10.     public float runSpeed = 10.0f;
    11.     public float strafeSpeed = 3.5f;
    12.     public float turnSpeed = 100.0f;
    13.     public float jumpSpeed = 10.0f;
    14.     public float gravitySpeed = 100.0f;
    15.    
    16.     private Vector3 vectorNormal;
    17.     private Vector3 vectorCross;
    18.    
    19.     private bool canJump = false;
    20.    
    21.     void FixedUpdate ()
    22.     {
    23.         if (Input.GetButton("Sprint"))
    24.         {
    25.             transform.position += transform.forward * (Input.GetAxis("Vertical") * Time.deltaTime * runSpeed);
    26.         }
    27.         else
    28.         {
    29.             transform.position += transform.forward * (Input.GetAxis("Vertical") * Time.deltaTime * walkSpeed);
    30.         }
    31.         transform.position += transform.right * (Input.GetAxis("Strafe") * Time.deltaTime * strafeSpeed);
    32.        
    33.         if (Input.GetButton("Jump")  canJump)
    34.         {
    35.             rigidbody.AddForce(vectorNormal * jumpSpeed);
    36.         }
    37.        
    38.         transform.Rotate(new Vector3(0, Input.GetAxis("Horizontal") * Time.deltaTime * turnSpeed, 0));
    39.        
    40.         vectorNormal = transform.position - targetPlanet.position;
    41.         vectorCross = -Vector3.Cross(vectorNormal, transform.right);
    42.         transform.rotation = Quaternion.LookRotation(vectorCross, vectorNormal);
    43.     }
    44.    
    45.     void OnCollisionStay (Collision other)
    46.     {
    47.         if (other.gameObject.tag == "Planet") {canJump = true;}
    48.     }
    49.    
    50.     void OnCollisionExit (Collision other)
    51.     {
    52.         if (other.gameObject.tag == "Planet") {canJump = false;}
    53.     }
    54. }
    55.  
    To Do: Create a jetpack, allow free orientation in "free space" and transitions to other planets using proximity and teleporters.

    Enjoy!
     
  43. Marsupilami

    Marsupilami

    Joined:
    Sep 22, 2013
    Posts:
    21
    If you implemented your gravity on the player script and used a raycast to get the polygon orientation directly under the player and apply gravity in the direction of that polygon you could attach your player to any surface. I may try something like this..
     
  44. sabotage234

    sabotage234

    Joined:
    Jun 20, 2013
    Posts:
    1
    I created an implementation using a first person view that checks the normal below the player and allows them to rotate and move around.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class PlayerMovement : MonoBehaviour {
    6.    
    7.     public float walkAcceleration = 1000;
    8.     public GameObject cameraObject;
    9.     public float maxWalkSpeed = 20;
    10.     Vector3 horizontalMovement;
    11.    
    12.     public float jumpVelocity = 600;
    13.     public float maxSlope = 45;
    14.    
    15.     public float walkDecelleration = 1;
    16.     public float airAccMod = .5f;
    17.     float walkDecX;
    18.    
    19.     float walkDecY;
    20.    
    21.    
    22.     float walkDecZ;
    23.     public bool grounded = true;
    24.     public float grav = 750;
    25.    
    26.     MouseLookFpsScript cameraMouseLook;
    27.    
    28.     public float lookSmoothDamp=.1f;
    29.    
    30.     public float xLookSensitivity = 320f;
    31.     float currYRotation = 0;
    32.     float yRotation;
    33.     float yRotationVel;
    34.    
    35.     public float sler = .1f;
    36.    
    37.     float diffY;
    38.     public int layerNumber;
    39.    
    40.     // Use this for initialization
    41.     void Start () {
    42.         cameraMouseLook = (MouseLookFpsScript) cameraObject.GetComponent("MouseLookFpsScript");
    43.    
    44.     }
    45.    
    46.    
    47.     // Update is called once per frame
    48.     void FixedUpdate () {
    49.  
    50.         //Setting limit to Rigidbody velocity
    51.         horizontalMovement = new Vector3(rigidbody.velocity.x,rigidbody.velocity.y, rigidbody.velocity.z);
    52.         if(horizontalMovement.magnitude > maxWalkSpeed){
    53.             horizontalMovement = horizontalMovement.normalized;
    54.             horizontalMovement *= maxWalkSpeed;
    55.             print ("kittens");
    56.         }  
    57.         rigidbody.velocity = new Vector3(horizontalMovement.x, horizontalMovement.y, horizontalMovement.z);
    58.        
    59.        
    60.        
    61.         //Adding friction
    62.         if(grounded){
    63.             rigidbody.velocity = new Vector3(Mathf.SmoothDamp(rigidbody.velocity.x,0,ref walkDecX,walkDecelleration),
    64.                 Mathf.SmoothDamp(rigidbody.velocity.y,0,ref walkDecY, walkDecelleration),
    65.                 Mathf.SmoothDamp(rigidbody.velocity.z,0,ref walkDecZ, walkDecelleration));
    66.         }
    67.        
    68.        
    69.         //Setting up raycast
    70.         RaycastHit groundRay;
    71.         Debug.DrawRay (transform.position,transform.up * -50, Color.red);
    72.         bool hitGround = Physics.Raycast(transform.position, -1 * transform.up, out groundRay);
    73.        
    74.  
    75.         //Rotating player based on grounds normal, looking for specific LayerMask that the player is gravited towards.
    76.         int gravLayMask = (1 << layerNumber);
    77.         print (gravLayMask);
    78.         if(Physics.Raycast(transform.position, -1 * transform.up, out groundRay,100, gravLayMask)){
    79.             Quaternion temp = Quaternion.FromToRotation(transform.up, groundRay.normal);
    80.             temp = temp * transform.rotation;
    81.             transform.rotation = Quaternion.Slerp(transform.rotation,temp,sler);
    82.         }
    83.        
    84.        
    85.        
    86.         //Rotate the player to look, change "y"
    87.         yRotation += Input.GetAxis("Mouse X") * xLookSensitivity;
    88.         diffY = yRotation-diffY;
    89.         currYRotation = Mathf.SmoothDamp(currYRotation,diffY,ref yRotationVel, lookSmoothDamp);
    90.         transform.Rotate(0,currYRotation*Time.deltaTime,0);
    91.         diffY = yRotation;
    92.  
    93.    
    94.        
    95.         //Moving the player
    96.         if(grounded){
    97.             rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration *Time.deltaTime, -1*grav * Time.deltaTime, Input.GetAxis("Vertical")* walkAcceleration*Time.deltaTime);
    98.         }else{
    99.             rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration *Time.deltaTime * airAccMod ,-1 * grav * Time.deltaTime, Input.GetAxis("Vertical")* walkAcceleration*Time.deltaTime * airAccMod);
    100.         }
    101.        
    102.         //Jump
    103.         if(Input.GetButtonDown("Jump")  grounded){
    104.             rigidbody.AddRelativeForce(0,jumpVelocity,0);
    105.         }
    106.        
    107.     }
    108.    
    109.     //Checks if the collider is touching ground beneath the player.
    110.     void OnCollisionStay(Collision collision){
    111.         foreach(ContactPoint contact in collision.contacts){
    112.             if(Vector3.Angle(contact.normal, transform.up)< maxSlope){
    113.                 grounded = true;   
    114.             }
    115.         }
    116.     }
    117.    
    118.    
    119.     void OnCollisionExit(){
    120.         grounded = false;  
    121.     }
    122.    
    123. }
    I also made a post that describes this in much more detail at my blog here. This can also allow the player to go up hills or other objects without orienting themselves up the hill/object using the layerMask. Also, for people who are having trouble, make sure you are not using the premade character controller for your player.
     
  45. newb_quest

    newb_quest

    Joined:
    Oct 4, 2013
    Posts:
    22
    hey all,

    Just wanted to say thanks to Podperson for the awesome scripts! I've used them in my project to create homing missiles and a gravity system that sucks powerups over to the player on collision. Really cool! I'm also planning to build out a black hole type weapon that sucks enemies into a point when you fire it. Awesome stuff!

    Video dev blog here showing some of the implementation:
    http://newbquest.com/?p=132

    Thanks again!
    M.
     
  46. BotHH

    BotHH

    Joined:
    Apr 22, 2013
    Posts:
    2
    Thanks for all the code and revisions everyone everything's working perfectly for me.

    I just have one problem, I want the player to be a ball which rolls along the surface of the "planet".With the rotation locks it wont roll along naturally and without the rotation locks it just goes haywire, I've tried creating a dummy sphere over the top of the player sphere but the two rigidbodies glitch and they shoot off into space. Does anyone have any idea how I could go about this? I'm about 6 hours on this one problem and I'm just about ready to pull my hair out. I'm using alex.loren's version of the code. I can post a package of it if anyone needs it. Any insight would be great. Thanks.
     
    Last edited: Dec 6, 2013
  47. TheShane

    TheShane

    Joined:
    May 26, 2013
    Posts:
    136
    Remove the rigidbody from your dummy sphere, and rotate it manually based on how far your player moved and the radius of the planet. The position and collisions are handled by the rigidbody controller. The physics engine is not going to allow two rigidbodies to overlap, and you don't really need or want that anyway. The rolling of the ball will work just as an animation that you create procedurally with the movement of the player.
     
  48. BotHH

    BotHH

    Joined:
    Apr 22, 2013
    Posts:
    2
    I've got it working well now, I removed the mesh renderer for the ball and placed the dummy ball atop. Then I set its rotation using the players movement, I had some problems with this as after a while it begin rolling in unnatural ways. I had continually reset the rotation based on the camera, lock the position of the player and roll the planet in the opposite direction to get what looks like a naturally rolling ball. The codes not pretty but it works. Thanks for the help.
     
    Last edited: Dec 13, 2013
  49. briward

    briward

    Joined:
    Dec 15, 2013
    Posts:
    1
    I love this code dude although I can't seem to figure out how to get the jump to work properly? If using the addForce it will just send him straight into space with no hope of returning?
     
  50. JonathanBurroughs

    JonathanBurroughs

    Joined:
    Jan 22, 2014
    Posts:
    16
    I found Sebastian Lague's Faux Gravity tutorial video invaluable:



    That said I've run into a similar obstacle to briward and am having trouble using RigidBody.ApplyForce to get my character off the ground. I've been doing an OnCollisionStay check to determine when my character is in contact with another collision object and then applying RigidBody.ApplyForce in the local vertical to try and get the character off the ground. But no matter how much I multiple the ApplyForce by I barely blip off the surface of my sphere.

    Any idea where I might be going wrong?
     
    Last edited: Aug 18, 2017