Search Unity

How to hover using Physics with slight up and down motion?

Discussion in 'Physics' started by Inferi, Jun 5, 2020.

  1. Inferi

    Inferi

    Joined:
    Sep 28, 2015
    Posts:
    145
    I have been searching and experimenting all day to find out how to hover with physics and also have a slight up and down motion. Keeping it at the same place "hover" is easy but the slight up and down motion seems to be hard for me to figure out.

    I would like to use Sin curve with amplitude and frequensy to control the up and down motions. Also an offset for the y.

    I cant find anything on how to do this that really works.


    In short terms, I like this code to be using physics instead:

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class RigidBodyFloat : MonoBehaviour{
    7.  
    8.     private Rigidbody rb;
    9.     public float yOffset;
    10.     public float amplitude = 0.5f;
    11.     public float frequency = 0.1f;
    12.  
    13.     private float xPos, yPos, zPos;
    14.  
    15.     void Start(){
    16.         rb = transform.GetComponent<Rigidbody>();
    17.     }
    18.  
    19.  
    20.     private void Update() {
    21.         xPos = transform.position.x;
    22.         zPos = transform.position.z;
    23.         yPos = Mathf.Sin(Time.time * frequency) * amplitude + yOffset;
    24.         transform.position = new Vector3(xPos, yPos, zPos);
    25.     }
    26.  
    27.  
    28.     private void FixedUpdate() {
    29.         // Use physics here instead!?
    30.     }
    31.  
    32. }

    Anyone know how?
     
  2. wanderbox

    wanderbox

    Joined:
    Feb 12, 2020
    Posts:
    3
    Maybe something like this? (Unfortunately it seems like the amplitude can be a little bit off from the value you set, particularly at small scales. It can be tweaked until it's right though.)

    Code (CSharp):
    1. public class RigidBodyFloat : MonoBehaviour {
    2.     public float yOffset;
    3.     public float amplitude = 0.5f;
    4.     public float frequency = 0.1f;
    5.  
    6.     private Rigidbody rb;
    7.     private bool initialConditionsSet = false;
    8.  
    9.     void Start() {
    10.         rb = transform.GetComponent<Rigidbody>();  
    11.     }
    12.  
    13.     void FixedUpdate() {
    14.         if (!initialConditionsSet) {
    15.             rb.MovePosition(rb.position + new Vector3(0, yOffset, 0));
    16.             rb.velocity = new Vector3(0, amplitude * frequency, 0);
    17.             initialConditionsSet = true;
    18.         }
    19.         float freqSqrd = frequency * frequency;
    20.         Vector3 desiredAccel = new Vector3(0, freqSqrd * (yOffset - rb.position.y), 0);
    21.         rb.AddForce(desiredAccel, ForceMode.Acceleration);    
    22.     }
    23. }
    24.  
    Edit: Corrected a bug
     
    Last edited: Jun 5, 2020
    Inferi likes this.
  3. Inferi

    Inferi

    Joined:
    Sep 28, 2015
    Posts:
    145
    This is somewhat the same as I had before when I tried to do it myself.

    I cant seem to get it to go up and down in the same small natural motion as I had with the other code. It oscillates "I think its called oscillates" to much. The mass of the object is 250 btw, forgot to say that, and gravity is ON :)

    I have been playing around with the values and ForceMode but its still not the hovering that I need. I need it to be like a thruster that is always on downwards that hold up an object. The up and down motions would not be that big, only small tiny moves :)
     
    Last edited: Jun 5, 2020
  4. Inferi

    Inferi

    Joined:
    Sep 28, 2015
    Posts:
    145
    I have decided to go ahead with just a normal hovering. Where it sits still in air and not any up and down movement. Maybe I will figure it out later and then ill update this thread :)
     
  5. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    983
    If you make your graphical model a child of the root object of the thing you want to hover, you can use animations or even just a simple script to move that model in local space.
     
  6. Inferi

    Inferi

    Joined:
    Sep 28, 2015
    Posts:
    145
    How will that work if I want to manipulate the childobject with physics? like explosions or external forces?
     
  7. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    983
    You don't manipulate the child object, the parent will have the rigidbody and that will be what you manipulate.
     
    Inferi likes this.
  8. Inferi

    Inferi

    Joined:
    Sep 28, 2015
    Posts:
    145
    Sounds like I need to try that :) Thanks
     
  9. Inferi

    Inferi

    Joined:
    Sep 28, 2015
    Posts:
    145
    Just to be clear... I have the rigidbody as parent already and now I am making that hover with physics. You mean that I can manipulate the child to hover with ordinary non physics code instead and that will not break the physics on the parent in future, like with collisions and stuff?
     
  10. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    983
    Yep. So, for example you can write a simple script that attaches to the child object and simply moves it using its transform's localPosition. By doing that, you'll only be manipulating it in relation to the parent object which means the up and down hovering effect will always be moving up and down relative to the direction the parent is facing. If you flip the parent, rotate the parent, or move the parent in anyway, that up/down motion will flip/rotate/move with the parent.

    Also, if you don't want to use a script you can simply attach an animator to the child and use the build-in keyframing tools to make an animation that causes the chil object to move up and down over time. This will effectively be doing exactly the same thing as the above-mentioned script - moving the child object up and down relative to the parent, but it will be done using animation tools and assets rather than code.

    EDIT: I suppose the updown motion might look a bit odd if your object is on a slope and the parent is rotated to follow the slant of that slope. If that's the case then you might have to use a bit of vector math to figure out how to move the child object properly in global space but the same basic idea would still work.
     
    Inferi likes this.
  11. Inferi

    Inferi

    Joined:
    Sep 28, 2015
    Posts:
    145
    No incline or decline is planned in this gameworld, so I dont think that will be any problem but thanks for the heads up :)