Hovering Tank

I have a sci-fi themed tank that I need to make it look like it’s hovering up and down through C# script. How do I go about applying force to the rigidbody giving it the impression that it’s hovering up and letting gravity bring it back down again all without increasing or editing the collider box? Where do I start?

EDIT

So I was playing around with the code I gave in the link below to see if it was an all in one solution and I think my freak of nature gravity value (-500) is affecting the code badly and my craft still sticks to the ground does anyone have a clue?

Converted Code:

using UnityEngine;

using System.Collections;

public class ScifiHover : MonoBehaviour
{
float forwardPower;

float steerPower;

float landingPower;

float jumpingPower;

float hoverHeight;

float stability = 1;

public GameObject body;

public float speedUpdate;

private Vector3[] hitNormal = new Vector3[5];

private Quaternion rotation;

private float increment;

private Vector3[] lastNormals = new Vector3[5];

private bool physicsSetup = false;

private Vector3 boxDim;

private Vector3[] cornersPoint = new Vector3[5];

private Transform[] corners = new Transform[5];

private BoxCollider boxCollider;

private float yBounce;

private Vector3 lastPosition;

private float distance;

private Vector3 average;

void Awake()
{

    InitializePhysics();
}

void Update()
{

    CalculateSpeed();

}

void FixedUpdate()
{

    if (physicsSetup)
    {

        RaycastHit hit;

        for (int i = 0; i <= corners.Length - 1; i++)
        {

            if (Physics.Raycast(corners_.position, -corners*.up, out hit, hoverHeight + 100.0f))*_

{
if (hit.collider.gameObject.tag == “Floor”)
{
hitNormal = body.transform.InverseTransformDirection(hit.normal);
if (lastNormals != hitNormal*)*
{
increment = 0;
lastNormals = hitNormal*;*
}
distance = hit.distance;
if (hit.distance < hoverHeight)
{
constantForce.relativeForce = (-average + transform.up) * rigidbody.mass * jumpingPower * rigidbody.drag * Mathf.Min(hoverHeight, hoverHeight / distance);
}
else
{
constantForce.relativeForce = -(transform.up) * rigidbody.mass * landingPower * rigidbody.drag / Mathf.Min(hoverHeight, hoverHeight / distance);
}
}
}
}
average = -(hitNormal[0] + hitNormal[1] + hitNormal[2] + hitNormal[3] + hitNormal[4]) / 2;
if (increment != 1) { increment += 0.03f; }
rotation = Quaternion.Slerp(body.transform.localRotation, Quaternion.Euler(average * Mathf.Rad2Deg), increment);
Quaternion temp = rotation;
temp.y = transform.up.y * Mathf.Deg2Rad;
body.transform.localRotation = temp;
float fwdForce = Input.GetAxis(“Vertical”) * forwardPower;
rigidbody.AddForce(transform.forward * fwdForce);
float steerForce = Input.GetAxis(“Horizontal”) * steerPower;
rigidbody.AddTorque(transform.up * steerForce);
}
}
void CalculateSpeed()
{
if (lastPosition != transform.position)
{
float distance = Vector3.Distance(transform.position, lastPosition);
speedUpdate = (distance / 1000) / (Time.deltaTime / 3600); //Km/h
}
}
void InitializePhysics()
{
//Store the box dimenssion of the hovering object.
boxCollider = body.AddComponent();
boxDim = new Vector3(boxCollider.size.x * body.transform.localScale.x, boxCollider.size.y * body.transform.localScale.y, boxCollider.size.z * body.transform.localScale.z) * stability;
cornersPoint[0] = new Vector3(transform.position.x - boxDim.x / 2, transform.position.y - boxDim.y / 2, transform.position.z + boxDim.z / 2);
cornersPoint[1] = new Vector3(boxDim.x / 2 + transform.position.x, transform.position.y - boxDim.y / 2, transform.position.z + boxDim.z / 2);
cornersPoint[2] = new Vector3(boxDim.x / 2 + transform.position.x, transform.position.y - boxDim.y / 2, transform.position.z - boxDim.z / 2);
cornersPoint[3] = new Vector3(transform.position.x - boxDim.x / 2, transform.position.y - boxDim.y / 2, transform.position.z - boxDim.z / 2);
cornersPoint[4] = transform.position;
Destroy(boxCollider);
for (int i = 0; i <= cornersPoint.Length - 1; i++)
{
GameObject stablePlatform = GameObject.CreatePrimitive(PrimitiveType.Sphere);
stablePlatform.name = “StablePlatform” + “(” + i + “)”;
stablePlatform.transform.parent = body.transform;
stablePlatform.transform.localPosition = transform.InverseTransformPoint(cornersPoint*);*
corners = stablePlatform.transform;
Destroy(stablePlatform.GetComponent());
Destroy(stablePlatform.GetComponent());
}
cornersPoint = null;
physicsSetup = true;
}
}

As asafsitner mentioned, it’s best to do it via animation, as it allows you to add unsteady hovering which also depends on the current state of the tank (i.e. moving, shooting, standing, searching).

You can always use Mathf.Cos or Mathf.Sin, as they will produce a periodical value which ranges from -1 to 1.

alt text

Here’s a part of my Hoverboard script.

What it does is check the distance down to the ground; if it is less than the specified height, it applies upward force at a percentage of the force needed to lift it up. The - Time.deltaTime is actually just a small number that is used to make sure the hoverForceMultiplier doesn’t go above 1.

I have a Rigidbody of Mass 1, Use Gravity is Enabled (ticked).

EDIT - here’s the C# version :

using UnityEngine;
using System.Collections;

public class HoverScript : MonoBehaviour 
{
	public float hoverDistance = 0.75f;
	public float hoverForce = 10.0f;
	private float currentHeight = 0.0f;
	private float hoverForceMultiplier = 0.0f;
	private Vector3 hoverForceApplied = Vector3.zero;
	
	void FixedUpdate() 
	{
	    // -- find hover distance and add force to make hover   
	    RaycastHit rayHit;
	    if (Physics.Raycast(transform.position, Vector3.down, out rayHit))
	    {
	       currentHeight = rayHit.distance;
	       if (currentHeight < (hoverDistance - Time.deltaTime))
	       {
	         // find percentage of currentHeight below hoverDistance
	         hoverForceMultiplier = (hoverDistance - currentHeight) / hoverDistance;
	         hoverForceApplied = (Vector3.up * hoverForce * hoverForceMultiplier) + (Vector3.up * 9.8f);
	         rigidbody.AddForce(hoverForceApplied);         
	       } else {       
	         // apply anti-gravity force for half distance above hoverDistance
	         if ((currentHeight - hoverDistance - Time.deltaTime) < (hoverDistance / 2))
	         {
	          hoverForceApplied = (Vector3.up * 9.8f) * ((hoverDistance - (currentHeight - hoverDistance)) / hoverDistance);
	          rigidbody.AddForce(hoverForceApplied);
	         }
	       }
	    }
	}
}

Original Post :

It’s in JS and right now I have no time to convert and check it. I shall make a C# vesion when I get home tonight =]

#pragma strict

var hoverDistance : float = 0.75;
var hoverForce : float = 10.0;
private var currentHeight : float = 0.0;
private var hoverForceMultiplier : float = 0.0;
private var hoverForceApplied : Vector3 = Vector3(0, 0, 0);

function FixedUpdate () 
{
	// -- find hover distance and add force to make hover		
	var rayHit : RaycastHit;
	if(Physics.Raycast(transform.position, Vector3.down, rayHit))
	{
		currentHeight = rayHit.distance;
		if (currentHeight < (hoverDistance - Time.deltaTime))
		{
			// find percentage of currentHeight below hoverDistance
			hoverForceMultiplier = (hoverDistance - currentHeight) / hoverDistance;
			hoverForceApplied = (Vector3.up * hoverForce * hoverForceMultiplier) + (Vector3.up * 9.8);
			rigidbody.AddForce(hoverForceApplied);    		
		} else {	    	
			// apply anti-gravity force for half distance above hoverDistance
			if ((currentHeight - hoverDistance - Time.deltaTime) < (hoverDistance / 2))
			{
				hoverForceApplied = (Vector3.up * 9.8) * ((hoverDistance - (currentHeight - hoverDistance)) / hoverDistance);
				rigidbody.AddForce(hoverForceApplied);
			}
		}
	}
}

example : http://www.alucardj.net16.net/unityquestions/HoverBoard6.html