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

Making a Script for a Magnet with a Hole in the Center

Discussion in 'Scripting' started by Shadowfang_TC, Nov 17, 2016.

  1. Shadowfang_TC

    Shadowfang_TC

    Joined:
    Jul 26, 2015
    Posts:
    18
    Hello,

    I already have a script that allows a marble to be "magnetically" pulled towards an object and stick there. I also have built a couple of different magnets, one of which is basically a donut. Is there any way in which I could edit this script to allow the ball to pass through the center of the object without getting stuck if it had enough velocity?


    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5.  
    6. internal class MagneticCup : MonoBehaviour
    7. {
    8.     [SerializeField]
    9.     Rigidbody MarbleRigidBody = null;
    10.  
    11.     float MaxDistance = 2f; // Maximum range at which the marble will start being pulled to the cup
    12.     float MaxStrength = 30f; // Strength with which the marble will be pulled when it is right next to the cup (reduces with distance)
    13.  
    14.     void Update()
    15.     {
    16.         Update_Magnetism();
    17.         Update_CupDirection();
    18.     }
    19.  
    20.     void Update_Magnetism()
    21.     {
    22.         float Distance = Vector3.Distance(MarbleRigidBody.transform.position, this.transform.position);
    23.  
    24.         if (Distance < MaxDistance) // Marble is in range of the magnet
    25.         {
    26.             float TDistance = Mathf.InverseLerp(MaxDistance, 0f, Distance); // Give a decimal representing how far between 0 distance and max distance.
    27.             float strength = Mathf.Lerp(0f, MaxStrength, TDistance); // Use that decimal to work out how much strength the magnet should apple
    28.             Vector3 DirectionToCup = (this.transform.position - MarbleRigidBody.transform.position).normalized; // Get the direction from the marble to the cup
    29.  
    30.             MarbleRigidBody.AddForce(DirectionToCup * strength, ForceMode.Force);// apply force to the marble
    31.  
    32.         }
    33.     }
    34.  
    35.     void Update_CupDirection()
    36.     {
    37.         Vector3 DirectionToMarble = (MarbleRigidBody.transform.position - this.transform.position).normalized; // Direction from the cup to the marble
    38.         this.transform.forward = DirectionToMarble; // Make the cap face that direction
    39.     }
    40.  
    41. }
    42.  
    43.  
    The part at the bottom of the script that causes the object to face towards the marble can be ignored as well. Thank you Mordus for helping me build this one originally.
     
    Last edited: Nov 17, 2016
  2. Shadowfang_TC

    Shadowfang_TC

    Joined:
    Jul 26, 2015
    Posts:
    18
  3. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    8,950
    For something like a torus (donut), you could basically determine the closest point on a circle to the object and apply the force there. You could calculate the angle from the center toward the target object and project it out by the radius on the plane of the magnet. Might cause some odd behavior, but it's a place to start.
     
  4. Shadowfang_TC

    Shadowfang_TC

    Joined:
    Jul 26, 2015
    Posts:
    18
    That was one of my initial thoughts, but I'm not certain on how to go about doing that. I am very new to using C#. On a side note, the torus (thought I'd put donut in case anyone didn't know the shapes lol) does not seem to allow the marble to roll through it at all. I tested the mesh collider, and it causes the hole to be an invisible part of the collider. Is there a way around this?
     
  5. Scabbage

    Scabbage

    Joined:
    Dec 11, 2014
    Posts:
    268
    Probably because the mesh collider is checked as convex. Untick the convex option in the Mesh Collider component of the torus and see if it changes the physics collider.
    The script also looks fine to me, why wouldn't the marble go through? Assuming it passes through the centre of the torus without hitting it, if it had any velocity when entering the range of the magnet it should exit with the same velocity.
     
  6. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    8,950
    What @Scabbage said. Make sure your collider is set to convex.

    I played around with it a bit.. the math actually turns out to pretty straight forward. If you have a transform, the method on that script looks like this :
    Code (CSharp):
    1.         float radius = 20f;
    2.         public Vector3 getPoint(Vector3 target)
    3.         {
    4.             Vector3 pp = Vector3.ProjectOnPlane((target-transform.position), transform.up)+transform.position;
    5.             return ((( pp-transform.position).normalized)*radius)+transform.position;
    6.         }
    7.  
    8.  
    The radius being the size of the circle, and the target passed is the location of the object you want to find the point for. It takes into account the rotation of the transform. Here is how it responds with a few gizmos attached to see what is happening.


    The yellow is the target, the green connection on the circle is the point that is being returned.

    Heh.. I kept playing around with it, here is some video:
    (crappy frame rate capture)

    Little bit better (still gets choppy at the end, with all the editor gizmos):
     
    Last edited: Nov 20, 2016
    Mordus likes this.
  7. Mordus

    Mordus

    Joined:
    Jun 18, 2015
    Posts:
    174
    Nice. I took a crack at it but i couldn't get it to work quite right. Took the same concept as you but tried to do it a different way by playing with vectors and rotations (something i can never get quite right :p); couldn't get it to work quite right and the calculated point was always off the plane a little. I didn't actually know about Vector3.ProjectOnPlane. I'll have to play with that later :p.
     
  8. Shadowfang_TC

    Shadowfang_TC

    Joined:
    Jul 26, 2015
    Posts:
    18
    This is what happens when the ball collides with the center of the torus shaped magnet. There's no magnetic script active on the object at this time.






    I haven't tested the suggested script yet. Once I fix the problem with the collider I will get on it.
     
    Last edited: Nov 20, 2016
  9. Scabbage

    Scabbage

    Joined:
    Dec 11, 2014
    Posts:
    268
    @Shadowfang_TC What collider are you using for the torus? Unchecking convex did nothing?
     
  10. Shadowfang_TC

    Shadowfang_TC

    Joined:
    Jul 26, 2015
    Posts:
    18
    Unchecking convex made it so the collider stopped working entirely. The ball passed through all portions of the mesh at that point. Also I am using the mesh collider as there is no easy way to shape a collider for a torus with the built in tools.
     
  11. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    8,950
    Make sure your mesh collider isn't too large, there is a limit to the amount of verts your hull can have. Though it should give you a warning if there are too many.
     
  12. Shadowfang_TC

    Shadowfang_TC

    Joined:
    Jul 26, 2015
    Posts:
    18
    I'm receiving no warning. Also wouldn't the collider not work at all if it were too big? How would I go about checking the triangle count on the mesh? When I exported it from Cinema it had 144 polygons.