💬

[Unity] 前方に球を飛ばす魔法攻撃の実装

2022/03/27に公開

[Unity] 前方に球を飛ばす魔法攻撃の実装

行いたいこと

・RPGの主人公が行う魔法攻撃を実装したい。
・主人公の目の前に球を出現させ、前方に発射したい。
・球が出現してから1秒後に破壊、もしくは、敵に衝突したら破壊したい。
・上記のことを攻撃ボタンを押下したら、行うようにしたい。

事前準備

1) Assetのimport

importするAssetはお好みのもので問題ないですが、私は以下のAssetをimportしました。

・Player
https://assetstore.unity.com/packages/3d/characters/animals/dog-knight-pbr-polyart-135227

・発射させたいprefab
https://assetstore.unity.com/packages/vfx/particles/fire-explosions/fire-spell-effects-36825

<確認事項>
・Project/Assets配下にDogKnightが配置されたこと。
・Project/Assets配下にPyroParticlesが配置されたこと。

2) Prefabの配置

・Playerの配置
Project>Assets/DogKnight/Prefab/DogPolyart.prefabをHierarchyに配置する。

・球の配置
a) Project>Assets配下にResourcesフォルダを作成。
(Assetsを右クリック > Create > Folder > 「Resources」と名前を付ける。)
b) Project>Assets/Resourcesフォルダ配下に「MagicPrefabs」フォルダを作成
c) Project/Assets/PyroParticles/Prefab/Prefab/Meteor.prefabを「ctrl + D」でコピー。
(「Meteor 1」が生成されたかと思います。)
d) Resources/MagicPrefabsフォルダ配下に、「Meteor 1」をドラッグ&ドロップする。
e) 「Meteor 1」の名前を、meteorに変更する。

ここまで出来たら、以下のようなフォルダ構成となっているかと思います。

3) Animationの準備

a) Project/Assets配下に「Animator」フォルダを作成。
b) Project/Assets/Animator配下にPlayerAnimatorControllerを作成。
(Project/Assets/Animatorを右クリック > Create > AnimatorControllerをクリック)
c) PlayerAnimatorControllerをダブルクリック。
d) Aniamatorの画面にAssets/DogKnight/Animations配下のAnimationをドラッグ&ドロップ。
e) 以下の配置してください。

(今回必要な部分は「Entry」「Idle_Battle」「Attack01」だけですが、
 他の部分は気にしないでください...)
f) 「Idle_Battle」→「Attack01」には「Attack」triggerを設定。
g) 「Idle_Battle」←「Attack01」には何も設定しません。

以上で事前準備は終了です。
それでは、コーディングをバシバシやっていきましょう!!

ソースコード

これからは、プレハブの生成、発射、破壊をコーディングしていきます。
作成するソースファイルは3つです。

PlayerManager.cs

Playerにアタッチするソースファイルです。
左クリックを検知したら、Idel_BattleからAttack01に遷移するようにします。

PlayerManager.cs
using UnityEngine;
using UnityEngine.Animations;

public class PlayerManager : MonoBehaviour
{
    Animator animator;                  // PlayerのAniamtor
    Rigidbody rb;                       // PlayerのRigidbody

    void Start()
    {
        animator = GetComponent<Animator>();    // PlayerのAnimatorを取得
    }
    
    void Update()
    {
        playerAttack();
    }
    
    private void playerAttack()
    {
        if (Input.GetButtonDown("Fire1"))    //左クリックされたら
        {
            animator.SetTrigger("Attack");   // 「Attack」Triggerをonにする
        }
    }

PlayerAttBehaviour.cs

AnimationClipのAttack01にアタッチするソースファイル。
本ソースファイルは普通に作成する方法とは違い、以下の方法で作成する。
「Attack01」をクリック > Add Bhaviour > New Scripts > 「PlayerAttBehaviour」と入力

PlayerAttBehaviour.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAttBehaviour : StateMachineBehaviour
{
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        // 生成したいプレハブをResources/MagicPrefabs配下のプレハブを指定する。
        GameObject shotObject = (GameObject)Resources.Load("MagicPrefabs/Meteor");

        // プレハブの生成場所を指定する。(今回はPlayerのポジションを指定)
        Vector3 playerPos = animator.GetComponent<Transform>().position;

        // プレハブの生成
        GameObject shot = Instantiate(shotObject, playerPos, Quaternion.identity);

        // キャラクターオブジェクトを取得
        GameObject playerGameObj = animator.GetComponent<PlayerManager>().gameObject;

        // PlayerMagicAtt.csのSetObject()を呼び出し
        shot.GetComponent<PlayerMagicAtt>().SetObject(playerGameObj, shot);
    }

PlayerMagicAtt.cs

Resources/MagicPrefabs/Meteorプレハブにアタッチするソースファイルです。

PlayerMagicAtt.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMagicAtt : MonoBehaviour
{
    public float shot_speed = 1000;
    protected Vector3 forward;
    protected Rigidbody rb;
    protected GameObject characterObject;
    private GameObject attPrefab;

    void Start()
    {
        rb = this.GetComponent<Rigidbody>();            // プレハブのRigidbodyを取得
        forward = characterObject.transform.forward;    // Playerの前方を取得
        Destroy(this.attPrefab, 1f);                    // プレハブを1秒後破壊
    }

    void Update()
    {
        rb.velocity = forward * shot_speed;        // プレハブを移動させる
    }

    // 球のis triggerのチェックを外す
    // Enemyのis triggerのチェックを外す
    private void OnTriggerEnter(Collider other)
    {
        Debug.Log("衝突しました。");
        // 敵に衝突したら、プレハブを破壊
        if (other.gameObject.CompareTag("Enemy"))
        {
            Destroy(attPrefab);
        }
    }

    // Playerと生成されたプレハブのGameObjectのセッター
    public void SetObject(GameObject characterObject, GameObject attPrefab)
    {
        this.characterObject = characterObject;
        this.attPrefab = attPrefab;
    }

Inspector

・各ソースファイルをアタッチする。
  PlayerManager.cs ⇒ Player
  PlayerAttBehaviour.cs ⇒ Attack01(既にアタッチされていると思います)
  PlayerMagicAtt.cs ⇒ Meteor

・Meteorの「Sphere Collider」の「Is Trigger」にチェックを入れる。

・各prefabのInspectorは以下のようにしてください。

<Player>
DogKnightをHierarchyに配置してください。(Unpack Completlyも行ってください。)

<Enemy>
Enemyは適用に用意してください。(Playerと全く同じprefabでも問題ありません。)
(Unpack Completlyも忘れずに!)

<球prefab>

以上でMeteorプレハブを生成してPlayerの正面に発射し、1秒後に消滅するかと思います。

Discussion