Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
1
Question by Calclavia · Sep 16, 2013 at 12:42 PM · objectweightunder

Weight exerted on object

I'm working on a game where I have a pressure plate and the player can stack objects on it. Is it possible to detect how much mass is stacked on top of the pressure plate? Any explanation of methods I could use to achieve this?

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

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by meat5000 · Sep 16, 2013 at 01:02 PM

Force = Mass x Acceleration.

In this case it is Mass x Gravity.

That simple.

Maybe manipulate the OnCollisionStay functions or even perform up upwards raycast from the plate to collect all the rigidbody.mass information associated with the colliders you detect. Then you can just add the masses and multiply by gravity if you like, to get the downward Force.

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 Calclavia · Sep 17, 2013 at 01:34 AM 0
Share

The thing I'm not sure about is how to raycast upwards for this case. Won't the object at the very bottom block the casting of blocks stacked on top?

avatar image meat5000 ♦ · Sep 17, 2013 at 11:06 AM 0
Share

Just shoot a ray in the local y of the button or the normal of the button face. The objects won't block the ray.

avatar image
0

Answer by SteenPetersen · Jan 26, 2019 at 10:55 AM

I made a weight scale for my game where I used raycasts to determine this, but it was a bit iffy as it was Virtual reality and things could slide away from the ray etc - so I used Physics.OverlapSphere instead. Then I simply populated two rigidbody arrays with the correct parent object of the compound colliders that it interacts with and determined the weight on the right and left and could them compare.

I used the extension method below to find the correct parent that has the rigidbody. I dont like using the keyword .root as that way I can organise my hierarchy without worrying about breaking code.

     /// <summary>
     /// Finds a parent with a certain tag name, will return null 
     /// if none can be found
     /// </summary>
     /// <param name="go">Child Object from which to begin searching</param>
     /// <param name="tag">String value tag to search for</param>
     /// <returns></returns>
     public static GameObject FindParentWithTag(this GameObject go, string tag)
     {
         // reference to child
         Transform child = go.transform;
 
         // go up the hierarchy and look through all parent objects
         while (child.parent != null)
         {
             // if you find one with the given tag
             if (child.parent.tag == tag)
             {
                 // return it
                 return child.parent.gameObject;
             }
 
             // set the current child to be the previous parent so we can keep looking
             child = child.parent.transform;
         }
 
         // return nothing if there was no parent with the given tag
         return null; 
     }


Once I had that in Place I could attach the script below to the scale and it works quite nicely:

 public class ScalesText : MonoBehaviour
 {
     [Tooltip("Position of the left shelf from where we will cast the overlapsphere")]
     [SerializeField] Transform leftShelf;
     [Tooltip("Position of the right shelf from where we will cast the overlapsphere")]
     [SerializeField] Transform rightShelf;
     [Tooltip("Text field where we will write the difference between the two weights")]
     [SerializeField] TextMeshProUGUI textField;
     [Tooltip("Text field where we will write the total weight on the right side")]
     [SerializeField] TextMeshProUGUI rightTotal;
     [Tooltip("Text field where we will write the total weight on the left side")]
     [SerializeField] TextMeshProUGUI leftTotal;
 
     /// <summary>
     /// List of rigidbodies on the right side
     /// </summary>
     private List<Rigidbody> objectsOnRight;
     /// <summary>
     /// lidt of rigidbodies on the left side
     /// </summary>
     private List<Rigidbody> objectsOnLeft;
 
     /// <summary>
     /// the total weight current on the right side
     /// </summary>
     float totalWeightOnRight;
     /// <summary>
     /// the total weight currently on the left side
     /// </summary>
     float totalWeightOnLeft;
 
     private void Start()
     {
         /// Initialize the two lists that will be needed
         objectsOnRight = new List<Rigidbody>();
         objectsOnLeft = new List<Rigidbody>();
     }
 
     private void Update()
     {
         /// Don't perform this check everyframe as it 
         /// is not very efficient to do so
         if (Time.frameCount % 50 == 0)
         {
             DetermineWeight();
         }
     }
 
     /// <summary>
     /// Determines the weight on the right and left 
     /// side of the Scale and also the difference in weight.
     /// Will also write the results to the UI elements
     /// </summary>
     private void DetermineWeight()
     {
         totalWeightOnRight = 0;
         totalWeightOnLeft = 0;
 
         int interactableLayer = 1 << 14;
 
         Collider[] right = Physics.OverlapSphere(rightShelf.position, 0.15f, interactableLayer);
         Collider[] left = Physics.OverlapSphere(leftShelf.position, 0.15f, interactableLayer);
 
         for (int i = 0; i < right.Length; i++)
         {
             if (!objectsOnRight.Contains(right[i].gameObject.FindParentWithTag("Interactable").GetComponent<Rigidbody>()))
             {
                 objectsOnRight.Add(right[i].gameObject.FindParentWithTag("Interactable").GetComponent<Rigidbody>());
             }
         }
 
         for (int i = 0; i < left.Length; i++)
         {
             if (!objectsOnLeft.Contains(left[i].gameObject.FindParentWithTag("Interactable").GetComponent<Rigidbody>()))
             {
                 objectsOnLeft.Add(left[i].gameObject.FindParentWithTag("Interactable").GetComponent<Rigidbody>());
             }
         }
 
         for (int i = 0; i < objectsOnRight.Count; i++)
         {
             totalWeightOnRight += objectsOnRight[i].mass;
         }
 
         for (int i = 0; i < objectsOnLeft.Count; i++)
         {
             totalWeightOnLeft += objectsOnLeft[i].mass;
         }
 
         rightTotal.text = totalWeightOnRight.ToString();
         leftTotal.text = totalWeightOnLeft.ToString();
         textField.text = Math.Abs(totalWeightOnRight - totalWeightOnLeft).ToString();
 
         objectsOnRight.Clear();
         objectsOnLeft.Clear();
     }
 
     private void OnDrawGizmos()
     {
         Gizmos.color = Color.red;
         Gizmos.DrawWireSphere(rightShelf.position, 0.15f);
         Gizmos.DrawWireSphere(leftShelf.position, 0.15f);
     }


Hope this helps someone trying to do the same as me =)

have fun! alt text


scale.png (126.7 kB)
Comment
Add comment · 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
0

Answer by HazimEmad · Feb 15 at 01:31 AM

You can try this: (assuming all objects and button have center anchor)

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class WeightedButton : MonoBehaviour
 {
     [SerializeField]
     float massRequired = 100; //Mass required to activate button
     [SerializeField]
     float initialCastDistance = 0.2f; //Initial Check distance for first object on the button
     float dynamicCastDistance; //This number will be used to change the check distance of the box cast
     [SerializeField]
     LayerMask objectLayerMask; //Objects to weigh.They must have a rigidbody & collider
     bool totalMassCalculated;  //Used to exit the while loop after adding all masses
     RaycastHit[] raycastHits; //Array that will contain all objects placed on the button
     int currentNumberOfObjectsOnButton; //Dynamic Counter
     float totalMass; //Sum of masses of all placed objects
     Vector3 halfExtents; //The size of the button collider used for boxcasting
     float distanceFromTheTop; //highest point in the stack
 
     private void Awake()
     {
         halfExtents = GetComponent<BoxCollider>().bounds.extents;
     }
     void OnCollisionStay(Collision collision)
     {
         if (collision.gameObject.tag == "object")
         {
             CheckTotalMass();
 
             if (totalMass >= massRequired)
             {
                 Debug.Log("Button is ON");
             }
             else
             {
                 Debug.Log("Button is OFF");
             }
         }
     }
 
     void CheckTotalMass()
     {
         // Reset all the values
         currentNumberOfObjectsOnButton = 0;
         totalMass = 0;
         totalMassCalculated = false;
         distanceFromTheTop = 0;
         dynamicCastDistance = initialCastDistance;
 
         //While loop used for determining the number and mass of placed objects
         while (!totalMassCalculated)
         {
             //Check for objects using the dynamic distance
             raycastHits = Physics.BoxCastAll(transform.position, halfExtents, Vector3.up,
                 Quaternion.identity, dynamicCastDistance, objectLayerMask);
 
             //Check if we reached the top object
             if (raycastHits.Length > currentNumberOfObjectsOnButton)
             {
                 //Calculate the distance from the top
                 for (int j = 0; j < raycastHits.Length; j++)
                 {
                     if (distanceFromTheTop < (raycastHits[j].distance
                         + raycastHits[j].transform.GetComponent<Collider>().bounds.size.y))
                     {
                         distanceFromTheTop = raycastHits[j].distance
                         + raycastHits[j].transform.GetComponent<Collider>().bounds.size.y;
                     }
                 }
 
                 //Increase the check distance
                 dynamicCastDistance = distanceFromTheTop + initialCastDistance;
 
                 //Increase the number of placed object to check for in the next loop cycle
                 currentNumberOfObjectsOnButton++;
             }
             else
             {
                 //This is used to exit the while loop when we reach the top of the stack
                 totalMassCalculated = true;
 
                 //For loop to add the masses of the placed object
                 for (int i = 0; i < raycastHits.Length; i++)
                 {
                     totalMass += raycastHits[i].transform.GetComponent<Rigidbody>().mass;
                 }
             }
         }
 
         Debug.Log("Total mass is " + totalMass);
 
         Debug.Log("Total number of objects is " + raycastHits.Length);
 
         Debug.Log("Approximate Distance from top is " + distanceFromTheTop);
     }
 }


Comment
Add comment · 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

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

18 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

Related Questions

How do I add gravity to an object? 1 Answer

Emmiter in time intervals 1 Answer

swapping out an object on collision 2 Answers

Problem with Object collision 1 Answer

Animating an object so it doesn't bounce to the initial location the animation was recorded 1 Answer


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