モノ創りで国造りを

ハード/ソフト問わず知見をまとめてます

磁石に吸い付く動きをUnityで実装してみる--後編--

磁石に吸い付く動きの実現がやっとこさ完了。
前編と中編のコードは、金属オブジェクトに力がかかる範囲が限定されていなかったのを改善
これならリアルは差し置いてUnityのデフォルト機能であるArea Effectorを使うほうが
よっぽど楽だなと実感したここ数日間でした。

public class magneticForce : MonoBehaviour {
    Vector3 distance;
    float distanceN;//法線方向の距離
    Vector3 magPosition;//磁石の中心位置
    Vector3 magExtents;
    Vector3 magRightPoint;
    Vector3 magLeftPoint;
    float magForce;//磁力を受けるオブジェクトにかかる力
    float magForceX;//磁力を受けるオブジェクトにかかる力
    float magForceY;//磁力を受けるオブジェクトにかかる力
    float magConst = 5.0f;//定数のパラメータ
    float magAngle;//磁石の角度
    float magAngleSign;
    SpriteRenderer sr;
    float width;
    GameObject metal;//磁力を受けるオブジェクト
    Rigidbody2D rigid2D;
    float tanObjects;
    float angleObjects;//オブジェクト間の角度
    float xDir;
    float yDir;

    // Use this for initialization
    void Start () {
        this.sr = GetComponent<SpriteRenderer>();
        this.magPosition = transform.position;
        this.magAngle = transform.localEulerAngles.z * Mathf.Deg2Rad;//ラジアンで角度を取得
        this.magAngleSign = Mathf.Sign(Mathf.Tan(magAngle));
        this.magExtents = new Vector3(this.sr.bounds.extents.x *  Mathf.Cos(magAngle), this.sr.bounds.extents.x * Mathf.Sin(magAngle), 0.0f);
        this.magRightPoint = magPosition + magExtents;
        this.magLeftPoint = magPosition - magExtents;
        Debug.Log("magAngle:" + magAngle);
        this.metal = GameObject.Find("metal");
        this.rigid2D = this.metal.GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update() {
        if (((metal.transform.position.y - magRightPoint.y) * magAngleSign < magAngleSign * (metal.transform.position.x - magRightPoint.x) / -Mathf.Tan(magAngle)) &&
            ((metal.transform.position.y - magRightPoint.y) * magAngleSign > magAngleSign * (metal.transform.position.x - magLeftPoint.x) / -Mathf.Tan(magAngle))) {
            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);
        }
    }
}