Unity3Dで3D脱出ゲームの作り方、パート2(プレイヤーの設定、アニメーション、Hash IDの使い方、HPの状態)

Unity3Dで3D脱出ゲームの作り方、パート2です。
パート2で作成するプレイヤーを操作するためのスクリプトが若干だいぶよくわからないのですが、わかったつもりで進めてしまいましょう!

プレイヤーの設定

Unity: Stealth – Player Setup

Modelsのchar_ethanをシーンビューにドロップしてTagをPlayer、Position X:-2.5 Y:0 Z:0に変更する。
char_ethanオブジェクトを展開してchar_ethan_skeletonオブジェクト以外の子要素を選択してUse Light Probesにチェックを入れる。

char_ethanオブジェクトにCapsule Colliderを追加してCenter X:0 Y:1 Z:0、Radius 0.4、Height 2に変更する。続けてRigidbodyを追加してConstraintsのFreeze Position YとFreeze Rotation X,Y,Zにチェックを入れる。続いてAudio Sourceを追加してAudio Clipにplayer_footstepsをアタッチして、Play On Awakeのチェックをはずし、Loopにチェックし、Volumewo0.1に変更する。

main_cameraのAudio Listenerを削除する。
char_ethanオブジェクトにAudio Listenerを追加する。

プレイヤーのアニメーション

Unity: Stealth – Player Animator Controller

AssetsのAnimatorsフォルダを選択してAnimator Controllerを作成してPlayerAnimatorという名前に変更します。
Animatorビューを選択して、ParametersにFloatでSpeed、BoolでDeadとSneakingとShoutingを追加します。
AssetsのAnimationsフォルダを選択してhumanoid_idleを展開し、IdleをAnimatorビューにドロップします。

char_ethanオブジェクトを選択して、PlayerAnimatorをchar_ethanオブジェクトのAnimator Controllerにドロップします。

Animatorビューを選択して右クリックをしてCreate StateからBlend Treeを作成します。Blend TreeをLocomationという名前に変更してLocomationをダブルクリックします。そこに表示されるBlend Treeという名前をLocomationに変更します。
Inspectorにあるプラスのマークを押してAdd Motion Fieldを選択します。さらにもう一度Add Motion Fieldを選択します。
続けてInspectorにある丸ポチのマークを押してWalkを選択します。同じくもう1つの丸ポチを押してRunを選択します。Automate Thresholdのチェックをはずして、Compute ThresholdsをSpeedに変更します。

Base Layerに戻ります。
IdleからLocomationへTransitionを作成します。
TransitionのConditionsをSpeed Greater 0.1、Sneaking falseにします。

LocomationからIdleへTransitionを作成します。
TransitionのConditionsをSpeed Less 0.1にします。

AssetsのAnimationsのHumanoidのhumanoid_sneakを展開してSneakをAnimatorビューにドロップします。
LocomationからSneakへTransitionを作成します。
TransitionのConditionsをSpeed Greater 0.1、Sneaking trueにします。
SneakからLocomationへTransitionを作成します。
TransitionのConditionsをSpeed Greater 0.1、Sneaking falseにします。

SneakからIdleへTransitionを作成します。
TransitionのConditionsをSpeed Less 0.1にします。
IdleからSneakへTransitionを作成します。
TransitionのConditionsをSpeed Greater 0.1、Sneaking trueにします。

AssetsのAnimationsのHumanoidのhumanoid_dyingを展開してDyingをAnimatorビューにドロップします。
Any StateからDyingへTransitionを作成します。
TransitionのConditionsをDead trueにします。

AssetsのAnimatorsを選択してAvatar Maskを作成してPlayerShoutingMaskという名前に変更します。
PlayerShoutingMaskのInspectorのHumanoidを展開して頭と向かって右側の手と腕とIKというのを緑色にして後は赤にします。

Animatorビューを選択してShoutingという名前でLayerを追加します。ShoutingレイヤーのMaskにはPlayerShoutingMaskを指定します。
Empty State(New State)を作成して、AssetsのAnimationsのHumanoidのhumanoid_shoutを展開してShoutをドロップします。
New StateからShoutへTransitionを作成してConditionsをShouting trueにします。
ShoutからNew StateへTransitionを作成します。

Hash IDの使い方

Unity: Stealth – HashIDs

HierarchyのgameControllerを選択してHashIDsというC#スクリプトを追加して編集します。

using UnityEngine;
using System.Collections;

public class HashIDs : MonoBehaviour {
	public int dyingState;
	public int deadBool;
	public int locomotionState;
	public int shoutState;
	public int speedFloat;
	public int sneakingBool;
	public int shoutingBool;
	public int playerInSightBool;
	public int shotFloat;
	public int aimWeightFloat;
	public int angularSpeedFloat;
	public int openBool;

	void Awake(){
		dyingState = Animator.StringToHash ("Base Layer.Dying");
		deadBool = Animator.StringToHash ("Dead");
		locomotionState = Animator.StringToHash ("Base Layer.Locomotion");
		shoutState = Animator.StringToHash ("Shouting.Shout");
		speedFloat = Animator.StringToHash ("Speed");
		sneakingBool = Animator.StringToHash ("Sneaking");
		shoutingBool = Animator.StringToHash ("Shouting");
		playerInSightBool = Animator.StringToHash ("PlayerInSight");
		shotFloat = Animator.StringToHash ("Shot");
		aimWeightFloat = Animator.StringToHash ("AimWeight");
		angularSpeedFloat = Animator.StringToHash ("AngularSpeed");
		openBool = Animator.StringToHash ("Open");
	}
}

プレイヤーの動き

Unity: Stealth – Player Movement

char_ethanオブジェクトを選択してPlayerMovementという名前でC#スクリプトを作成して編集します。

using UnityEngine;
using System.Collections;

public class PlayerMovement : MonoBehaviour {
	public AudioClip shoutingClip;
	public float turnSmoothing = 15f;
	public float speedDampTime = 0.1f;

	private Animator anim;
	private HashIDs hash;

	void Awake(){
		anim = GetComponent<Animator>();
		hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
		anim.SetLayerWeight (1,1f);
	}

	void FixedUpdate(){
		float h = Input.GetAxis ("Horizontal");
		float v = Input.GetAxis ("Vertical");
		bool sneak = Input.GetButton ("Sneak");

		MovementManagement (h, v, sneak);
	}

	void Update(){
		bool shout = Input.GetButtonDown ("Attract");
		anim.SetBool (hash.shoutingBool, shout);
		AudioManagement (shout);
	}

	void MovementManagement(float horizontal, float vertical, bool sneaking){
		anim.SetBool (hash.sneakingBool, sneaking);

		if (horizontal != 0f || vertical != 0f) {
			Rotating (horizontal, vertical);
			anim.SetFloat (hash.speedFloat, 5.5f, speedDampTime, Time.deltaTime);
		} else {
			anim.SetFloat(hash.speedFloat, 0f);
		}
	}

	void Rotating(float horizontal, float vertical){
		Vector3 targetDirection = new Vector3 (horizontal, 0f, vertical);
		Quaternion targetRotation = Quaternion.LookRotation (targetDirection, Vector3.up);
		Quaternion newRotation = Quaternion.Lerp (rigidbody.rotation, targetRotation, turnSmoothing * Time.deltaTime);
		rigidbody.MoveRotation (newRotation);
	}

	void AudioManagement(bool shout){
		if (anim.GetCurrentAnimatorStateInfo (0).nameHash == hash.locomotionState) {
			if (!audio.isPlaying) {
				audio.Play ();
			}
		} else {
			audio.Stop ();
		}

		if (shout) {
			AudioSource.PlayClipAtPoint(shoutingClip, transform.position);
		}
	}
}

char_ethanオブジェクトを選択してInspectorのPlayer Movement(Script)のShouting Clipにplayer_attractAttentionを指定します。

AnimatorビューのBase LayerのSneakを選択してSpeedを1.7にするとSneakが速くなります。

プレイヤーのHP状態

Unity: Stealth – Player Health

char_ethanオブジェクトを選択してPlayerHealthという名前でC#スクリプトを作成して編集します。

using UnityEngine;
using System.Collections;

public class PlayerHealth : MonoBehaviour {
	public float health = 100f;
	public float resetAfterDeathTime = 5f;
	public AudioClip deathClip;

	private Animator anim;
	private PlayerMovement playerMovement;
	private HashIDs hash;
	//private SceneFadeInOut sceneFadeInOut;
	private LastPlayerSighting lastPlayerSighting;
	private float timer;
	private bool playerDead;

	void Awake(){
		anim = GetComponent<Animator>();
		playerMovement = GetComponent<PlayerMovement> ();
		hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
		lastPlayerSighting = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<LastPlayerSighting>();
	}

	void Update(){
		if(health <= 0f){
			if(!playerDead){
				PlayerDying();
			} else{
				PlayerDead();
				LevelReset();
			}
		}
	}

	void PlayerDying(){
		playerDead = true;
		anim.SetBool (hash.deadBool, true);
		AudioSource.PlayClipAtPoint (deathClip, transform.position);
	}

	void PlayerDead(){
		if(anim.GetCurrentAnimatorStateInfo(0).nameHash == hash.dyingState){
			anim.SetBool(hash.deadBool, false);
		}

		anim.SetFloat (hash.speedFloat, 0f);
		playerMovement.enabled = false;
		lastPlayerSighting.position = lastPlayerSighting.resetPosition;
		audio.Stop ();
	}

	void LevelReset(){
		timer += Time.deltaTime;
		if(timer >= resetAfterDeathTime){
			// no fading scene available
		}
	}

	public void TakeDamage(float amount){
		health -= amount;
	}
}

SceneをFadeさせるための機能は省略しています。

使い方に慣れてはきたけど、いまだに新しいやり方やら何やらで理解が追いついていません!
やったことがあるというのが大切なんです、たぶん・・。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください