Collisions on an orbiting object.

Hello,

I have an object orbiting around a sphere. You can rotate the object to travel around the sphere. However i would like it to collide with walls/obstructions/enemies. I tried using transform.Rotate and Translate to get what i want and that works fine except that it ignores the walls.

How can i keep it from passing through them?

I’ve also tried adding a character controller and a rigidbody but i have to explicitly keep it from shooting into orbit upon collision. I’d like to clean up my code.

This is what i currently use:

override public void FixedUpdate ()
{
	//To ensure that we are still in the water and not sailing off into space
	if(!Physics.Raycast(transform.position,-transform.up, 1.5f)) 
	{ 
    	faux += transform.position.normalized * -2 *Time.deltaTime; 
    	GetComponent<CharacterController>().Move(faux); 
	} 
	
	//Rotate our ship
	if(Input.GetAxis("Horizontal") != 0)
		transform.Rotate(0, Input.GetAxis("Horizontal") * rotateSpeed, 0); 
	//Apply Rotation based on our angle from Vector3.Zero
	//use character Rotate
	Quaternion QuaternionRotation = Quaternion.FromToRotation (transform.up, (transform.position - Vector3.zero).normalized); 
	transform.rotation = QuaternionRotation * transform.rotation;
	//Move ship forward
	Vector3 moveDirection = new Vector3(0, 0, 1); 
	moveDirection = transform.TransformDirection(moveDirection); 
	moveDirection *= speed; 
		
	GetComponent<CharacterController>().Move((moveDirection) * Time.deltaTime);
}

By directly rotating and translating you overrule the physics engine. If you want to keep doing that, you could try to detect collisions and decide not to move whenever it’s colliding with something. Alternatively, apply forces and velocities to the object’s rigidbody to get it to move in the direction you want and let the physics engine do its thing.

Can you give a little more detail about the setup?
How can the object be orbiting by rotating it? Is the pivot not at the center of the geometry?
What should happen when a collision occurs?

@Jasper, Ideally i just want to use the rigidbody to deal with collisions. It works with the script i pasted above but it isn’t ideal.

@Rafes, I have a ship that moves around a sphere so to speak. Pivot is at the center, which just so happens to exist at 0,0,0. You can rotate the ship to go in another direction along the suface of the sphere. Although it doesn’t directly interact with the sphere’s surface. When collision occurs i just need to ship to either stop moving or go around it (capsule collider). When it comes to other enemies, i’m assuming it comes down to the mass and either you get pushed or the enemy get’s pushed.

OK, try to set up a little hierarchy like this…

  • Parent GameObject at the center of the planet
    ---- + GameObject at the planets surface
    ---- ---- + Your ship with a rigidbody[/CODE]

Now the trick will be to get the ship to follow its parent unless it is acted upon by a force, then when the force is weaker or gone, it should go back to its parent, which is the same as transform.localPostion = Vector3.zero.

I’m leaving gaps in here but it is more of an idea of an approach than a solution anyway.

Well the code that i posted works fine, it’s just that the colliders push the rigidbody up and down when the ship moves against them

need to correct height in code manually after collisions. it should still be stable to do that as its just one axis.

That’s what i’m doing now but i was wondering if perhaps i was doing it wrong. That there was a way to keep the rigidbodies from behaving that way.

if(!Physics.Raycast(transform.position,-transform.up, 1.5f)) 
	{ 
    	faux += transform.position.normalized * -2 *Time.deltaTime; 
    	GetComponent<CharacterController>().Move(faux); 
	}

I don’t think you want a character controller or to move the transform directly. With physics you should move the rigid body as the docs state.

I just read up on it and i see what you mean. However, i tried changing the code to affect the rigidbody with the MovePosition() and MoveRotation() but i’m not sure how to apply it correctly as to get it to do what i need. I modified my code but the rotation is off and my ship slowly ascends into the heavens :stuck_out_tongue:

override public void FixedUpdate ()
{
	//To ensure that we are still in the water and not sailing off into space
	if(!Physics.Raycast(transform.position,-transform.up, 1.5f)) 
	{ 
    	faux += transform.position.normalized * -2 *Time.deltaTime; 
    	rigidbody.MovePosition(faux); 
	} 
	
	//Rotate our ship
	if(Input.GetAxis("Horizontal") != 0)
		transform.Rotate(0, Input.GetAxis("Horizontal") * rotateSpeed, 0); 
	//Apply Rotation based on our angle from Vector3.Zero
	//use character Rotate
	Quaternion QuaternionRotation = Quaternion.FromToRotation (transform.up, (transform.position - Vector3.zero).normalized); 
    rigidbody.MoveRotation(rigidbody.rotation * QuaternionRotation);

		
	rigidbody.MovePosition(rigidbody.position + new Vector3(0,0,3) * Time.deltaTime);
}

Do you have gravity off?

Have you tried really stripping this back and adding one thing at a time. There seems to be a lot of clutter here. Here are some random and, I hope, helpful questions…

These are pretty much the same thing…
transform.position.normalized
transform.position - Vector3.zero ← subtracting 0 does nothing right?

An object’s position is a vector from World 0 to the object, so normalizing the position will get you vector which points from world 0 to the object but is only 1 unit long. Is this what you want? I’m not sure you need to normalize at all though. A direction is a direction. magnitude doesn’t matter.

Are you casting down? Won’t this hit anything? I don’t see a layer mask or any other testing of what is hit. What is the mechanic here?
if(!Physics.Raycast(transform.position,-transform.up, 1.5f))Is the following moving the current position along world Z at 3 times the frame’s deltaTime? Or is MovePosition changing that to a local direction?

    rigidbody.MovePosition(rigidbody.position + new Vector3(0,0,3) * Time.deltaTime);