Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by megaspeeder · Sep 09, 2020 at 12:05 PM · physicsrigidbodyforcedragvehicle

How to negate this force?

I'm making a videogame about submarines. I need the player to be able to move around the submarine. I've implemented this with a player using a rigidbody and a controller script and a submarine gameobject using a rigidbody and a controller script. The rigidbody has a script which is called buoyancy.


Depending on the volume of water displaced and the weight of the rigidbody, it will sink up to a certain height. This works fine.
The problem is since there is drag on each rigidbody, when the player moves, it will act this force upon the submarine and move it. This also happens when the player is pushing on a wall connect to the interior of the submarine.
I want the player not to be able to move the submarine from walking inside it but if it is light enough, to be able to push it from the outside.
Here's a link to a video showing this
Buoyancy Script

 using System;
 using UnityEngine;
 
 public class Buoyancy : MonoBehaviour
 {
     private const float surfaceHeight = 0f;
     private const float waterDensity = 1f;
 
     [SerializeField]
     private float area = 0f;
     [SerializeField]
     private Rigidbody objectRigidbody = null;
 
     private Vector3 buoyantForce = Vector3.zero;
 
     public Vector3 Force => buoyantForce;
 
     private void FixedUpdate()
     {
         if (transform.position.y >= surfaceHeight)
         {
             buoyantForce = Vector3.zero;
             return;
         }
 
         buoyantForce = GetBuoyantForce();
 
         objectRigidbody.AddForce(buoyantForce, ForceMode.Force);
     }
 
     private Vector3 GetBuoyantForce()
     {
         Vector3 u = Vector3.up;
 
         float magnitude = waterDensity * -Physics.gravity.y * (surfaceHeight - transform.position.y) * area;
 
         return magnitude * u;
     }
 }

Player Movment Script

 using System;
 using UnityEngine;
 
 public class PlayerMovement : MonoBehaviour
 {
     [SerializeField]
     private Rigidbody playerRigidbody = default;
     [SerializeField]
     private float jumpHeight = 1f;
     [SerializeField]
     private float airPenalty = 0.2f;
     [SerializeField]
     private float topSpeed = 2f;
     [Header("Ground")]
     [SerializeField]
     private Transform groundCheck = default;
     [SerializeField]
     private float groundRadius = 1f;
     [SerializeField]
     private LayerMask groundMask = default;
 
     private Input input = default;
     private Vector2 move = default;
     private bool grounded = false;
     private bool jump = false;
 
     private void Awake()
     {
         input = new Input();
 
         input.Player.Move.performed += ctx => move = ctx.ReadValue<Vector2>();
         input.Player.Move.canceled += _ => move = Vector2.zero;
 
         input.Player.Jump.performed += _ => jump = true;
         input.Player.Jump.canceled += _ => jump = false;
     }
 
     private void FixedUpdate()
     {
         CheckGrounded();
 
         Vector3 force = Vector3.ClampMagnitude(transform.right * move.x + transform.forward * move.y, 1f) * topSpeed - playerRigidbody.velocity;
 
         force.y = 0f;
 
         if (grounded)
         {
             if (jump)
             {
                 playerRigidbody.AddForce(Vector3.up * Mathf.Sqrt(-2f * Physics.gravity.y * jumpHeight), ForceMode.VelocityChange);
             }
         }
         else
         {
             force *= airPenalty;
         }
 
         if (force != Vector3.zero)
         {
             playerRigidbody.AddForce(force, ForceMode.VelocityChange);
         }
     }
 
     private void CheckGrounded()
     {
         grounded = Physics.CheckSphere(groundCheck.position, groundRadius, groundMask);
     }
 
     private void OnEnable()
     {
         input.Enable();
     }
 
     private void OnDisable()
     {
         input.Disable();
     }
 
     private void OnDrawGizmos()
     {
         if (groundCheck != null)
         {
             Gizmos.color = Color.red;
             Gizmos.DrawWireSphere(groundCheck.position, groundRadius);
         }
     }
 }
 

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Sep 09, 2020 at 12:22 PM

To ensure a one directional interaction between the submarine and your player you could split up the physics into two parts. Unfortunately Unity's standard physics implementation does not support mutiple physics scenes in order to have seperate local physics for the player. However you can work with collision layers and have a seperate collison object for the submatine with a kinematic rigidbody. This seperate collision model of the submarine would be simply a child of the actual submarine. Now the player shouldn't collide with the actual submarine but only with this extra interior collider object. Since this object has a kinematic rigidbody it can push the player around when the submarine moves, but never the other way round because the player does not interact with the actual (non kinematic) submarine rigidbody.


Note if you don't want external forces and movement on the submarine to affect the player at all, it's usually the easiest solution to have the interior physics seperate and stationary somewhere in the level and just map the results into the actual submarine. Of course this can get tricky when the player can actually leave and enter the submarine. The first approach is more robust in this regards. Though it's also possible to combine both solutions depending on the wanted behaviour.


Always keep in mind that the physics engine is just a rough approximation and game or simulation development is just about getting the look and feel right and not to be physically accurate. PhysX is not a viable solution when you're looking for actual scientific physcis simulations.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image megaspeeder · Sep 09, 2020 at 01:19 PM 0
Share

I'm trying to do an open world game, so yes, the player will be able to enter and exit. I also have another script which automatically levels out the submarine because if it collides with an object, I want it to rotate accordingly but then return to its normal inclination. Would that affect the interaction or not? I'm already using two layers for collisions because when the player is inside the submarine, I still want the exterior colliders to detect collisions on the outside but if they are all on the same collision layers then the player is forced outside of the submarine. How can I adjust this accordingly? Sorry for the long answer.

avatar image Bunny83 megaspeeder · Sep 11, 2020 at 12:13 AM 0
Share

Of course this is all still possible. Assu$$anonymous$$g that the world geometry and most other things are on the default layer, you can move the submarine itself on a seperate layer, the player on a seperate layer and the additional kinematic rigidbody on a seperate layer. With the collision matrix you can exactly specify which layer can collide with which other layer. So your submarine rigidbody should only collider with the default layer. The Player should collide with the default layer and the additional kinematic rigidbody of the submarine, but not with the submarine itself. Likewise the additional kinematic rigidbody shouldn't collide with anything else besides the player(s). Since the kinematic rigidbody can not be affected by collisions with other objects, the player can not affect the actual submarine at all.

avatar image
0

Answer by Matt1000 · Sep 09, 2020 at 12:14 PM

If you know for sure the rigidbody Drag is the one causing the forces (which I didn't get tbh), then I'd simply go with a script that toggles that property whn you leave/enter the submarine.


Also, I don't understand why the buoyancy is affected by height but maybe it's due to pressure, not sure.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image megaspeeder · Sep 09, 2020 at 12:24 PM 0
Share

I'm following Archimedes' Principle:

F = h · ρ · g

Where

  • F is the force exerted upon the submarine

  • h is the depth of the submarine

  • ρ is the density of the medium

  • g is the gravity acted upon the submarine

Since the submarine is affected by gravity, the depth will begin to increase and thus the force. When the force is equals to the force of gravity, it will be at it's equilibrium point.

Put a beach ball on the surface. It stays there. Submerge it just below the surface. It pushes upwards. Try putting it by your feet. It pushes upwards very strongly.

avatar image Bunny83 · Sep 09, 2020 at 12:37 PM 0
Share

Buoyancy in reality is not affected by height (or depth). A real submarine adjusts it's ballast tanks in order to become neutral so they perfectly float in the medium. They move up and down by using its diving rudders to literally "swim" up and down in the water. In a sense a submarine drives through the water like an airplane flies through the air. With the exception that a submarine doesn't immediately "fall down" when they make a full stop since they don't have to generate lift through speed. Though even submarines have "sail planes" which keep them more stable as they drive through the water.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

257 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Touch controlled ice puck 0 Answers

Add force based on drag speed 4 Answers

Force is not applied to the rigidbody? 1 Answer

Realistic methods of propulsion without friction involved 0 Answers

How exactly does Rigidbody Drag works? 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges