こんにちは。皆様年末如何お過ごしでしょうか。
僕は土日フル出勤&毎日深夜3時過ぎに帰ってきて、10時に出社するという生活で、なんか最後の方は楽しかったです。
しかし個人開発やる時間がほぼ取れず、たまに取れた日曜午前休みとかで進めていた内容しかありません。

メモ書きですので、この記事にて一気に書きます。

内容は下記です。

■ゲームの雰囲気をトゥーン調にする
■カメラ指定した対象に追従させる
■キャラクターのステータス管理
■HPバーの作り方
■パーティクルの出し方
■オブジェクトの画面外判定
■その他結構ハマった事



■ゲームの雰囲気をトゥーン調にする
流行っていたり、個人的に好きなので、トゥーン調(アニメ調)の雰囲気のゲームが作りたかったのですが、リソースができないとか、アセット使おうにも種類が少なかったりして断念していました。

そこで、そういう雰囲気に最初から作られている物でなくても、マテリアルとシェーダーの設定で後からそういう雰囲気にできるのでは?と試してみました。

結果的にはデフォルトのトゥーンシェーダーと環境光の設定で割と簡単に行けると判断しました。
(今作ってるゲームはこの方法で行こうと思っています)

<具体的なやり方>
デフォルトのトゥーンシェーダーは
toon/basic 環境光が反映されないやつ
toon/lit 環境光反映される
の2パターンがすでに用意されているのですが、ポイントは下の方(toon/lit)を使って、それに加えて環境光をいじることです。

環境光の設定は
window >Lighting
 Environment Lighting>Source を Colorにして色を白系で良い感じに見える色に設定します
(昔のUnityだとEdit>Render Setting)

before

after(※地形のモデルは元からトゥーン調、メインキャラと敵キャラを見てほしい)

これでリアル系のアセットも雰囲気統一してトゥーン調にできて良いと個人的には思ってます。
(元からトゥーンな雰囲気のモデルが用意できればそれが一番いいんですが)



そろそろ年賀状書かなきゃいけないので以下駆け足で書きます。


■カメラ指定した対象に追従させる
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;

  4. public class CameraCtrl : MonoBehaviour {
  5.     //追従対象
  6.     public GameObject _target;
  7.     //カメラを滑らかに追従するか
  8.     public bool _is_smooth = false;
  9.     //カメラとターゲットの距離比率
  10.     public float _offset = 1.0f;

  11.     private Vector3 offset = Vector3.zero;

  12.     
  13.     void Start() {
  14.         if (!_target) {
  15.             Debug.Log("カメラの追従対象が設定されていません");
  16.         }

  17.         offset = transform.position - _target.transform.position;
  18.         offset *= _offset;
  19.     }

  20.     void LateUpdate() {
  21.         Vector3 newPosition = transform.position;
  22.         newPosition.x = _target.transform.position.x + offset.x;
  23.         newPosition.y = _target.transform.position.y + offset.y;
  24.         newPosition.z = _target.transform.position.z + offset.z;

  25.         if (_is_smooth) {
  26.             transform.position = Vector3.Lerp(transform.position, newPosition, 5.0f * Time.deltaTime);
  27.         } else {
  28.             transform.position = newPosition;
  29.         }

  30.     }
  31. }

offset値を入れることで、距離感の調整も可能



■キャラクターのステータス管理

ゲーム作りの基本的な手法なのですが、キャラクターのステータスを管理するキャラステクラスを作り、ステータスを持つオブジェクトにアタッチさせます。
これはなるべく汎用的に、敵と味方で分けたりはせずに共通で使えるように作ります。

  1. public class CharaStatus : MonoBehaviour {
  2.     public int MaxHP = 10;
  3.     public int HP = 10;
  4.     public float Speed = 1.0f;
  5.     public int Power = 4;

  6.     public void Damage(int _var) {
  7.         HP -= _var;
  8.         HP = HP < 0 ? 0 : HP;
  9.     }


  10.     public void Heal(int _var) {
  11.         HP += _var;
  12.         HP = MaxHP < HP ? MaxHP : HP;
  13.     }

  14.     public float GetHpPer() {
  15.         return (float)HP / (float)MaxHP;
  16.     }

  17. }

例えばこんな感じで持たせておくと、これをアタッチするだけでステータス系の管理ができるようになります。
ダメージ与えたかったらこれのDamage()を呼ぶだけみたいな。



■HPバーの作り方

GameObject > Canvas > Slider
という構成で作り、このGameObjectをキャラの子にしてやればOK

CanvasのインスペクタビューにあるCanvasコンポーネントのRenderModeをWorldSpaceに変更する
後はスケールを調整し、邪魔な〇を消したりする。

くっつけたキャラと一緒に回転してしまうので、
GameObjectに付けたスクリプトで、常にカメラ側を向くようにする

  1.     void Update() {
  2.         //常にカメラを向くようにする
  3.         //(プレイヤーから見たカメラは若干ずらしてるから、upベクトルとしてカメラのupを指定してる)
  4.         transform.LookAt(camera.transform.position, -camera.transform.up);
  5.         //transform.LookAt(camera.transform.position, camera.transform.up);

  6.     }


  7.     public void SetHpPer(float _per) {
  8.         _slider.value = _per;
  9.     }
LookAtの第二引数にカメラのUpベクトルを指定しています。


■パーティクルの出し方
1つのパーティクルで構成されるParticleSystemであったら、
particle_explosion = particle_explosion_obj.GetComponent<ParticleSystem>();
単純にPlayとStopでいける。
何回も使うのはインスタンス1つ作って、
particle_explosion.Play();
particle_explosion.Stop();
でやるのが良さげ。

複数のパーティクルを内包した感じになっているのは、
パーティクルを梱包したGameObjectを生成してすぐ消す
GameObject explObj = Instantiate(particle_explosion_obj, _target.transform.position, _target.transform.rotation);
Destroy(explObj, 1.0f);

それか、先のPlay/Stopの方法を、子オブジェクト全てに対して行えばOK。
使用頻度によるかな。



■オブジェクトの画面外判定
画面外に出たら
  1. void OnBecameInvisible() {
  2. }
が呼ばれる

ただしRendererコンポネートをアタッチしておく必要がある



■その他結構ハマった事
Inspector の 名前の右にあるstatic にチェックが入ってると、rigitbodyとかcolliderとかアタッチしても効かない

メインキャラにIsKinematicは、マップのコリジョンとうまく共存できなくなるからやめた方が良い


なんと今回わたくし3連休を頂いております。
それでは皆さん、また来年もゲーム作りを楽しみましょう!