Hi Everyone! Forgive me if there is already another post addressing something like this, but I haven't found it yet. I'm trying to get my object to ignore the default gravity field and move between the walls of the pipe in the attached image. The effect I'm trying to achieve is to allow my player (cube) to exit with a different rotation/spin when leaving the pipe as it falls back toward the ground. I've seen an attractor script for planetary bodies elsewhere, but I'm not sure those apply to this scenario or not. Obviously, I'm planning on using a mesh collidor for my pipeline in the image (I created this in Blender) and the faces are inverted. If I need to create a script for this, where would I start? Which object would I apply this script to and in which way?
You have few ways of doing it. But I describe 2. 1, Switch on/off gravity on RigidBody itself. 2. Use own gravity script, to control gravity acting on objects. You can have then even planetary effect.
Hi @Antypodish , thanks for your reply! I wanted to ask, would this allow my cube to turn upside down as it moves left and right in the pipe structure?
If you switch off gravity on Rigid Body, and apply forces at the cube, pointing toward cross section center of the pipe, then should not be issue. Your force vector would be ( center of pipe position - cube position ) multiply by actual force ( gravity ). So you can technically even jump upside down.
Hi @Antypodish , I think I may know what you're getting at! Just thought I'd ask though - not sure how I'd calculate the center of my pipe FBX model, but here's the current code I'm playing around with: Code (CSharp): private void OnCollisionEnter(Collision collision) { //collision.gameObject.GetComponent<Rigidbody>().transform.up = Vector3.zero; //player.gameObject.GetComponent<Rigidbody>().useGravity = false; myNormal = transform.up; playerRB = collision.gameObject.GetComponent<Rigidbody>(); gravity = 0; //playerRB.isKinematic = true; //player.gameObject.GetComponent<Rigidbody>().AddRelativeForce() } private void FixedUpdate() { if (gravity == 0) { myNormal = transform.up; playerRB.AddForce(-10 * playerRB.mass * myNormal); } } private void OnCollisionExit(Collision collision) { //player.gameObject.GetComponent<Rigidbody>().useGravity = true; gravity = 1; playerRB.isKinematic = false; } I have the player rigidbody declared as a global variable earlier, along with the gravity flag, etc. Probably not the best way to do it but I'm lazy - outside of that, what would you do differently about the functions I'm using above?
Ah just looked at your image again. you walking inside pipe, not outside of the pipe? If inside, then vector need push away from center. Other than that - You know where is the pipe. You can either cache gameObject, ray cast, or detect on collision. - You know orientation of the pipe, or pipes - You know length (scale). Most likely forward z axis. - You know position of player / cube - What you need, is a distance from cross section center. - Therefore, what you need, is project calculated distance vector from center of pipe object, to pipe forward vector. Something like that (for pushing outised) (untested may not work directly), but you get an idea. Code (CSharp): Vector3 vectorFromPipeCenter = cubePosition - pipeCenter ; Vector forwardPipeVector = pipeRotation * Vector3.forward ; // or Vector forwardPipeVector = pipeTransform.forward ; // And finally Vector project2Center = Vector3.Project ( vectorFromPipeCenter, forwardPipeVector ) ; float radiusFromCrossectionCenter = project2Center.magniude ;
Hi @Antypodish , Yes. I do want the cube to be walking INSIDE the pipe. On that note, should I pass the pipe in as a global parameter in the class this method belongs to? Or can I call on the pipe to get the center of it in the function itself? Code (CSharp): private void OnCollisionEnter(Collision collision) { //collision.gameObject.GetComponent<Rigidbody>().transform.up = Vector3.zero; //player.gameObject.GetComponent<Rigidbody>().useGravity = false; myNormal = transform.up; playerRB = collision.gameObject.GetComponent<Rigidbody>(); gravity = 0; //playerRB.isKinematic = true; //player.gameObject.GetComponent<Rigidbody>().AddRelativeForce() }
Preferably store data in scripts, where you going use it. If you can, avoid global parameters. Make a script with class holding pipe methods and properties. And then instantiate this class, in the script you are going to use. This script should hold references to pipe, or pipes. Probably as a list, or dictionary.
Hi @Antypodish ! So, I tried to apply what you said, though not necessarily doing all the things I should do like avoid using global parameters. Can you tell what I'm doing below exactly? I've had no success with getting the cube to stick to the walls of the pipe yet instead of falling down. Code (CSharp): private void FixedUpdate() { if (gravity == 0) { myNormal = transform.up; //playerRB.AddForce(-10 * playerRB.mass * myNormal); vectorFromPipeCenter = playerRB.position - attractRB.position; forwardPipeVector = attractRB.rotation.z * Vector3.forward; // or //Vector forwardPipeVector = pipeTransform.forward; // And finally project2Center = Vector3.Project(forwardPipeVector, forwardPipeVector); float radiusFromCrossectionCenter = project2Center.magnitude; playerRB.AddForce(project2Center); } }
If you falling down, means your normal gravity is still active. What script tries to do, is to find a vector, facing toward center of pipe, oriented in its forward direction. To get vector to center, along its axis, you need project vectors, to find perpendicular vector to pipe axis. Vector Projection https://en.wikipedia.org/wiki/Vector_projection I hope you are not color blind, as I used colors here, for better picturing Simply you are looking for a2, which is project2Center, which is calculated by Vector3.Project ( vectorFromPipeCenter, forwardPipeVector); Where a1 = forwardPipeVector and a = vectorFromPipeCenter. Now I just realized, I made slight mistake. Since I accidentally put into Vector3.Project twice forwardPipeVector, instead vectorFromPipeCenter and forwardPipeVector. So now you project a onto a1 to get a2. now suitable is to get normalized a2 vector, so you normalizing it. which means values of vector are between -1 and 1. With that, you should have artificial gravity direction, which you can apply to AddForce. And second mistake I made. Code (CSharp): Vector3 pipeGravityPull = project2Center.normalized * Mathf.Pow ( radiusFromCrossectionCenter * someOptionalForceFactor ), 2 ) ; // pipe pull force = distance from pipe center to power 2 playerRB.AddForce ( pipeGravityPull ) ; just on side note, forwardPipeVector = attractRB.rotation.z * Vector3.forward; // getting forward vector of the pipe axis. is the same as attractRB.transform.forward ; If all that makes sense Code (CSharp): private void FixedUpdate() { if (gravity == 0) { myNormal = transform.up; //playerRB.AddForce(-10 * playerRB.mass * myNormal); vectorFromPipeCenter = playerRB.position - attractRB.position; forwardPipeVector = attractRB.rotation.z * Vector3.forward; // or //Vector forwardPipeVector = pipeTransform.forward; // And finally project2Center = Vector3.Project(forwardPipeVector, vectorFromPipeCenter); float radiusFromCrossectionCenter = project2Center.magnitude; // pipe pull force = distance from pipe center to power 2 Vector3 pipeGravityPull = project2Center.normalized * Mathf.Pow ( radiusFromCrossectionCenter * someOptionalForceFactor ), 2 ) ; playerRB.AddForce ( pipeGravityPull ) ; } } Something like that, if haven't made more mistakes.
Actually, I wonder if I'm also doing it wrong since I'm trying to trigger this movement when the player cube COLLIDES with the pipe, like so: Code (CSharp): private void OnCollisionEnter(Collision collision) { //collision.gameObject.GetComponent<Rigidbody>().transform.up = Vector3.zero; //player.gameObject.GetComponent<Rigidbody>().useGravity = false; myNormal = transform.up; playerRB = collision.gameObject.GetComponent<Rigidbody>(); gravity = 0; //playerRB.isKinematic = true; //player.gameObject.GetComponent<Rigidbody>().AddRelativeForce() } Maybe it's better to do something different? Not sure. What do you think?
Also, should I be making only the player a rigid body and the pipe not a rigid body? Or does that even matter?
Well I turned the player's gravity back on. However movement still seems to be the same. Here's my overall code, in case you wonder. Again, I know you said don't use global variables (which makes sense) but I'm just playing around "gravity" is just a flag to figure if I should allow gravity to run its normal course or start to attract the RigidBody towards the pipe center. Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; public class FauxGravity : MonoBehaviour { public Transform attractor; public Transform player; Rigidbody attractRB; Rigidbody playerRB; Vector3 myNormal; Vector3 vectorFromPipeCenter; Vector3 forwardPipeVector; Vector3 project2Center; int gravity = 1; // Use this for initialization void Start () { attractRB = attractor.GetComponent<Rigidbody>(); } // Update is called once per frame void Update () { } private void OnCollisionEnter(Collision collision) { //collision.gameObject.GetComponent<Rigidbody>().transform.up = Vector3.zero; //player.gameObject.GetComponent<Rigidbody>().useGravity = false; myNormal = transform.up; playerRB = collision.gameObject.GetComponent<Rigidbody>(); gravity = 0; //playerRB.isKinematic = true; //player.gameObject.GetComponent<Rigidbody>().AddRelativeForce() } private void FixedUpdate() { if (gravity == 0) { Debug.Log("Gravity is 0."); myNormal = transform.up; //playerRB.AddForce(-10 * playerRB.mass * myNormal); vectorFromPipeCenter = playerRB.position - attractRB.position; //vectorFromPipeCenter = attractRB.position - playerRB.position; forwardPipeVector = attractRB.rotation.z * Vector3.forward; // or //Vector forwardPipeVector = pipeTransform.forward; // And finally project2Center = Vector3.Project(forwardPipeVector, forwardPipeVector); float radiusFromCrossectionCenter = project2Center.magnitude; // pipe pull force = distance from pipe center to power 2 Vector3 pipeGravityPull = project2Center.normalized * Mathf.Pow ( (radiusFromCrossectionCenter * 1 ), 2 ) ; playerRB.AddForce ( pipeGravityPull ) ; } } private void OnCollisionExit(Collision collision) { Debug.Log("Gravity is 1 again."); //player.gameObject.GetComponent<Rigidbody>().useGravity = true; gravity = 1; playerRB.isKinematic = false; } void gravityAttract(Collider colliderObject) { var rb = colliderObject.GetComponent<Rigidbody>(); rb.AddForce(Vector3.down * 30, ForceMode.Force); rb.AddForce(Vector3.up * 30, ForceMode.Force); } }
Physics.gravity is not an int value? Or are you saying just turn off gravity altogether from all objects? I've tried turning gravity off on the player but it doesn't seem too helpful. Think it would help if you saw other files too?
is float. But the point is, if you 0 that, then you would be sure, not the normal gravity is pulling down. If still failing down, means something else is acting on object. And yes, switching gravity in the game object does switches it off/on. Is just to check/test.
So I just figured out part of the problem, it seems that I need to alter my PlayerMovement script so that it moves along the pipe wall when the collision is detected. But I don't know how my player will detect that! Here's my player collision script: Code (CSharp): using UnityEngine; public class PlayerCollison : MonoBehaviour { public PlayerMovement movement; void OnCollisionEnter(Collision collisionInfo) { if (collisionInfo.collider.tag == "Obstacle") { Debug.Log("We hit a freaking obstacle."); Debug.Log("Player has collided with: " + collisionInfo.collider.name); movement.enabled = false; FindObjectOfType<GameManagement>().EndGame(); } else { Debug.Log("Player has collided with: " + collisionInfo.collider.name); } } } It seems it only detects the objects with the "Obstacle" tag, even though my else block is OUTSIDE that check. Code (CSharp): using System; using UnityEngine; public class PlayerMovement : MonoBehaviour { public Rigidbody rb; public float forwardForce = 2000f; public float sidewaysForce = 500f; public Boolean fauxGravity = false; // Use this for initialization void Start () { } // Update is called once per frame use fixed update for Unity Fizzix void FixedUpdate () { //add forward force rb.AddForce(0, 0, forwardForce * Time.deltaTime); if (Input.GetKey(KeyCode.RightArrow) && !fauxGravity) { rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange); } if (Input.GetKey(KeyCode.LeftArrow) && !fauxGravity) { rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange); } if (rb.position.y <-1f) { FindObjectOfType<GameManagement>().EndGame(); } } //void OnCollisionEnter(Collision collision) //{ // //collision.gameObject.GetComponent<Rigidbody>().transform.up = Vector3.zero; // //player.gameObject.GetComponent<Rigidbody>().useGravity = false; // System.Console.WriteLine("Player has collided with: " + collision.collider.name); // if(collision.gameObject.name == "PipeBasic 1") // { // System.Console.WriteLine("Player Collided with Pipe"); // fauxGravity = true; // } // //playerRB.isKinematic = true; // //player.gameObject.GetComponent<Rigidbody>().AddRelativeForce() //} } Above is my PlayerMovement script. I like to think I can change the gravity flag in either of those scripts so that player movement is confined to the pipe walls... can my pipe be marked kinematic for this to work???
Yes, shouldn't be a problem. As long you have working collision detection, to trigger gravity. Can you put another debug log, just outside, or after if else loop? Just to see, if collisionInfo.collider.name is detected for else condition. My thought is, maybe OnCollisionEnter is not triggered, when tag is different than Obstacle?
Hey @Antypodish, can't say that will help. But maybe I can email you my project so you can see what I have and what I need to change?
Sorry, but I got already two project opened at once, all the time. So they keep me occupied by much You can always strip project (make copy) to leave just asset folder, Then simply zip it, or so. And attach it here, as just small file, if suitable. Try different collision detection. Just do some basics test. Like different tags. Or names, or objects. Maybe you missed something.
OK, so I made SOME kind of progress - but the trouble is updating the player's normal... seems that when I try to normalize the force affecting the player, the player just slows down and then freezes in place. Code (CSharp): private void FixedUpdate() { if (gravity == 0) { //Debug.Log("Gravity is 0."); //playerRB.AddForce(-10 * playerRB.mass * myNormal); vectorFromPipeCenter = attractRB.position - playerRB.position; vectorFromPipeCenter.Normalize(); Debug.Log("Player distrance from pipe center: " + vectorFromPipeCenter); //vectorFromPipeCenter = attractRB.position - playerRB.position; forwardPipeVector = attractRB.rotation.z * Vector3.forward; Debug.Log("Player forward vector? " + forwardPipeVector); // or //Vector forwardPipeVector = pipeTransform.forward; // And finally project2Center = Vector3.Project(vectorFromPipeCenter, playerRB.angularVelocity); float radiusFromCrossectionCenter = project2Center.magnitude; // pipe pull force = distance from pipe center to power 2 pipeGravityPull = project2Center.normalized * Mathf.Pow ( (radiusFromCrossectionCenter * 1 ), 2 ) ; playerRB.useGravity = false; Debug.Log("Adding force from FG"); playerRB.AddForce (pipeGravityPull.x, pipeGravityPull.y, 0) ; } if (gravity == 1) { //playerRB.useGravity = true; } }
vectorFromPipeCenter.Normalize() is more like direction rather distance. (just for info) The actual distance (see line 10 and 18), if you actually need it, is vectorFromPipeCenter.magnitude Just for extra note, try not over use this method, calling 100s times per frame, as it uses sqrt. In line 17 you have Code (CSharp): project2Center = Vector3.Project(vectorFromPipeCenter, playerRB.angularVelocity); with Code (CSharp): playerRB.angularVelocity Is this what you suppose to have? Are you sure is this right?
Hi @Antypodish , So, in light of what you said, what would you suggest with my player movement script? It seems I have to make my player movement script work in tandem with that method I provided earlier from my FauxGravity script. Code (CSharp): void FixedUpdate () { distanceFromPipeCenter.Normalize(); //add forward force rb.AddForce(0, 0, forwardForce * Time.deltaTime); if (Input.GetKey(KeyCode.RightArrow) && !fauxGravity) { rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange); } if (Input.GetKey(KeyCode.LeftArrow) && !fauxGravity) { rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange); } if (Input.GetKey(KeyCode.RightArrow) && fauxGravity) { //Debug.Log("Right pressed"); rb.AddForce(sidewaysForce * pipePull.x*Time.deltaTime, sidewaysForce * pipePull.y * Time.deltaTime, 0, ForceMode.VelocityChange); Debug.Log(rb.angularVelocity); rb.rotation = Quaternion.FromToRotation(transform.up, distanceFromPipeCenter) * transform.rotation; } if (Input.GetKey(KeyCode.RightArrow) && fauxGravity) { //Debug.Log("Left pressed"); rb.AddForce(-sidewaysForce * pipePull.x * Time.deltaTime, sidewaysForce * pipePull.y * Time.deltaTime, 0, ForceMode.VelocityChange); Debug.Log(rb.angularVelocity); float headingDeltaAngle = Input.GetAxis("Horizontal") * Time.deltaTime * sidewaysForce; Quaternion headingDelta = Quaternion.AngleAxis(headingDeltaAngle, transform.up); //align with surface normal transform.rotation = Quaternion.FromToRotation(transform.up, distanceFromPipeCenter) * transform.rotation; //apply heading rotation transform.rotation = headingDelta * transform.rotation; } if (rb.position.y <-1f) { FindObjectOfType<GameManagement>().EndGame(); } }
Are these two separate scripts, running in game? Or you have replaced the previous one with the current, what you have just shown.? Just curious. Can you explain, what made you think, using playerRB.angularVelocity in first place?
Hi there, These are two separate scripts. One controls the movement of the player. The other was the one we tried to work on together, which applied the false gravity to the surface normal. angularVelocity was what I thought could be used to translate the rotation of the player, but that could me understanding Unity physics incorrectly, and especially physics in general.
Hi @Antypodish ! So, I worked through this with another dev friend of mine a couple of nights ago. We figured out that your algorithm was definitely right - the problem is that when my player moves left or right, it is ONLY moving along the horizontal axis. That being said, I've run into ANOTHER issue too - taking note of the forward vector of my pipe model ALWAYS returns zero. I've already revised the algorithm to not only follow what you had written, but include ADDITIONAL logic so that activation of the false gravity doesn't depend on whether the cube collides with the pipe wall, but rather is inside the collidor itself, if that makes sense. Can you take a look at the two scripts below and let me know what you suggest? Player movement script: Code (CSharp): using System; using UnityEngine; public class PlayerMovement : MonoBehaviour { public Rigidbody rb; public float forwardForce = 2000f; public float sidewaysForce = 500f; public Boolean fauxGravity = false; public Vector3 distanceFromPipeCenter = new Vector3(0, 0, 0); public Vector3 pipePull = new Vector3(0,0,0); // Use this for initialization void Start () { } // Update is called once per frame use fixed update for Unity Fizzix void FixedUpdate () { distanceFromPipeCenter.Normalize(); //add forward force rb.AddForce(0, 0, forwardForce * Time.deltaTime); if (Input.GetKey(KeyCode.RightArrow) && !fauxGravity) { rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange); } if (Input.GetKey(KeyCode.LeftArrow) && !fauxGravity) { rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange); } if (Input.GetKey(KeyCode.RightArrow) && fauxGravity) { //Debug.Log("Right pressed"); rb.AddForce(sidewaysForce * -pipePull.x * Time.deltaTime, sidewaysForce * pipePull.y * Time.deltaTime, 0, ForceMode.VelocityChange); Debug.Log(rb.angularVelocity); //float headingDeltaAngle = Input.GetAxis("Horizontal") * Time.deltaTime * sidewaysForce; //Quaternion headingDelta = Quaternion.AngleAxis(headingDeltaAngle, transform.up); //align with surface normal //transform.rotation = Quaternion.FromToRotation(transform.up, distanceFromPipeCenter) * transform.rotation; //apply heading rotation //transform.rotation = headingDelta * transform.rotation; } if (Input.GetKey(KeyCode.LeftArrow) && fauxGravity) { //Debug.Log("Left pressed"); rb.AddForce(-sidewaysForce * -pipePull.x * Time.deltaTime, sidewaysForce * pipePull.y * Time.deltaTime, 0, ForceMode.VelocityChange); Debug.Log(rb.angularVelocity); //float headingDeltaAngle = Input.GetAxis("Horizontal") * Time.deltaTime * sidewaysForce; //Quaternion headingDelta = Quaternion.AngleAxis(headingDeltaAngle, transform.up); //align with surface normal //transform.rotation = Quaternion.FromToRotation(transform.up, distanceFromPipeCenter) * transform.rotation; //apply heading rotation //transform.rotation = headingDelta * transform.rotation; } //if (fauxGravity) //{ // rb.useGravity = false; // float distForward = Mathf.Infinity; // RaycastHit hitForward; // if (Physics.SphereCast(transform.position, 0.25f, -transform.up + transform.forward, out hitForward, 5)) // { // distForward = hitForward.distance; // } // float distDown = Mathf.Infinity; // RaycastHit hitDown; // if (Physics.SphereCast(transform.position, 0.25f, -transform.up, out hitDown, 5)) // { // distDown = hitDown.distance; // } // float distBack = Mathf.Infinity; // RaycastHit hitBack; // if (Physics.SphereCast(transform.position, 0.25f, -transform.up + -transform.forward, out hitBack, 5)) // { // distBack = hitBack.distance; // } // if (distForward < distDown && distForward < distBack) // { // transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(Vector3.Cross(transform.right, hitForward.normal), hitForward.normal), Time.deltaTime * 5.0f); // } // else if (distDown < distForward && distDown < distBack) // { // transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(Vector3.Cross(transform.right, hitDown.normal), hitDown.normal), Time.deltaTime * 5.0f); // } // else if (distBack < distForward && distBack < distDown) // { // transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(Vector3.Cross(transform.right, hitBack.normal), hitBack.normal), Time.deltaTime * 5.0f); // } // GetComponent<Rigidbody>().AddForce(-transform.up * Time.deltaTime * 10); //} if (rb.position.y <-1f) { FindObjectOfType<GameManagement>().EndGame(); } } //void OnCollisionEnter(Collision collision) //{ // //collision.gameObject.GetComponent<Rigidbody>().transform.up = Vector3.zero; // //player.gameObject.GetComponent<Rigidbody>().useGravity = false; // System.Console.WriteLine("Player has collided with: " + collision.collider.name); // if(collision.gameObject.name == "PipeBasic 1") // { // System.Console.WriteLine("Player Collided with Pipe"); // fauxGravity = true; // } // //playerRB.isKinematic = true; // //player.gameObject.GetComponent<Rigidbody>().AddRelativeForce() //} } FauxGravity script: Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; public class FauxGravity : MonoBehaviour { public Transform attractor; public Transform player; public Transform collider; Rigidbody attractRB; Rigidbody playerRB; Vector3 myNormal; public Vector3 vectorFromPipeCenter; public Vector3 forwardPipeVector; Vector3 project2Center; public Vector3 pipeGravityPull; int gravity = 1; // Use this for initialization void Start () { attractRB = attractor.GetComponent<Rigidbody>(); playerRB = player.GetComponent<Rigidbody>(); //Physics.gravity.magnitude = 0; } // Update is called once per frame void Update () { } private void OnCollisionEnter(Collision collision) { //collision.gameObject.GetComponent<Rigidbody>().transform.up = Vector3.zero; //player.gameObject.GetComponent<Rigidbody>().useGravity = false; myNormal = playerRB.transform.up; //playerRB = collision.gameObject.GetComponent<Rigidbody>(); gravity = 0; //playerRB.isKinematic = true; //player.gameObject.GetComponent<Rigidbody>().AddRelativeForce() } private void FixedUpdate() { if (gravity == 0) { //Debug.Log("Gravity is 0."); //playerRB.AddForce(-10 * playerRB.mass * myNormal); vectorFromPipeCenter = playerRB.position - attractRB.position; //vectorFromPipeCenter.Normalize(); Debug.Log("Player distrance from pipe center: " + vectorFromPipeCenter.magnitude); //vectorFromPipeCenter = attractRB.position - playerRB.position; Debug.Log("attractRB forward is " + playerRB.rotation.z); forwardPipeVector = player.forward.magnitude * Vector3.forward; Debug.Log("Player forward vector? " + forwardPipeVector); // or //Vector forwardPipeVector = pipeTransform.forward; // And finally project2Center = Vector3.Project(forwardPipeVector, vectorFromPipeCenter); float radiusFromCrossectionCenter = project2Center.magnitude; Debug.Log("Normal is: " + Quaternion.AngleAxis(90, forwardPipeVector)); // pipe pull force = distance from pipe center to power 2 pipeGravityPull = Quaternion.AngleAxis(90, forwardPipeVector) * project2Center.normalized * Mathf.Pow ( (radiusFromCrossectionCenter * 1 ), 2 ); Debug.Log("Pipe gravity vector? " + pipeGravityPull); playerRB.useGravity = true; Debug.DrawLine(pipeGravityPull, pipeGravityPull); Debug.Log("Adding force from FG"); playerRB.AddForce(pipeGravityPull); } if (gravity == 1) { //playerRB.useGravity = true; } } private void OnCollisionExit(Collision collision) { //Debug.Log("Gravity is 1 again."); //player.gameObject.GetComponent<Rigidbody>().useGravity = true; gravity = 1; //playerRB.useGravity = true; playerRB.isKinematic = false; //playerRB.AddForce(10, 20, 0); } void gravityAttract(Collider colliderObject) { var rb = colliderObject.GetComponent<Rigidbody>(); rb.AddForce(Vector3.down * 30, ForceMode.Force); rb.AddForce(Vector3.up * 30, ForceMode.Force); } } I more than appreciate the help you've provided so far!
Briefly looking at, looks ok. I mean, if it works with further improvements that cool to hear. I presume, you are done on that part for now? Now you should play with it for some time. and when you sure all works, clean up the scrips. You can always keep draft version copies somewhere. Ideally would be, if you at some point adapt classes FauxGravity and PlayerMovement to be without MonoBehaviour. But don't worry abut it for now. If you don't have many active scripts all over the place, that should be fine. Btw, if you ever use KeyUp or KeyDown, means pressed and released, then keep in mind, to put them in update, rather than FixedUpdate. Otherwise, you may miss key evenets. Good luck.