AizuVR blog

会津大学VR部の部員が持ち回りで投稿していくブログです。特にテーマに縛りを設けずに書いていきます!

「面白法人カヤックVR分室」としても活動しています。詳細はこちら

Cしゃーぷ

 安江です。vr部のチーム活動でc♯を先輩に教えてもらいながらやってるんですが、、、やればやるほどわからないことが増えていき、質問しっぱなしです。そんな僕が教えてもらいながらも、なんとか作ったプログラムを今回は載せようと思います。

 今回の目的は破壊のシステムみたいな感じです。詳しく言いますと、ものにダメージが入ると、分解するようにするって感じです。

 作るプログラムは3つ。

 一つ目は

public class DestructThing : MonoBehaviour {

 public bool isDecomposition;   
 /*structure配列の保持*/
 public List<Structure> structures = new List<Structure>();

// Use this for initialization
void Start()
{
    /*rigidbodyの取得*/
    gameObject.AddComponent<Rigidbody>();
    /*子の取得*/
        foreach (var child in structures)
        {
            var structure = child.gameObject.AddComponent<Structure>();
            structures.Add(structure);
            structure.Initialize(this);
        }

}
/*ダメージを受けたとき*/
public void Damaged()
{
    Collapse();
}

void Collapse() {
    if (!isDecomposition)
    {
        /*rigidbodyの取得*/
        var rigid = GetComponent<Rigidbody>();
        Destroy(rigid);
        foreach (var structure in structures)
        {
            if (!structure.isDecomposition) {
                structure.gameObject.AddComponent<Rigidbody>();
            }
        }
        isDecomposition = true;
    }
}


// Update is called once per frame
void Update () {


}

}

目的としては、ダメージが入ったときにしたにstructure(そういうclassがあります、あとで説明します)に物理演算をしたいということです。 そのために配列を確保しそれをlistとして子を保持したということです。 3つのプログラムでやろうとしているのでこれだけではよくわからないですね、、、、、。

次はstructureです

public class Structure : MonoBehaviour {

public bool isDecomposition;
/*DesturctThingを保持するために*/
public DestructThing destructThing;
/*fragment配列の確保*/
public List<Fragment> fragments = new List<Fragment>();

// Use this for initialization
void Start()
{
    /*子の取得*/
    foreach (Transform child in transform)
    {
        var fragment = child.gameObject.AddComponent<Fragment>();
        fragments.Add(fragment);
        fragment.Initialize(this);
    }

}

public void Initialize(DestructThing destructThing)
{
    this.destructThing = destructThing;
}
/*ダメージを受けた時*/
public void Damaged()
{
    destructThing.Damaged();
    Collapse();
}
/*崩壊させたい*/
void Collapse()
{
    if (!isDecomposition)
    {
        var rigid = GetComponent<Rigidbody>();
        if (rigid != null)
        {
            Destroy(rigid);
        }
        foreach (var fragment in fragments)
        {
            fragment.gameObject.AddComponent<Rigidbody>();
        }
        isDecomposition = true;
    }
}

}

このプログラムもやりたいことはさっきのやつとあんまり変わらないです。ダメージが入ったときにfragmentに物理演算をさせたいということです。 というわけで最後はfragmentのプログラムですね。

public class Fragment : MonoBehaviour {

public Structure structure;
public Fragment fragment;

// Use this for initialization
void Start()
{

}

public void Initialize(Structure structure)
{
    this.structure = structure;

}
/*ダメージを受けたときの大元*/
public void Impact(Fragment fragment)
{
    if (GameSystemController.Instance.IsPlaying)
    {
        structure.Damaged();
    }
}

public void Collapse()
{
    gameObject.AddComponent<Rigidbody>();
}

}

このプログラムがものを分解するときの一番小さいfragmentになります。そのため、先ほどのように子を取得する必要はないです。ただし、新しく、impactというメソッドがでてきました。これは先ほどからの「ダメージを受けたとき」っていうやつの大元になってきます。ダメージの判定とかに関しては、先輩が作ったメソッドを読んでるだけなので詳しいことはよくわかりません!!

これらの3つのプログラムで一番ややこしいところは、メソッドがダメージから分解までにあっちこっちに飛んで行ってます。

最初のダメージの大元は先ほどの通り、このImpactメソッドです。これがダメージを受けると、今度は、structureのDamagedメソッドに飛んで行きます。

さらに、structureのDamagedかdestructthingのDamagedを呼びつつ、自身のcollapseメソッドを呼びます。

先にcollapseを解決しましょう。分解のフラグが0(false)の場合、自身の物理演算をやめつつ、したのfragmentに物理演算をするようにします。このとき、fragmentはlistに格納されているため、foreachで回し、全てのfragmentに物理演算をさせるようにします。これらを終えると、分解のフラグを1(true)にしてひと段落、、、 かと思いきや、まだ、destructthingのDamagedメソッドがあります。ただし、実際にやってることはstructureのDamagedと変わらないので説明は省略します。 これで全てのプログラムが終わりました。

最初に書いたように、c♯の勉強はやればやるほどわからない’ことが増えて行って、混乱してます。 この解説も多分おかしいことも言っていると思いますし、自分でも、まだ完全には理解できてない部分もあります。 ただ、これからもちょっとずつわからないことを、潰して、増やしてを繰り返していけたらいいと思いました。(小並感)

会津大学VR部の部員が持ち回りで投稿していくブログです。特にテーマに縛りを設けずに書いていきます!