Need help with hover script

Hi guys!

I’m developing a game called Jetpack Race and this is the official fan page:

Here is a development build:

https://googledrive.com/host/0ByQU1sFLNlqnbVlkWmo1QzF4MUU/jprpublish.html

I can’t make the hover function to work properly. I have a gameobject, with a rigidbody, charactercontroller, thirdpersoncamera, etc. All stuff seems to be very easy to fix but the damn hover script is not working! Here is the code I’m using:

void ApplyHover ()
		{
				if (hover) {
						RaycastHit hit;
						Debug.Log ("HoverDistance: " + hoverDistance);
						if (Physics.Raycast (transform.position, Vector3.down, out hit, hoverDistance)) {
				
								Debug.Log ("Aplicando força pra cima...");
								ScreenPrinter.Print (string.Format ("Raycast Hit: {0}", hit.point.y));


								rigidbody.AddForce ((Vector3.up + new Vector3 (0, hoverDistance, 0)) * hoverForce);
								if (hit.point.y != Vector3.zero.y) {
										Debug.DrawLine (transform.position, hit.point, Color.blue);
								}
					
								rigidbody.drag = 100.0f;
						} else {
								Debug.Log ("Aplicando força pra baixo...");
								rigidbody.AddForce ((Vector3.down + new Vector3 (0, Random.value, 0)) * hoverForce);
								rigidbody.drag = 1.0f;
					
						}
					
						Debug.Log ("Distance: " + hit.distance);
				}

		}

I don’t know why the character cant fall on depressions and hover fixed X meters above the collision below. Seems that this AddForce method is doing nothing! If i force transform.position = ANYTHING works. But all hover tutorials says to use this damn AddForce.

What I’m doing wrong?

It doesn’t seem like you’re using the distance from the ground at all here, you will want to use the RaycastHit.point and objects position to get the distance:

float d = Vector3.Distance(transform.position, hit.point);
or
float d = transform.position.y - hit.point.y;

rigidbody.AddForce ((Vector3.up + new Vector3 (0, d, 0)) * hoverForce);

Your hoverDistance variable is just the distance for the Raycast to travel

Oh and your link to the build doesn’t work, you can’t just give us a directory on your hard drive :stuck_out_tongue:

Sorry, didn’t notice I’ve copied the wrong URL. Here is the correct one: https://googledrive.com/host/0ByQU1sFLNlqnbVlkWmo1QzF4MUU/jprpublish.html

I’ll try that code and inform if it works, thank you very much.

Somehow, the code does not work either. This AddForce never works. If i force transform.position = someotherposition works, but adding force makes no effect. Any ideas why?

I think your high drag values may have been part of the problem, but I don’t know exactly what it is. I went and tried making a rigidbody hover, I had some trouble preventing it from ‘bouncing’ into the sky but I think I’ve got it figured out. I took the raycast’s hit position and used that to determine the target Y position, then took the players Y vs target Y to get the distance to multiply the force by. Since you should to be able to dip below the target height you have to limit the distance variable, otherwise you’ll fire off into the sky if you drop too low as the value will get really high. You could add a downwards force when you’re above it to counteract that but this should at least get you on the right track. It’ll work if you just throw this script on a cube, but you’ll want to change the drag and force limits, I just picked random values that show it works.

using UnityEngine;
using System.Collections;

public class hover_script : MonoBehaviour {
	public float hover_height = 5.0f;
	public float max_force = 0.75f;
	
	void FixedUpdate () {
		RaycastHit hit;
		if(Physics.Raycast(transform.position, Vector3.down, out hit, hover_height)){
			float th = hit.point.y + hover_height;
			float dtt = (transform.position.y < th)? th - transform.position.y : 0.0f;
			dtt = Mathf.Min(dtt, max_force);
			if(transform.position.y < th){
				rigidbody.drag = 1.0f;
				rigidbody.AddForce(Vector3.up * dtt, ForceMode.VelocityChange);
			}
		}
		else{
			rigidbody.drag = 0.2f;	
		}
	}
}

I’ve found something. If I remove the Character Controller, the player falls and don’t collide with the mesh collider of the terrain.

Maybe charactercontroller is causing the hover script to not work. Any toughts on this?

Maybe CharacterController has issues with Rigidbody, dunno yet. Any Unity Guru to help me on this?

Yeah, I don’t think you’re supposed to use a character controller with a rigidbody, it’s meant as a replacement so you don’t have to use physics with varying friction/bounciness/etc. for your character. You might as well just use a rigidbody and capsule collider with the rotation locked, though you can probably achieve the same with the character controller using the Move function.

Sorry that I’m not sure what the exact topic at hand is, but I can affirm that the character controller is not meant to be used with rigidbody; it’s a substitution for moving/interacting with a character WITHOUT forces.

maybe start with something like this:

http://wiki.unity3d.com/index.php/ShipControls

and modify it to your specific needs

Somehow, this script works nicely:

void ApplyHover ()
	{
		if (hover) {
			RaycastHit hit;

			if(Physics.Raycast(transform.position,Vector3.down, out hit))
			{
				hitTransform = hit.transform;
				currentHeight = hit.distance + Mathf.Sin(hit.distance);

				var up= currentHeight < (hoverDistance - Time.deltaTime) || transform.position.y < 0;
				if (up)
				{
					forceMultiplier = (hoverDistance - currentHeight) / hoverDistance;
					forceApplied = (Vector3.up * force * forceMultiplier) + (Vector3.up * 9.8f);

					rigidbody.AddForceAtPosition(forceApplied, transform.position);

					Debug.DrawRay (transform.position, transform.TransformDirection (Vector3.down) * hit.distance, Color.red);
				} else {
					
					if ((currentHeight - hoverDistance - Time.deltaTime) < (hoverDistance / 2))
					{
						forceApplied = (Vector3.up * 9.8f) * ((hoverDistance - (currentHeight - hoverDistance)) / hoverDistance);
						rigidbody.AddForceAtPosition(forceApplied,transform.position);
					}
					
					Debug.DrawRay (transform.position, transform.TransformDirection (Vector3.down) * hit.distance, Color.green);
				}
			}
		}
	}

But I don’t know why my raycast is being cast from the cube face instead of its center of mass. Any ideas why?

UPDATE
Found it. Nevermind. I was positioning the cube 1 unit in Z inside the player object. Sorry.

OK, now I see the difference between them. Thank you very much, MDragon and Josh707!

No problem, glad you got it figured out!

I think I’ve got the hovering script up and running. It needs some tweeks but seems promising.

Here is an update:

I’m not happy with the rotating/turning system, but I’ll figure out.

Thank you guys!