■基本的な仕組み
接近攻撃は「敵の遠隔攻撃②」で作成した発射位置のオブジェクトを流用した。接近攻撃のアニメーションを再生するとオブジェクトも連動して動くので、このコライダーでプレイヤーとの接触判定を行う。また、このオブジェクトは普段は非アクティブにしておき、攻撃アニメーション中だけアニメーションイベントでアクティブになるようにしておく。
なお、このコライダーは単なる当たり判定なので、これまで同様コライダーのIsTriggerとRigidBodyのIsKinematicにチェックを入れておく。
■スクリプト (手のオブジェクトにアタッチ)
- 基本的には弾丸のときと同じ処理だが、初速を与えて飛ばす必要がないのでシンプル
- 弾丸と違いプレハブを生み出す必要がないので、Inspectorから直接参照をしている。ただし、敵そのものをプレハブ化する場合は、やはりFindWithTagなどで参照する必要がある。最終的にはプレハブ化に対応させて30秒ごとに増えるようにした。(>>最新版の全スクリプト(Github))
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 PunchBehaviour : MonoBehaviour { | |
public float time_Destroy = 0.5f; | |
public LifeManager lifeManager;//このオブジェクトはHierarchyに常に存在するので直接参照可能 | |
public GameObject attacker; | |
private string attackerTag; | |
void Start(){ | |
attackerTag = attacker.tag; | |
} | |
void OnTriggerEnter(Collider other){ | |
//ヒット先が発射元の陣営の場合は何もせず処理を終了 | |
if(other.tag == attackerTag){return;} | |
//プレイヤーの場合はダメージ処理 | |
if(other.tag == "Player"){ | |
//一度に2ダメージ | |
lifeManager.Damage(); | |
lifeManager.Damage(); | |
} | |
} | |
} |
■スクリプト(敵の親オブジェクトにアタッチ)
「敵の遠隔攻撃②」と同じもの。距離に応じて呼び出すアニメーションを変える。
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 EnemyAttack : MonoBehaviour { | |
public float range_punch = 1f; | |
public float range_shooting = 10f; | |
public float interval = 3f; | |
public AudioSource soundPunch; | |
public AudioSource soundShoot; | |
public GameObject bulletPrefab; | |
public GameObject hand; | |
public Transform targetCenterPos; | |
private float intervalCounter = 0; | |
private Animator animator; | |
private GameOverManager gameOverManager; | |
// Use this for initialization | |
void Start () { | |
//HierarchyからGameOverManagerを見つけて代入 | |
GameObject manager = GameObject.FindWithTag("Manager"); | |
gameOverManager = manager.GetComponent<GameOverManager>(); | |
//アニメーターの取得 | |
animator = GetComponent<Animator>(); | |
} | |
// Update is called once per frame | |
void Update () { | |
//古いトリガーをオフにする | |
animator.ResetTrigger ("Attack1Trigger"); | |
animator.ResetTrigger ("Attack2Trigger"); | |
//ゲームオーバーの監視 | |
if(gameOverManager.IsCalled){return;} | |
//インターバルの更新 | |
CounteInterval (); | |
//攻撃の処理 | |
Search (); | |
} | |
void CounteInterval(){ | |
intervalCounter += Time.deltaTime; | |
intervalCounter = Mathf.Clamp (intervalCounter, 0f, interval); | |
} | |
void Search (){ | |
//プレイヤーに向けてレイを飛ばす | |
Ray ray = new Ray(transform.position, transform.forward); | |
RaycastHit hit; | |
if (Physics.Raycast (ray, out hit, range_shooting)) { | |
//レイの当たったコライダーがPlayerの場合(=射線が確保されている) | |
if (hit.collider.tag == "Player") { | |
Attack (hit.collider.transform.position); | |
} | |
} | |
} | |
void Attack(Vector3 playerPos){ | |
//プレイヤーとの距離で攻撃手段を変更 | |
if(Vector3.Distance(transform.position, playerPos) < range_punch){ | |
//パンチ攻撃 | |
animator.SetTrigger ("Attack2Trigger"); | |
}else{ | |
//インターバルを確認 | |
if(intervalCounter == interval){ | |
//射撃攻撃 | |
animator.SetTrigger ("Attack1Trigger"); | |
//インターバルのカウントをリセット | |
intervalCounter = 0f; | |
} | |
} | |
} | |
//霊夢パンチ(AnimationEventで呼び出す) | |
public void ReimuPunch(){ | |
//エフェクトと判定をアクティブにする | |
hand.SetActive (true); | |
} | |
//ReimuPunchで使用 | |
public void SoundPunch(){ | |
//効果音 | |
soundPunch.Play (); | |
} | |
//ReimuPunchで使用 | |
public void ResetPunch(){ | |
//非アクティブに戻す | |
hand.SetActive (false); | |
} | |
//霊夢ショット(AnimationEventで呼び出す) | |
public void ReimuShoot(){ | |
//効果音 | |
soundShoot.Play (); | |
//発射座標から目標座標への回転ベクトルを作成 | |
Vector3 direction = targetCenterPos.position - hand.transform.position; | |
Quaternion rotation = Quaternion.LookRotation(direction); | |
//オブジェクトの生成 | |
GameObject bullet = Instantiate (bulletPrefab, hand.transform.position, rotation) as GameObject;//<! 情報を渡したいのでインスタンス化 | |
bullet.GetComponent<BulletBehaviour>().SetShooterTag(tag); | |
} | |
} |
0 件のコメント:
コメントを投稿