■弾丸の作成
今回はCreateで作れるCubeをお札に見立てる。
画像をProjectに入れると、画像はTexture TyepがTextureとしてインポートされる。次にProjectでMaterialをCreateする。このMaterialのAlbedoの左にある四角いマスに、先ほどのTextureを入れると全面を画像で覆うMaterialがつくられる。
これを先ほどのCubeにアタッチする。すると6面全てにお札の画像が表示される。本来、お札の側面に画像は不要だが、厚みを薄くすると気にならなくなるのでこのまま使用する。シーン上で形を整えたらProjectに移し、プレハブにする。
お札がオブジェクトに接触したことを判定できるようにするため、プレハブにコライダーをアタッチする(CreateしたCubeには初めからBoxColliderが付いている)。また、このコライダーは弾丸として空間を移動することになるので、RigidBodyもアタッチする(「カメラワーク①」でこの話に触れた)。
■スクリプト(弾丸にアタッチ)
- StartでRigidbody.velocityを用いて初速を与える。これにより、このプレハブがInstantiateされたら直進するようにしておく
- このように、弾丸の移動にRigidbody(物理演算)を用いているため、IsKinematicにチェックを入れることはできない(これにより様々な制約が生じる。できれば他の方法で動かしたほうがいいかも)
- ステージかプレイヤーに当たったらDestroy(gameObject) し、それ以外のコライダー(発射元と同じタグの陣営、もしくはアイテム)は無視したいので、IsTriggerにチェック入れて、OnTriggerEnterで接触判定する
- isTriggerをONにしてOnTriggerEnterで弾丸をDestroyするのと、isTriggerをONにしてOnCollisionEnterで弾丸をDestroyするのは同じかと思っていたが、後者は物理的影響がちゃんと発生する。なお当たった相手は押されるのだが、質量を増やしても変化はなかった。
- ただし、isTriggerを使うと衝突箇所の検出が不可能になる。あくまで接触判定しか取れない。(参考)思いつく対策としては…。
- 弾丸の位置から接触位置を割り出す
- プレイヤーの位置=接触位置にする
- 弾丸の位置=接触位置にする
- プレハブのようにProjectで控えているオブジェクトは、InspectorからHierarchyのオブジェクトを参照することができない。そのため、Hierarchy上の情報はFindWithTagで取得したり、Publicを付けたメソッドで外部から受け渡しをする必要がある。(ここでは発射元のタグを外部からメソッドを通して受け取れるようにしている)
- このスクリプトは他の陣営の弾丸にも使える汎用的なものにしようとした。ただ、各陣営ごとにこのスクリプトを用意したほうが素直かもしれない。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
public class BulletBehaviour : MonoBehaviour { | |
public float speed = 20f; | |
public float time_Destroy = 2f; | |
private Rigidbody bulRig; | |
private string shooterTag; | |
private LifeManager lifeManager; | |
// Use this for initialization | |
void Start () { | |
//HierarchyからScoreManagerを見つけ、管理クラスをlifeManagerに代入 | |
GameObject manager = GameObject.FindWithTag("Manager"); | |
lifeManager = manager.GetComponent<LifeManager>(); | |
//進行方向の設定 | |
bulRig = GetComponent<Rigidbody> (); | |
bulRig.velocity = transform.forward * speed; | |
//指定時間経過で消えるようにしておく | |
Destroy(gameObject, time_Destroy); | |
} | |
public void SetShooterTag(string tag){ | |
//発射元のタグを受け取る | |
shooterTag = tag; | |
} | |
void OnTriggerEnter(Collider other){ | |
//ヒット先が発射元の陣営の場合は何もせず処理を終了 | |
if(other.tag == shooterTag){return;} | |
//ヒット先がアイテムの場合は何もせず処理を終了 | |
if(other.tag == "Item"){return;} | |
//プレイヤーの場合はダメージ処理 | |
if(other.tag == "Player"){lifeManager.Damage();} | |
//発射元以外に当たったので、この弾丸を消す | |
Destroy (gameObject); | |
} | |
} |
0 件のコメント:
コメントを投稿