Changing Gravity in Game for Character Controller

Hey friends,

I’m working on a mini game for my senior projects at school. In the mini game, one player controls the gravitational force where the other player controls the character and has to navigate a maze. My original script had the character as a rigidbody but the controls were clunky. My classmates thought the concept was really cool but recommended I execute the concept with a character controller instead of a rigidbody.

So, here’s my current scripts. One controls the gravity and is attached to the main camera. The other controls the character. The gravity changes just fine but I can’t control the character when the gravity is changed to the -y, z, and -z axises. Anyone able to help me with this?

public class GravityChange : MonoBehaviour {

	public Vector3 gravity;
	public float gravForce = 9.81f;
	public int gravPull;


	void Start()
	{
		gravity.x = 0;
		gravity.y = gravForce;
		gravity.z = 0;

		gravPull = 1;
	}
	
	void Update()
	{
		if(Input.GetButtonDown("Grav Up")){
			gravity.x = 0;
			gravity.y = gravForce;
			gravity.z = 0;

			gravPull = 0;
		}

		if(Input.GetButtonDown("Grav Down")){
			gravity.x = 0;
			gravity.y = -gravForce;
			gravity.z = 0;

			gravPull = 1;
		}

		if(Input.GetButtonDown("Grav West")){
			gravity.x = -gravForce;
			gravity.y = 0;
			gravity.z = 0;

			gravPull = 2;
		}

		if(Input.GetButtonDown("Grav East")){
			gravity.x = gravForce;
			gravity.y = 0;
			gravity.z = 0;

			gravPull = 3;
		}
	}
}

public class ControllerGravity : MonoBehaviour
{

	public float speed = 6.0F;
	public float jumpSpeed = 8.0F;
	public float gravity = 10.0F;
	public Vector3 gravDirection = Vector3.zero;
	public int gravType = 1;
	private Vector3 moveDirection = Vector3.zero;

	void Update() {
		CharacterController controller = GetComponent<CharacterController>();
		gravDirection = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<GravityChange>().gravity;
		gravType = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<GravityChange>().gravPull;
		gravity = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<GravityChange>().gravForce;

		if (gravType == 0){
			if (controller.isGrounded) {
				moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
				moveDirection = transform.TransformDirection(moveDirection);
				moveDirection *= speed;
				if (Input.GetButton("Jump"))
					moveDirection.y = -jumpSpeed;
			}
			moveDirection -= gravDirection * Time.deltaTime;
			controller.Move(moveDirection * Time.deltaTime);

		}else if (gravType == 1) {
			if (controller.isGrounded) {
				moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
				moveDirection = transform.TransformDirection(moveDirection);
				moveDirection *= speed;
				if (Input.GetButton("Jump"))
					moveDirection.y = jumpSpeed;
			}
			moveDirection -= gravDirection * Time.deltaTime;
			controller.Move(moveDirection * Time.deltaTime);

		}else if (gravType == 2) {
			if (controller.isGrounded) {
				moveDirection = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
				moveDirection = transform.TransformDirection(moveDirection);
				moveDirection *= speed;
				if (Input.GetButton("Jump"))
					moveDirection.z = jumpSpeed;
			}
			moveDirection -= gravDirection * Time.deltaTime;
			controller.Move(moveDirection * Time.deltaTime);
			
		}else {
			if (controller.isGrounded) {
				moveDirection = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
				moveDirection = transform.TransformDirection(moveDirection);
				moveDirection *= speed;
				if (Input.GetButton("Jump"))
					moveDirection.z = -jumpSpeed;
			}
			moveDirection -= gravDirection * Time.deltaTime;
			controller.Move(moveDirection * Time.deltaTime);
		}
	}
}

Here are my original scripts I used with the rigidbody.

public class GravityChange : MonoBehaviour {

	public Vector3 gravity;
	public float gravForce = 9.81f;
	public int gravPull;
void Start()
	{
		gravity = Physics.gravity;

		gravity.x = 0;
		gravity.y = -gravForce;
		gravity.z = 0;
	}

	
	void Update()
	{
		Physics.gravity = gravity;

		//if 'q' is pressed change gravity northward
		if(Input.GetButtonDown("Grav North")){
			gravity.x = 0;
			gravity.y = 0;
			gravity.z = gravForce;
		}

		//if 'w' is pressed change gravity upward
		if(Input.GetButtonDown("Grav Up")){
			gravity.x = 0;
			gravity.y = gravForce;
			gravity.z = 0;
		}

		//if 'e' is pressed change gravity eastward
		if(Input.GetButtonDown("Grav East")){
			gravity.x = gravForce;
			gravity.y = 0;
			gravity.z = 0;
		}

		//if 'a' is pressed change gravity westward
		if(Input.GetButtonDown("Grav West")){
			gravity.x = -gravForce;
			gravity.y = 0;
			gravity.z = 0;
		}

		//if 's' is pressed change gravity downward
		if(Input.GetButtonDown("Grav Down")){
			gravity.x = 0;
			gravity.y = -gravForce;
			gravity.z = 0;
		}

		//if 'd' is pressed change gravity southward
		if(Input.GetButtonDown("Grav South")){
			gravity.x = 0;
			gravity.y = 0;
			gravity.z = -gravForce;
		}
	}
	
}

This script was attached to the rigidbody:

public class CharacterMove : MonoBehaviour {
	public float speed = 2.0f;
	public Vector3 jumpHeight;
	public float jumpSpeed = -0.3f;
	private bool grounded = false;

	void FixedUpdate () {
		float moveHoriz = Input.GetAxis ("Horizontal");
		float moveVert = Input.GetAxis ("Vertical");

		if (Physics.gravity.x != 0) {
			Vector3 moveForward = new Vector3 (0, moveVert, 0);
			Vector3 turnSide = new Vector3 (0, 0, -moveHoriz);

			rigidbody.MovePosition (rigidbody.position + moveForward * Time.deltaTime * speed);
			rigidbody.MovePosition (rigidbody.position + turnSide * Time.deltaTime * speed);
		}
		if (Physics.gravity.z != 0) {
			Vector3 moveForward = new Vector3 (moveVert, 0, 0);
			Vector3 turnSide = new Vector3 (0, -moveHoriz, 0);

			rigidbody.MovePosition (rigidbody.position + moveForward * Time.deltaTime * speed);
			rigidbody.MovePosition (rigidbody.position + turnSide * Time.deltaTime * speed);
		}
		else {
			Vector3 moveForward = new Vector3 (moveVert, 0, 0);
			Vector3 turnSide = new Vector3 (0, 0, -moveHoriz);

			rigidbody.MovePosition (rigidbody.position + moveForward * Time.deltaTime * speed);
			rigidbody.MovePosition (rigidbody.position + turnSide * Time.deltaTime * speed);
		}



		if (grounded) {
			if (Input.GetButton ("Jump")) {
				jumpHeight = Physics.gravity * jumpSpeed;

				rigidbody.AddForce (jumpHeight, ForceMode.Impulse);
			}
		}
	}

	void OnCollisionStay (){
		grounded = true;
	}

	void OnCollisionExit () {
		grounded = false;
	}
}

To be honest you’re better off making your own controller. The Unity one SUCKS, it’s so overly complicated for what it is, I can do just as much as the Character Controller with like 45 lines of code. And check this, it’s easy to read and organize! lol.

But there’s nothing wrong with using a Rigidbody, you just gotta know how to deal with them, I’ve spent 3 weeks getting Rigidbody controls to work just the way I wanted them, it’s HARD, but once you figure out the key to getting the rigidbody to work is just plainly a lot of tweaking, that’s it.

But you should be able to walk, but again, that might be because ur using Unities crappy controller as well lol.

Just do a TEST, put in your Update function

if(Input.GetKey(KeyCode.W)){
transform.Translate(Vector3.forward * YourSpeed * Time.deltaTime);

}

Just to see if you can walk forward that way, if you cant, it’s your gravity script.