【UnityC#講座】ユニティちゃんにパンチさせる


Unity2019.2.2f1
Windows10

ユニティちゃんパンチ/トップ

【UnityC#講座】3D人型モデルを三人称視点で動かす操作を改良

今回はこの記事の続きとしてユニティちゃんにパンチをさせます。
そして次回は操作するユニティちゃんとNavMeshAgentで動くユニティちゃんで殴り合いをさせるのでその準備もします。

■AnimatorControllerの設定をする

アニメーションクリップ

攻撃モーションとダメージモーションを追加します。
ダメージモーションは今回使いませんが、次回使うのでついでに設定しておきます。
ユニティちゃんのフォルダの中からPOSE30DAMAGED00をアニメーションクリップを見つけてAnimatorControllerにドラッグしてください。

攻撃モーション
Project > Assets > unity-chan! > Unity-chan > Art > Animation > unitychan_ARpose2 Impo > POSE30

ダメージモーション
Project > Assets > unity-chan! > Unity-chan > Art > Animation > unitychan_DAMAGED00 In > DAMAGED00

そうすると長方形のアイコン、StateができるのでInspectorから名前をAttackとDamageに替えます。

ユニティちゃんパンチ/名前をAttack

Transition

そしてStateを左クリックで選択してから右クリック、Make Transitonをし、他のStateを左クリックすることでつなげます。
画像のようにしてください。

ユニティちゃんパンチ/AnimatorController

Blend Tree ←→Attack
Blend Tree ←→Damage
Attack → Damage

Blend TreeはAttackとDamageの両方と互いにTransition(矢印付きの線)を張り、AttackからDamageは一方通行です。

Parameters

次はParametersを設定しましょう。
AnimatorControllerの左上のParametersを選択、そして+ボタンをクリックし、Boolを選択します。
それでまたAttackとDamageの2つを作ってください。

ユニティちゃんパンチ/Parameters

Transitionの設定

次はTransitionの設定です。
Transitionをクリックし、HasExitTimeのチェックを外し、Conditionsの設定をします。

ユニティちゃんパンチ/Transition/Inspector/HasExitTime、Conditions

Conditionsの+ボタンを押し、それからそれぞれ以下のようにします。

Blend Tree → Attack Attack/True
Blend Tree ← Attack Attack/False
Blend Tree → Damage Damage/True
Blend Tree ← Damage Damage/False
Attack → Damage Damage/True

Blend Treeから行くのがTrueで戻るのがFalseです。
AttackからDamageに行くのは攻撃中に攻撃を受けた時のためです。

■アニメーションイベントの設定をする

アニメーションイベントはアニメーション中の特定のタイミングでメソッドを呼び出したりできる機能です。
まずはPOSE30のアイコンをクリックし、InspectorからEdit、Eventsとたどり設定します。
StateのMotion欄のPOSE30をクリックするとすぐにPOSE30にたどりつけます。

ユニティちゃんパンチ/POSE30/アイコン

ユニティちゃんパンチ/POSE30/Edit

ユニティちゃんパンチ/POSE30/アニメーションイベント

Eventsという文字の下のアイコンをクリックし、出てきた棒をメソッドを呼びたい時間に置きますが、後で調整できるので適当でいいです。
そしてFunctionの欄にAttackEndと入れてください。
最後にApplyをクリックして完了です。

Damageも同じように設定しDamageEndと入れてください。

ユニティちゃんパンチ/DAMAGED00/アニメーションイベント

■攻撃判定のオブジェクトを設置する

次は攻撃が相手に当たったことを判定するオブジェクトを設置します。
これもパンチさせるだけならいらないのですが、次回の殴り合いのために作っておきましょう。

まずの空のオブジェクトを出し名前をAttackPointにします。

Hierarchy > Create > Create Empty

次はTagを設定します。
InspectorのTagからPlayerAttackEnemyAttackを作ります。

Tag > Add Tag > Tags > +

ユニティちゃんパンチ/AttackPoint/Tag

ユニティちゃんパンチ/AttackPoint/Add Tag

+ボタンを押してTagの名前を付けてください。
そして戻ってPlayerAttackを選びます。
EnemyAttackは次回使います。

次はそれをユニティちゃんの右手のアーマチュア(アニメーションするための骨組み)の子オブジェクトにします。
混み入っていて面倒ですが頑張りましょう!

Hierarchy > unithchan > Charaster1_Reference > Charaster1_Spine > Character1_Spine2 > Charaster1_RightShoulder > Character1_RightArm > Character1_RightHand

ユニティちゃんパンチ/AttackPoint配置

ちなみにCreate横の検索欄に名前をコピペすれば簡単にたどりつけます。

ユニティちゃんパンチ/Hierarchy検索

次はAddComponentでSphereColliderを入れます。
位置はXYZのPositionがすべて0で良いです。
円の大きさ、Radiusは0.2にしましたが別に何でもいいです。
そしてIsTriggerにチェックを入れることを忘れないでください。

ユニティちゃんパンチ/右手にAttackPoint

ユニティちゃんパンチ/SphereCollider/IsTrigger

スポンサーリンク

■スクリプトを設定する

最後はスクリプトを書いてアタッチし、そのInspectorを設定すれば出来上がりです。
前回書いたPlayerスクリプトに追加します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(Rigidbody))]
public class Player : MonoBehaviour
{
[SerializeField] float speed = 4f;
private Animator animator;
Transform cam;
Rigidbody rb;
CapsuleCollider caps;
//列挙型、Actionの部分は自分で名前つける
enum Action
{
Move,
Attack,
Damage
}
//列挙型の名前を型にして変数を宣言する
[SerializeField] Action action = Action.Move;
//攻撃判定のオブジェクトを入れる
[SerializeField]GameObject attackObj;
void Start()
{
animator = GetComponent<Animator>();
rb = GetComponent<Rigidbody>();
rb.constraints = RigidbodyConstraints.FreezeRotation;
cam = Camera.main.transform;
caps = GetComponent<CapsuleCollider>();
caps.center = new Vector3(0, 0.76f, 0);
caps.radius = 0.23f;
caps.height = 1.6f;
//攻撃判定のオブジェクトをしまっておく
attackObj.SetActive(false);
}
void Update()
{
//Action.Moveの時だけ移動できるようにする
if (action == Action.Move)
{
float x = Input.GetAxisRaw("Horizontal") * Time.deltaTime * speed;
float z = Input.GetAxisRaw("Vertical") * Time.deltaTime * speed;
animator.SetFloat("X", x * 50);
animator.SetFloat("Y", z * 50);
if (z > 0)
{
transform.rotation = Quaternion.Euler(new Vector3(transform.rotation.x,
cam.eulerAngles.y, transform.rotation.z));
}
else if (z < 0)
{
z = z / 1.5f;
}
transform.position += transform.forward * z + transform.right * x;
//マウスの左クリックでAction.Attackに変更する
if (Input.GetMouseButtonDown(0))
{
action = Action.Attack;
}
}
//Action.Attackの時だけ攻撃をする
else if (action == Action.Attack)
{
//パンチのアニメーションを出す
animator.SetBool("Attack", true);
//攻撃判定のオブジェクトを出す
attackObj.SetActive(true);
}
//Action.Damageの時だけダメージのアニメーションを出す
else if (action == Action.Damage)
{
animator.SetBool("Damage", true);
}
}
//TagがEenmyAttackのオブジェクトに当たるとAction.Damageになる
//Action.Damageの時に当たるとreturnでそれ以降何も起きない
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "EnemyAttack")
{
if (action == Action.Damage)
{
return;
}
else
{
action = Action.Damage;
}
}
}
//POSE30のアニメーションイベントで呼ばれる
//Invokeで指定した秒数の後にAttackEndAnimが呼ばれる
public void AttackEnd()
{
Invoke("AttackEndAnim", 0.5f);
}
//Action.Moveに戻す
//パンチアニメーションから移動アニメーションへ
//攻撃判定のオブジェクトをしまう
void AttackEndAnim()
{
action = Action.Move;
animator.SetBool("Attack", false);
attackObj.SetActive(false);
}
//DAMAGED00のアニメーションイベントで呼ばれる
//Action.Moveに戻す
//ダメージアニメーションから移動アニメーションへ
void DamageEnd()
{
action = Action.Move;
animator.SetBool("Damage", false);
}
}
view raw 45.cs hosted with ❤ by GitHub

列挙型(Enum)で移動、攻撃、ダメージの行動を分けるようにしました。
OnTriggerEnterでEnemyAttackのTagに当たるとダメージモードに切り替わるようにしています。
POSE30はアニメーションと言うよりも単なるポーズのようなのでInvokeで0.5秒後にAttackEndAnimメソッドを呼び攻撃モードを終えるようにしました。

仕上げはユニティちゃんにスクリプトをアタッチしていなければし、そしてInspectorからAttackPointを設定して出来上がりです。

ユニティちゃんパンチ/スクリプト/AttackPoint

さて、無事にパンチできたでしょうか?

今回はこれで終わります。

続きはこちらです。
【UnityC#講座】ユニティちゃんに殴り合いをさせる【NavMeshAgent】

■関連記事

【UnityC#講座】無料アセットでユニティちゃんに剣を振らせる

【UnityC#講座】無料アセットで一人称視点に剣を振らせる

ユニティちゃんライセンス

この作品はユニティちゃんライセンス条項の元に提供されています

スポンサーリンク

目次に戻る