- Home /
How to make a ball float / hover
I have created a floor and a sphere and am trying to get the ball to hover (about 1.6meters) above the ground. The ball will need to have a rigidbody though and be subjected to gravity (in certain cases). I cant seem to replicate the slight "hover" effect for the ball where it goes up and down slightly.
I have seen a few other examples but either cant get them to work as they were in javascript and as much as i have tried i cant get them to work, or they are unpredictable and don't give the results i desired.
C# examples only please. Many thanks.
Answer by VesuvianPrime · Feb 13, 2014 at 10:08 PM
Hi Somarl
It sounds like you want the ball to Oscillate
You can achieve this motion in Unity by doing something like this:
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour
{
void Update()
{
this.transform.position = Vector3.up * Mathf.Cos(Time.time);
}
}
Yes thanks. Oscillation is what im going for. This works great thank you. I cant however work out how to assign three values (speed of hovering, max height and $$anonymous$$ height) and make it oscillate between that. Also when i make this move around, will it be able to bounce off walls? (Sorry for the extra questions but i haven't been able to make it move around yet so i cant test this.)
You can control the oscillation like this:
float hoverHeight = (maxHeight + $$anonymous$$Height) / 2.0f;
float hoverRange = maxHeight - $$anonymous$$Height;
float hoverSpeed = 10.0f;
this.transform.position = Vector3.up * hoverHeight + $$anonymous$$athf.cos(Time.time * hoverSpeed) * hoverRange;
The more i think about it, the more i think you may be better putting your physics components on one GameObject and adding your oscillating ball as a child. This way the physics and the oscillation wont interfere with each other.
Here's a more editor friendly version. :) ;)
Also, if you wanted something more "aware" of its surroundings, all you'd need to do is raycast up or down and if the distance from the raycast is less than a value, change the upper or lower limiters. :D
using UnityEngine;
public class Hover : $$anonymous$$onoBehaviour
{
[SerializeField] [Range(0, 100)] private float oscillationRate = 1;
[SerializeField] [Range(0, 1)] private float oscillationRange = 1;
[SerializeField] private float upperHeightLimit = 10;
[SerializeField] private float lowerHeightLimit = 1;
private void Update ()
{
transform.position = ClampHeight((Vector3.up * $$anonymous$$athf.Cos(Time.time * oscillationRate) * ClampRange(oscillationRange)) + transform.position);
}
private float ClampRange(float value)
{
if (transform.position.y > upperHeightLimit)
upperHeightLimit = transform.position.y;
if (transform.position.y < lowerHeightLimit)
lowerHeightLimit = transform.position.y - lowerHeightLimit;
if (upperHeightLimit < lowerHeightLimit)
upperHeightLimit = lowerHeightLimit + 0.1f;
if (lowerHeightLimit > upperHeightLimit)
lowerHeightLimit = upperHeightLimit + 0.1f;
if (value != ((upperHeightLimit + lowerHeightLimit) / 2) - 0.25f)
value = ((upperHeightLimit + lowerHeightLimit) / 2) - 0.25f;
if (value != value * oscillationRange)
value *= oscillationRange;
value *= 0.01f;
return value;
}
private Vector3 ClampHeight(Vector3 value)
{
if (value.y < lowerHeightLimit)
value.y = lowerHeightLimit;
if (value.y > upperHeightLimit)
value.y = upperHeightLimit;
return value;
}
}
Uhm sorry but this term:
((normalizedRange + -normalizedRange) / 2.0f)
is just 0.0f
and this term:
(normalizedRange - -normalizedRange)
is just normalizedRange*2
. Also note that you're adding the cosine to the position over time. So you effectively integrating the cosine method. Since the derivative and the integral of the cosine is just "-sine" you still get a sine wave. However due to integration your absolute y position can drift over time.
So your line of code can be simplified to:
transform.position += Vector3.up * $$anonymous$$athf.Cos(Time.time * rate) * normalizedRange * 2;
This does exactly the same as your line of code ^^.
Unfortunately i cant get this to work. I have the following script on the sphere
using UnityEngine; using System.Collections;
public class BallControl : $$anonymous$$onoBehaviour { public float maxHeight = 10f; public float $$anonymous$$Height = 5f;
float hoverHeight = (maxHeight + $$anonymous$$Height) / 2.0f; //$$anonymous$$in and $$anonymous$$ax height are either not defined or if they are like above i get a field initialiser cannot reference the nonstatic field
float hoverRange = maxHeight - $$anonymous$$Height;
float hoverSpeed = 10.0f;
void Update()
{
this.transform.position = Vector3.up * hoverHeight + $$anonymous$$athf.cos(Time.time * hoverSpeed) * hoverRange; //$$anonymous$$athf does not contain a definition of cos
}
void OnControllerColliderHit(ControllerColliderHit hit)
{
print("collision"); //This never works because collision is never detected no matter what.
}
}
I am not sure though if $$anonymous$$onodevelop is being strange or not. I have never heard of $$anonymous$$athf not knowing what cos is. I however reinstalled unity, scrapped every project and started fresh and the same problem still occurs. I cant even run that script to see what values i want. In regards to the collision i think there is something wrong with the character controller as it never registers hits, only on trigger enter. There isnt a way to get a character controller to recognise collisions as yet in unity (otherwise the OnCollisionEnter bit would work, or OnControllerColliderHit(ControllerColliderHit hit) would work etc ) so i am going to work on building my own if i can.
I believe capitalizing the "c" in $$anonymous$$athf.cos would solve the recognition issue.
However, then you'll probably run into the issue I did: operator "+" cannot be appluied to operands of type Vector3 and float. Alas, no solution to this at the moment, but someone on here must know a way around this!
Answer by blblopez · Oct 12, 2014 at 12:50 AM
I believe capitalizing the "c" in Mathf.cos would solve the recognition issue.
However, then you'll probably run into the issue I did: operator "+" cannot be appluied to operands of type Vector3 and float. Alas, no solution to this at the moment, but someone on here must know a way around this!
Answer by MrSoad · Oct 11, 2014 at 11:56 PM
Take a look at this video tutorial. It is for floating on water, but remember that the water does not really exist and therefore it is exactly the same as floating on air(with the water plane render disabled) :
http://www.youtube.com/watch?v=mDtnT5fh7Ek
His code is short and works perfectly. You can adjust the water height value to make your sphere float at various heights. You can add a coroutine to add a regular slight adjustment to this for an extra bobbing effect.
Your answer
Follow this Question
Related Questions
Make enemy follow and hit the player 3 Answers
Hovering Tank 2 Answers
Sorting variable names by their values. 2 Answers
First Person Controller. (Unity3) 1 Answer