2013年6月4日火曜日

ボールを浮かしたい。その2

一日開いちゃいました。
前回の続き。

ボールを浮かしたい

コースは固定されてて重力が変化する空間の中でボールだけ浮かしたい…とか
書くだけでややこしいですね。

この考えでは進みそうにないのでちょっと考え切り替えました。
めんどくさいから物理エンジンに任せようって。
コースが上下に動けば勝手にボールは跳ねるだろうと。

どうやろうか

なんとかしてスマホの上下移動をコースの高さに反映すればいいんだよね。

Input.accelerationは常に重力加速度を受けてるから
スマホが固定されていれば1G(単位ベクトル)がかかった状態。

ここでスマホを上下に動かすとベクトルサイズが変わるはず。

やってみた

てきとーにInput.accelerationのベクトルサイズを計算して表示

float g = Input.acceleration.magnitude;
print(string.Format("DEBUG {0}", g));

動かさないとおおむね1前後
スマホ机に置いた状態
動かすとそれなりにばらつく
上下に動かした状態


でもこれだと左右に動かすだけでも1G以上がかかるよね。
まぁ傾けて遊ぶゲームだし急に左右に振るのは考えなくていいか。
無視しよ。

とりあえず使えそう!

ちょっと修正

Floorタグを持つオブジェクトのZ座標を動かすように書いてみた。
どんどんずれてどっか行っちゃうので自然と0近くに収束するようにした。

こんな感じ。

using UnityEngine;
using System.Collections;

public class Sensor : MonoBehaviour
{
    /// <summary>
    /// スマホの移動に連動させるオブジェクト
    /// </summary>
    GameObject floor;

    /// <summary>
    /// 前フレームでのZ座標
    /// </summary>
    float lastZ;

    // Use this for initialization
    void Start()
    {
        this.floor = GameObject.FindGameObjectWithTag("Floor");
        this.lastZ = 0;
    }


    // Update is called once per frame
    void Update()
    {
        //端末が上下に動いた量 +↑、-↓
        float g = Input.acceleration.magnitude - 1.0f;

        this.lastZ = (this.lastZ + g) * 0.9f;


        Vector3 lastPos = floor.transform.position;
        Vector3 newPos = new Vector3(lastPos.x, lastPos.y, this.lastZ);

        floor.transform.position = newPos;
    }
}

追記

黄本読んでたら気になる記述見ちゃった。

  • プログラム制御するオブジェクトはRigidbodyコンポーネントを付ける
  • そのうえでIsKinematicプロパティをONにする
  • Update関数ではなくFixedUpdate関数内で更新する
  • transformを直接操作せず、RigidbodyクラスのMoveRotation、MovePositionを使う
だそうな。


急きょ書き換え

  • floorオブジェクトにrigidbodyを付加、isKinematicをON
  • スクリプトも変更

using UnityEngine;
using System.Collections;

public class Sensor : MonoBehaviour
{
    /// <summary>
    /// スマホの移動に連動させるオブジェクト
    /// </summary>
    GameObject floor;

    /// <summary>
    /// 前フレームでのZ座標
    /// </summary>
    float lastZ;

    // Use this for initialization
    void Start()
    {
        this.floor = GameObject.FindGameObjectWithTag("Floor");
        this.lastZ = 0;
    }


    // Update is called once per frame
    void FixedUpdate()
    {
        //端末が上下に動いた量 +↑、-↓
        float g = Input.acceleration.magnitude - 1.0f;

        this.lastZ = (this.lastZ + g) * 0.9f;

        Vector3 lastPos = floor.transform.position;
        Vector3 newPos = new Vector3(lastPos.x, lastPos.y, this.lastZ);

        floor.rigidbody.MovePosition(newPos);
    }
}

FixedUpdateだと更新間隔を指定できるみたいね。
指定方法はまた調べよう。

transporm.positionとrigidbody.MovePositionの違いはまだ分かんない。

ていうかボールの跳ねあがり方まったく別物になったんだけどw

Unity系記事まとめ

スポンサーリンク

Related Posts Plugin for WordPress, Blogger...