磁石に吸い付く動きをUnityで実装してみる--中編--
前編では距離に応じて力が変化するスクリプトを書いてみたけど
磁石オブジェクトと金属オブジェクトの位置関係によって
引力になったり斥力になったりと、ひどい結果でした。
今回は磁石と金属の位置関係に関わらず、両者の間に常に引力が発生するよう
コードを修正できたので記載。
不等式の公式から両者の位置関係を把握して、
x軸方向、y軸方向それぞれにかかる力の符号を変えるようにしました。
public class magneticForce : MonoBehaviour { Vector3 distance; float distanceN;//法線方向の距離 Vector3 magPosition;//磁石の中心位置 float magForce;//磁力を受けるオブジェクトにかかる力 float magForceX;//磁力を受けるオブジェクトにかかる力 float magForceY;//磁力を受けるオブジェクトにかかる力 float magConst = 50.0f;//定数のパラメータ float magAngle;//磁石の角度 GameObject metal;//磁力を受ける金属オブジェクト Rigidbody2D rigid2D; float tanObjects; float angleObjects;//オブジェクト間の角度 float xDir; float yDir; // Use this for initialization void Start () { this.magPosition = transform.position; this.magAngle = transform.localEulerAngles.z * Mathf.Deg2Rad;//ラジアンで角度を取得 this.metal = GameObject.Find("metal"); this.rigid2D = this.metal.GetComponent<Rigidbody2D>(); } // Update is called once per frame void Update () { tanObjects = (metal.transform.position.y - magPosition.y) / (metal.transform.position.x - magPosition.x); angleObjects = Mathf.Atan(tanObjects); distanceN = (magPosition - metal.transform.position).magnitude * Mathf.Sin(angleObjects); magForce = magConst / distanceN; magForceX = Mathf.Abs(magForce * Mathf.Sin(magAngle)); magForceY = Mathf.Abs(magForce * Mathf.Cos(magAngle)); if (metal.transform.position.x > (metal.transform.position.y - magPosition.y) / Mathf.Tan(magAngle) + magPosition.x) { xDir = -1.0f; } else { xDir = 1.0f; } if (metal.transform.position.y > Mathf.Tan(magAngle) * (metal.transform.position.x - magPosition.x) + magPosition.y) { yDir = -1.0f; } else { yDir = 1.0f; } this.rigid2D.AddForce(new Vector2(xDir * magForceX, yDir * magForceY), ForceMode2D.Force); } }