Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Multiple Force positions on Object Issues

Discussion in 'Physics' started by zapman502, Dec 24, 2021.

  1. zapman502

    zapman502

    Joined:
    Apr 13, 2020
    Posts:
    14
    So just for context, im trying to make a space ship and simulate thrusters. I have a cube scaled a bit long to be a basic ship, and as children there are 4 cylinders evenly spaced on the corners of the cube. Now, I did 4 lines of AddForceAtPosition on one script attached to the main ship object, and but the cylinders positions as the force positions. The problem is everytime I activate the "thrusters" they seemingly work fine for a bit, but after letting it run for a while its clear its microscopically not applying force evenly, which eventually magnifies over time and starts spinning my ship object out of control. When I use a simple AddForce on the ship itself I dont have this issue and it acts as expected, but I want the thrusters to work as originally intended.

    My theory is that as each AddForceAtPosition is executed, they are basically rocking the ship at each corner in such a small degree that it makes the forces applied uneven and eventually cascades into the ship flipping. I do have these commands placed in a FixedUpdate function as well. Is there a way to apply force to multiple positions simultaneously? Is my theory even correct? If this has already been discussed AND resolved can you please link to the thread? Code included below
    [EDIT] I found another similar thread HOWEVER, all my 4 thrusters are facing downwards, so they all have to be applying the same simultaneous force to lift off the ground. Also the Mass of the ships rigidbody is 2030000 so that is why the thrust value is so high.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ShipSystems : MonoBehaviour
    6. {
    7.     //Give each thruster its own rigid body and health. If one thruster is damaged, you will have to compensate
    8.     Rigidbody rb;
    9.  
    10.     float _x; //Horizontal thrusters (left right)
    11.     float _y; //Elevation thrusters (up, down)
    12.     float _z; //Depth thrusters (forward, back)
    13.     [SerializeField]
    14.     float thrust;
    15.  
    16.     Vector3 thrusterforce;
    17.     [SerializeField]
    18.     GameObject g_LiftThrusterA;
    19.     [SerializeField]
    20.     GameObject g_LiftThrusterB;
    21.     [SerializeField]
    22.     GameObject g_LiftThrusterC;
    23.     [SerializeField]
    24.     GameObject g_LiftThrusterD;
    25.  
    26.     //Add dev_labled variables to track important rigidbody stats from this script
    27.  
    28.     // Start is called before the first frame update
    29.     void Start()
    30.     {
    31.         rb = this.GetComponent<Rigidbody>();
    32.         //Only making these 0 for now because im focuing on the Y force movement
    33.         _x = 0;
    34.         _z = 0;
    35.     }
    36.  
    37.     // Update is called once per frame
    38.     void FixedUpdate()
    39.     {
    40.      
    41.         if (Input.GetKey(KeyCode.UpArrow))
    42.         {
    43.          
    44.             thrust = 5000000; // times 4 for single AddForce to work
    45.             _y = thrust;
    46.         }
    47.         else
    48.         {
    49.             thrust = 0;
    50.             _y = thrust;
    51.         }
    52.         thrusterforce = new Vector3(_x, _y, _z);
    53.         //rb.AddForce(thrusterforce);  //Test physics with one point
    54.         //All positions
    55.         rb.AddForceAtPosition(thrusterforce, g_LiftThrusterA.transform.localPosition, ForceMode.Force);
    56.         rb.AddForceAtPosition(thrusterforce, g_LiftThrusterB.transform.localPosition, ForceMode.Force);
    57.         rb.AddForceAtPosition(thrusterforce, g_LiftThrusterC.transform.localPosition, ForceMode.Force);
    58.         rb.AddForceAtPosition(thrusterforce, g_LiftThrusterD.transform.localPosition, ForceMode.Force);
    59.  
    60.     }
    61. }
    62.  
     
    Last edited: Dec 24, 2021
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    For starters, this is a physics engine designed for games, not for scientific simulation. Setting a mass to something like 2030000 Kg is way too much. The reason is that you then have to scale-up everything else including, as you indicated, forces. There's simply no need to set such high masses. It won't make your simulation more realistic because you have a mass value equal to what a "real world" object is. What matters for realistic reactions are relative masses only.

    I would start with lowering this to a much more reasonable value. Then the floating-point calculations won't be trying to deal with high values and the higher precisions you seem to want. In the end, it's a finite amount of room in 32-bits.

    AddForceAtPosition, as the docs state, takes a world-position, not a local position. Seems you might be getting confused with AddRelativeForce.
     
  3. zapman502

    zapman502

    Joined:
    Apr 13, 2020
    Posts:
    14
    I fixed it while still using my large values for mass and force. It seems the AddForceAtPosition is pulling instead of pushing. I simply placed my thrusters on top of my object and I get absolutely no rotation, so ill probably have empty objects above my ship as the positions for the force to pull and keep the thrusters under for cosmetic only. Thanks for replying though. I hope this helps other people trying the same thing.
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    There's no directionality to this call, the direction is what you provide so I don't understand the comment.

    I want to highlight again, you are passing the "local" position, not the world position which is what this call wants.
     
  5. zapman502

    zapman502

    Joined:
    Apr 13, 2020
    Posts:
    14
    I dont know what to tell you, I could recreate that project and link you a download if you'd like to see it but yeah, thats what happened. It seems having a force at position below the parent messed up something in the physics. after further testing if I put it on the same Y plane or above the parent then it would work as intended. I know you are saying position doesn't matter but it literally worked by changing the y position of my force points with no change in my code so, maybe its a bug? I dont know but I have no reason to try and start an argument here, just stating my observations.
    I abandoned that project however as I realized what I was doing wasn't optimal for my purposes.
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    I didn't say that at all. I can see you abandoned the project but for clarity for anyone reading, I'm saying it does matter and that you're passing a local-space position when it should be a world-space position (there's a difference).