アフィリエイト広告を利用しています

現在ははてなブログで投稿しています!

広告

この広告は30日以上更新がないブログに表示されております。
新規記事の投稿を行うことで、非表示にすることが可能です。
posted by fanblog

2017年08月02日

プレイヤーを動かす:関数の解説

なんか記事を分けるのが
面倒くさかったので関数はまとめて書きます。


やっぱ、一気に解説した方がいいのかな…?


というか、更新遅れてごめんなさい!
色々ありまして!はい、すみません!!

記事書いて、保存しようとしたら
ネットエラーが出て……。

結局保存されておらず
同じ部分を何回も書かされました……。

正直、めっちゃイラッときました!
今度からはネットが安定してる所で書こう…。
(やる気が一気に無くなります…)


……関数は、Start、FixedUpdate、Updateがあります。
順番に見ていきましょう。





Start関数


まず、Start関数はこれです!
void Start () {
 rb = this.gameObject.GetComponent<Rigidbody>();
 anim = this.gameObject.GetComponent<Animator>();
}

これはまぁ、Rigidbodyと
アニメーター(Animator)を取得して
使えるようにしてるだけなんですがね(笑)

GetComponent<取得したいコンポーネント>()

で「コンポーネント」が取得出来ます。


……コンポーネントについては、
またいつか ^_^;

近い内に記事を書きますね。
今のところはスルーでお願いします……
ごめんなさい m(_ _)m

2017/9/8 追記
コンポーネントについての記事を更新しました。
↓こちらからご覧下さい。

コンポーネントとは?


結果、「rb」には「Rigidbody」、
「anim」には「Animator」が
入っている事になるので
スクリプト内ではrbやanimと記述すれば
それぞれ Rigidbody 、 Animator が使えます。


FixedUpdate関数

void FixedUpdate () {
 //*****接地判定*****//
 if (Physics.SphereCast(this.gameObject.transform.position + new Vector3(0, 2f, 0), transform.lossyScale.x * 0.5f, Vector3.down, out hit, 2f)) {
  isGrounded = true;
 } else {
  isGrounded = false;
 }
 //*****************//
}



……なんか一行だけ
やたらと長いですが……。


まぁ、やってる事は
意外と簡単?かもしれません。




では、気を取り直して。


まず、FixedUpdateとは
何か、を説明していきましょうか。



FixedUpdateとは、
Updateよりも狭い間隔で呼ばれる関数
です。


どういう事かというと、
Updateよりも呼ばれる間隔が狭い…つまり、
Updateよりも先に呼ばれるという事ですね。


例を出すと、
Updateは一秒に一回呼ばれるとしましょう。
そうすると、FixedUpdateは0.5秒毎に
呼ばれる、みたいな感覚でしょうか。


もっと簡単に言えば、

FixedUpdate → Update

の順に更新され続ける!

と覚えて下さい(笑)


多分これで大体は合ってるかと…


話を戻しましょう。

それで、コメント化もしてありますが
FixedUpdateでは接地判定をしています。


大まかな流れとしては、
地面にキャラクターが着いているか
 h            h
 hはい         hいいえ
 ↓             ↓
isGround変数を   isGround変数を
 trueにする       falseにする

         ↓

  スクリプト内で「isGround」を使えば
    接地しているかどうかが扱える

こんな感じです。


この流れを、
FixedUpdateで処理しています。


if構文の使い方、
覚えていますか?


簡単に説明しますね。
if (条件) {
 ・・・条件が成り立つ時の処理・・・
} else {
 ・・・条件が成り立たない時の処理・・・
}


まぁ、これくらいは覚えていますよね!
……いますよね?


もし、「覚えていない!」という方は
こちらが制御構文の記事になります。

ご覧下さい。


それで、()の中が条件ですね。
その条件が一番がややこしいですが…。


まず、()内でやっている事を
軽く説明します。


使っているのは、
Physics.SphereCast()
というものです。


どういうものかと言うと、
仮想の球を飛ばしてその球が
  何かに当たるかどうか

を判定するものです。


指定した位置から、指定した方向に
向けて、指定した長さの分だけ
「仮想の球」を飛ばします。


飛ばすと言っても、
「バヒュッ」って感じでは
無くてですねー…

飛ばすというか、
伸ばすというか……。


………適当な語句が僕の
ボキャブラリーには無いので
動画のリンクを貼ります……。
そこでイメージを掴んで下さい…。



何か話がずれました、
Physics.SphereCast()は
仮想の球を飛ばすと言いましたが、
物理的な影響は一切ありません!

あくまでも「仮想」ですので、
判定のみに使う事が出来ます。


それをプレイヤーの位置から
下向きに飛ばしていき、
何かに着いたら「地面に着いている」と
判定する様にします。

無題2.png

ただ、普通に光線(Ray)も
使えるんですよ。

細い線をピーッっと飛ばしてですね、
判定も出来るんですよ。


何故使わないのかと言うと、
線なので細すぎるんですよ。

地面の端に行くと、
キャラクターが落ちなくても
「地面に乗っていない」と判定されて
しまう可能性があります。

↓こんな感じに
無題1.png

これを回避する為にわざわざ
仮想の球を使って判定する訳です!

どうです、面倒くさいでしょう?
でも、これが一番正確かと。

少し弱点もあるんですけどね…。
それは後で説明します!


では、Physics.ShereCast()の
()の中を説明していきましょう。
Physics.SphereCast(発射の原点, 仮想の球の半径, 発射する方向, 当たった物の情報, 最大距離)


上のを読めば大体分かると思います。

というか、丸っきりそのままです。


唯一、ん?と思うやつは
「当たった物の情報」ってやつですかね?


まぁこれもそのままなんですが、
「当たった物がオブジェクトか」や
「タグはGroundか」など、色々使えます。


ですが必ず必要なのが、
hitと言う変数を宣言しておく」事です。

変数の型は「RaycastHit」です。
(……確か)

覚えなくても生きていける予備知識を
下に少し書いておきます。

そこから「あ、そうなるんだ」というのを
探してみてください。
上のコードや、ここにある全コードを
見てもいいですね。



■予備知識■■■■■
変数 : RaycastHit hit;
記述 : out hit

変数 : RaycastHit _Hit;
記述 : out _Hit;
■■■■■■■■■■



()の中の一つ一つを見ていきましょう。
原点
 this.gameObject.transform.position
 ↑これでこのゲームオブジェクト(プレイヤー自身)の位置を取得し、
 それに new Vector3(0, 2f, 0)
 これ、「高さが2であとは全部0の三次元ベクトル」を足すことで、
 プレイヤー自身の位置より2だけ高い位置からRayを飛ばす様にします。

仮想の球の半径
 transform.lossyScale.x
 ↑これはプレイヤー自身の「横の」大きさですね。
 thisが付いていませんが、このオブジェクトを使っています。
 ……実は、thisとか要りません。
 分かり易くする為に書いているだけですので…。
 lossyScaleで大きさが取得出来るので、それの横、x を使っていますね。
 何故0.5を掛けて半分にしているか分かりますよね?
 プレイヤーの(横の)大きさに合わせるためですよ!
 ここで設定出来るのは「半径」なので、「プレイヤーの直径」に0.5を掛けて半分にし、半径として扱います!

発射する方向
 Vector3.down
 これは、三次元ベクトルの下、まぁつまりプレイヤーの向きに関係なく下向きに発射しろ、って事ですね。

当たった物の情報
 これはさっき少し説明したので良いかと思います。
 当たったオブジェクトの判定に使ったりします。

最大距離
 そのままですね。
 球が飛んでいける距離です。
 ここでは2fとしていますが、永遠に伸ばしていきたい時は
 Mathf.Infinity と記述すればいけますよ。
 (2f、別に f は要りません…)


無駄話が多すぎて長くなりましたが、
FixedUpdateをまとめましょう。

もう丸暗記、の方が早いです!

「ここをこうしとけば取り敢えずこうなる」

みたいな感じで!

今回で言うと、
if (Physics.SphereCast(this.gameObject.transform.position + new Vector3(0, 2f, 0), transform.lossyScale.x * 0.5f, Vector3.down, out hit, 2f)) {
 仮想の球が当たっている時の処理;
} else {
 仮想の球が当たっていない時の処理;
}


……完璧です。
もう言い残す事はありません……!




とまぁ、そんな感じで
地面に仮想の球が当たっている時は
isGroundedをtrueに、
当たっていない時はfalseにしているだけです。


FixedUpdateは以上になります。


Update関数

さて、いよいよ最後ですね。
疲れてきたので手短にいきます。
void Update() {
 if (isGrounded) {
  InputHorizontal = Input.GetAxis("Horizontal");
  InputVertical = Input.GetAxis("Vertical");
  InputMagnitude = new Vector3(InputHorizontal, 0, InputVertical);

  jumpPower = 30f;

  //*****移動*****//
  Cam_forward = Vector3.Scale(Cam.transform.forward, new Vector3(1, 0, 1)).normalized;

  move_forward = Cam_forward * InputVertical + Cam.transform.right * InputHorizontal;

  rb.velocity = move_forward * moveSpeed + new Vector3(0, rb.velocity.y, 0);

  //移動方向に向きを変える
  if (move_forward != Vector3.zero) {
   transform.rotation = Quaternion.LookRotation(move_forward);
  }
  //***************//
 }
}


文章でダラダラ書いていると
読みにくいと思うので、新しい
解説方法を試します!
まぁ、まとめ方をちょっと
簡単にするだけなんですが。
(↑どうでもいい)


if (isGrounded) { ・・・・・・ }
if構文は、()の中がtrueの時に実行
つまり、isGroundedがtrueの時
 ↓
接地している時に {} 内を実行する!
…………以上。

InputHorizontal = Input.GetAxis("Horizontal");
Input.GetAxis("Horizontal")で
「横方向のキーの入力」がfloat型で
取得出来ます!

横方向、というのは設定次第で
変わりますが…。
主に A, D キーや←→キーの事です。

それの入力を取得し、
InputHorizontal変数に入れています。

InputVertical = Input.GetAxis("Vertical");
これは上の横方向の入力の
縦バージョンです。

W, S キーや↑↓のキーの入力を
少数型で-1〜1の間で取得し、
InputVertical変数に入れています。

良ければ↓の動画も参考にして下さい。


InputMagnitude = new Vector3(InputHorizontal, 0, InputVertical);
「横の入力 + 0 + 縦の入力」で、
その値の三次元ベクトルを作成します。

「高さ」を制御する
キー入力は無いので、y軸は0です。

これはまた後日使います。

2017/9/13 追記
記事を見直したところ、
意味の分からない事が書いてあったので
↑を書き直しました。


jumpPower = 30f;
これはなんというか……
そのままですね。

jumpPower変数に30を
代入しているだけですね。

jumpPower変数は、確かfloat型で
宣言していました。

ですので30f、floatですね。
まぁ少数点が無いのでfは無くても
良いんですけどね(笑)

Cam_forward = Vector3.Scale(Cam.transform.forward, new (1, 0, 1)).normalized;
これは少し難しいですね。

・Vector3.Scale(a, b)
 a, bどちらとも三次元ベクトルが入り、
 その二つを掛け合わせた数を出します。
 つまり、a × bですね。

aには「カメラの正面を丸ごと」
bには「新しい(1, 0, 1)の三次元ベクトル」

これを掛け合わせるので、
「yだけが0」になるんです。

もしこれが無いと、
僕の場合「カメラの正面に向かって進む」
という処理をするので、
カメラが少しでも下に向いていたら
地面にめり込んで行く始末です。
無題3.png
ですのでyだけを0にし、
向き…ですかね?
を、正面に直しています。
無題4.png

・Vector3.normalized
 三次元ベクトルの向き(角度)は
 そのままで、長さのみを全て1に直します。


何故わざわざ値を1にするのか?
それは、使う目的にあります。

変数の名前からも分かる通り、
カメラの正面、というか
カメラの向きからプレイヤーが
進める向きを算出しますよね?

その為、必要なのは「向き」です。
長さは正直どうでも良いのです。

ま、ここだけですが。
要らないのは。

後に(次の行ですが)出てくる計算で使います!
ので、全て1にし、計算しやすくしています。

(参考に)


move_forward = Cam_forward * InputVertical + Cam.transform.right * InputHorizontal;
予め一つ一つを説明しておきます。
・move_forward ・・・ 進む方向を入れておく変数
・Cam_forward ・・・ 上で算出したプレイヤーが進む、カメラの正面
・InputVertical ・・・ 縦のキー入力
・Cam.transform.right ・・・ カメラの右
・InputHorizontal ・・・ 横のキー入力

これを少し頭に入れておいて下さい。

この一行は、「入力から進む方向を決める」というものです。

カメラに対して前(奥)に入力したのか、
右に入力したのか、とかです。

それでは、少しずつばらして見ていきましょう。

・Cam_forward * InputVertical
 これのInputVerticalですが、
 縦の入力は「-1〜1」の間で取得します。

 前入力(奥側、W)をした場合は 1 、
 後ろ入力(手前側、S)の場合は -1 、
 何も入力が無い場合は 0 、と
 入力に合った数値が返ってくるので
 カメラの正面にその値を掛けています。

 入力が正の数か0か負の数かで
 前後どちらに進んでいるか分かりますね。

・Cam.transform.right * InputHorizontal
 これはさっきの縦入力の横バージョンですね。

 Cam.transform.rightでカメラの右側を取得し、
 InputHorizontalの横入力値を掛けています。

 横入力は、左(-1、A)、右(1、D)です。
 これで左右どちらに進むのかが分かります。

それで、縦の進む方向と横の進む方向を
足していますが...。

個人的には、これは感覚の方が大切かと思います。

なんか、縦と横で足しとけば斜めとかでも進めそうじゃん

これで一発です。

rb.velocity = move_forward * moveSpeed + new Vector3(0, rb.velocity.y, 0);
rbがありますね!
まず初めに!

rbには何が入っていましたっけ?
忘れてませんよね、「Rigidbody」
つまり「物理演算」です。

velocityとは、「速度」の事です。

学校で習ったんですが、速度には
「進む方向」と「進む速さ」の二つが
必要らしいです。

それは少し置いといて、
「rb.velocity」で速度を取得出来ます。

それに
「進む方向」×「進む速さ」+「重力」
の値を取得した速度に代入しています。

余談ですが、進む方向は
-1とか0とか1とかの次元です。
これだけでは進めません。

だから、速さを掛けるわけですね。

if (move_forward != Vector3.zero) { ・・・・・・ }
これは、move_forward変数が
Vector3.zero、つまり Vector3(0, 0, 0) で
無ければ { } の中を実行する、という
事になっています。

条件の方を少し詳しくやりましょう。

move_forward変数が (0, 0, 0)に
なるのは、進む方向が無い時。

つまり、ほとんどありません…。
(詳しい事は分からないので恐らくですが…。)

まぁ言葉に直すと、
「回転する必要がある時」
に実行されます。

そういえば、「!=」覚えていますか?
「左辺と右辺が等しくない」です。

覚えておきましょう。

transform.rotation = Quaternion.LookRotation(move_forward);
少し飛びますが、
Quaternion.LookRotation(三次元ベクトル)」
で三次元ベクトルをQuaternionとして
扱うことが出来ます。

どういう事かというと…。
まず頭に入れておいて欲しいのが
それぞれの「」です。

今まで使ってきた型は、
「Vector3」です。
ですが、回転を扱える型は
「Quaternion」です。

この二つ、(将来的にも)大切です!

そして、変えたいのはなんでしたっけ?
「進む方向に、向き・・を」
変えたいんですよね?

それで、進む方向として
扱ってきた変数の型はなんですか?

Vector3ですよね?

ですから、
「Vector3をQuaternionにする」
いう事が必要です。

そこで、この一行が
役に立っている訳ですね。

あとはやっている事は簡単です。
transform.rotationで
このオブジェクトの回転を取得、
Vector3からQuaternionに直した値を
代入して実際に角度を変更しています。





終わりに

長い記事を読んで頂き、
ありがとうございました!


お疲れ様でした!









2017年07月26日

「3DのARPGを作ってみよう!」ゲームの完成イメージ!

この記事、絶対最初に載せるべきでしたよね......。
忘れていた...。



気を取り直して、
この記事のカテゴリーである、

「3DのARPGを作ってみよう!」

の完成イメージをYouTubeにアップしました。



大体は、このイメージを目指していきますが、
もう少し「ゲームとしてプレイできる」レベルまで
引き上げたいと思っています!


ですので、動画にあるのに実装しなかったり、
動画にないものが実装されたりと...。

そんな事があると思います。

まぁ、気長に付き合って下さい!



スポンサードリンク








2017年07月25日

unityでプレイヤーを動かす:変数の解説

前に出して実装した
プレイヤーの移動のプログラムの、
変数部分を解説します。


プログラムの理解は大事なんですけど、
上手く説明出来てるかどうか…


というか、こんなチマチマ記事を出すより、
一気に出した方が良いんだろうか…。


まぁ、それはそれでまた考えます。


そろそろ本題に入りましょう。

スポンサードリンク




変数部分


まず、変数はどこかというと、
public Animator anim;

public bool isGrounded;

public RaycastHit hit;

public float InputHorizontal;
public float InputVertical;
public Rigidbody rb;
public float moveSpeed;
public float jumpPower = 30f;
public GameObject Cam;
public Vector3 Cam_forward;
public Vector3 move_forward;
public Vector3 InputMagnitude;

これですね。

これが変数の全体図になります。


この中の初めの一行、
public Animator anim;


これは、キャラクターを
走らせる、歩かせる、剣を振るなどの
「アニメーション(キャラの動き)」を
設定するのに使います。

ですが正直いって今回の
「プレイヤーの移動」には要らないので
説明は後回しにして、また後日ですね。


public bool isGrounded;

これは、接地判定に使います。

処理の方は後日説明しますが、
地面に着いているか、いないか
を判定します。


地面に着いていれば true、
着いていなければ false として使います。


public RaycastHit hit;

これも接地判定で使います。


「地面に当たっているか」を
判定するのに使います。


public float InputHorizontal;
public float InputVertical;

これらは上から順に、
横の入力
縦の入力となっています。

プレイヤーの移動にはキー入力が
欠かせませんので、この2つの変数に
「入力時の数値」を代入して使います。



public Rigidbody rb;

これは、物理演算です。
重力や、力を加えるのに使えます。


本プログラムでは、
この変数へは必須です。



何故かというと、本プログラムでの移動は
物体に「加速度」を加える事で
移動を表現します。


他にも位置自体を移動させたり
unityにある「キャラクターコントローラー」
というのも使えます。


ですが個人的にキャラクターコントローラーは
好きではありませんのでこれの移動はまた記事を…
………書くかなぁ?



public float moveSpeed;
public float jumpPower = 30f;

これらは上から順に
移動速度ジャンプさせる力です。


ジャンプは、「上向きに力を加えて」
表現するため、この様に「どのくらいの力か」を
決めておきます。



public GameObject Cam;
public Vector3 Cam_forward;
public Vector3 move_forward;

Camは、移動の方向を決めるためのカメラです。


必要があればプログラムで取得しますが、
今はインスペクタからで良いでしょう。


Cam_forwardは、
「プレイヤーが進むべき正面」です。

カメラの向きからキャラクターが
進む、正面として使います。


move_forwardは、カメラの向きに関係なく、
入力から進む方向を決める」のに使います。


例えば、カメラの正面に対して
後ろに進むのか右に進むのか、など
「キーの入力」からの進む方向を扱います。



public Vector3 InputMagnitude;

これで変数は最後ですね。


これは何に使うのかというと、
入力の大きさ」で使います。


例をあげると、
「キーの押し込みが
 小さすぎる場合は移動しない」
という処理を作るのに役立ちます。


終わりに

以上が変数全体となります。

ここでは大体のイメージしか
記述していないので、
分からなかったところもあるかと ^_^;


そこは、実際の処理を解説する時に
もう少し詳しくやるのでご安心を!


では、この辺にしたいと思いますが……。

……未だに記事を一括で書くかどうか
結論が出ません……。

どちらの方が良いのでしょうか…?



スポンサードリンク






2017年07月18日

unity5でプレイヤーの移動をしてみる : 取り敢えず実装

今回は、解説なしで取り敢えず実装、という形で
この記事はやっていきます。

更新、遅れましたね...。
色々大変でした...。

夏休みだというのに、
課題と部活ばかりですし...。



まぁ、気を取り直していってみましょう!



スポンサードリンク




ソースコード

まずはソースコードを出しますね。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Player_Move : MonoBehaviour {

 public Animator anim;
 public bool isGrounded;
 public RaycastHit hit;

 public float InputHorizontal;
 public float InputVertical;
 public Rigidbody rb;
 public float moveSpeed;
 public float jumpPower = 30f;
 public GameObject Cam;
 public Vector3 Cam_forward;
 public Vector3 move_forward;
 public Vector3 InputMagnitude;

 void Start () {
  rb = this.gameObject.GetComponent<Rigidbody>();
  anim = this.gameObject.GetComponent<Animator>();
 }

 void FixedUpdate () {
  //*****接地判定*****//
  if (Physics.SphereCast(this.gameObject.transform.position + new Vector3(0, 2f, 0), transform.lossyScale.x * 0.5f, Vector3.down, out hit, 2f)) {
   isGrounded = true;
  } else {
   isGrounded = false;
  }
  //*****************//
  }

 void Update() {
  if (isGrounded) {
   InputHorizontal = Input.GetAxis("Horizontal");
   InputVertical = Input.GetAxis("Vertical");
   InputMagnitude = new Vector3(InputHorizontal, 0, InputVertical);

   jumpPower = 30f;

   //*****移動*****//
   Cam_forward = Vector3.Scale(Cam.transform.forward, new Vector3(1, 0, 1)).normalized;

   move_forward = Cam_forward * InputVertical + Cam.transform.right * InputHorizontal;

   rb.velocity = move_forward * moveSpeed + new Vector3(0, rb.velocity.y, 0);

   //移動方向に向きを変える
   if (move_forward != Vector3.zero) {
    transform.rotation = Quaternion.LookRotation(move_forward);
   }
   //***************//
  }
 }
}


以上がソースコードとなります。

これを使い、プレイヤーの移動を行います。

移動の実装


まず、事前準備として色々します。

始めに、動かすプレイヤーを作成します。

Hierarchyで右クリック、
3D Object > Capsule でカプセルを作成します。

005.png

そしたら、カプセルを選択し、
右のPositionを
x, z を共に0とし、
y を 3 にします。

プレイヤーの作成は終わりです。

006.png

次に、
Project > Create > C# Scriptでスクリプトを作成し、
名前を「Player_Move」とします。

(ここで、Player_Moveとしなければエラーが出ます。
 仕様が分かっていれば変更オーケーです!)

そしたらPlayer_Moveを開き、
初めからから記述してある文章を全て消し、
上のソースコードを貼り付けます。

ここで1つ、訂正をお願いします!
勝手に改行されていなければ、ですが…、

23, 24行目になるでしょうか、
「<>」と、大文字になっているので、
「<>」この様に小文字に直して下さい!


html(インターネット上のブログラム)の
関係で、こうするしかなかったんです……。

2017/8/17 追記
上のメッセージは無視して下さい。
小文字に修正しました。




次はプレイヤー(Capsule)に
「Rigidbody」を付けます。

これがないと動きません!

007.png



そしたら作ったプレイヤー(Capsule)に
Player_Moveと取り付けます。

(ProjectのスクリプトをCapsuleにD&Dでできます。)

これでプレイヤーにスクリプトが取り付けれました。



プレイヤーが動くための地面がないので
地面を作ります。

[Hierarchy > 3D Object > Plane]で地面を作成し、
x, zのScaleを10にします。

これで地面が大きくなったと思います。

そして最後、
プレイヤー(Capsule)についている
「Player_Move」をInspectorで見てください。

008.png

その中にある、「Cam」に
Hierarchyの「Main Camera」をD&Dします。

あとは、実行!

......と言いたいところですが、
Player_Move の MoveSpeed を適当に設定してください。


このままだと、「移動の速度が0」、
つまり移動しないので......。

30くらいが丁度いいかと。



これで、晴れて移動が可能です!


今度こそ、実行すれば動きます!

お疲れ様でした!

終わりに

実装編は、これにて終了です。
後は、解説ですね。

これが終わったら……
何しましょうかね?


まぁ、それは後々
考えていきます。

それでは、また次回まで。


スポンサードリンク








2017年07月07日

【unity5】カメラ移動・回転 : ClampAngle関数の解説

前書き

今回で最後の解説編になりますね。

解説が終わったら、
全体の処理の流れを確認して終わりにします。

次からは

「プレイヤーの移動」

をやる、と言ったと思います。
......あれ、言いましたよね?

まぁそれはともかく、
解説していきますね。

スポンサードリンク




ClampAngle () : 解説

static float ClampAngle (float angle, float min, float max) {
 if (angle < -360) { angle += 360; }
 if (angle > 360) { angle -= 360; }
 return Mathf.Clamp(angle, min, max);
}


これが、今回説明する
ソースコードになります。

まず関数から見ていきましょう。



static とあります。

これを付ける事によって、
何処どこからでも呼び出せるようになる、
ということだと思います。
(そうであって欲しいです…)

その次はというと……
float とありますよね?

関数なのに少数型のfloat……。
どういう事でしょうね?


少し、関数の最後の方を見て下さい。

そこに、「return」とあります。
これは値を返すという意味で、
いつもの「void」部分にはというと、
返す値の型を void の代わりに記述します。

これをしないとエラーが出ますよ。

以上の事から、
void → float になっているんですね。




ClampAngle (・・・・・・

には、処理が決まっていません。

StartやUpdateのように
呼ばれるタイミングが決まっていない、
と言うことですね。

なので、呼ばないと実行されません!

そこで、前回の未説明部分がでてきますね。
y = ClampAngle(y, yMinLimit, yMaxLimit);

これです。

ここで、呼んでますよね?

そして何やら y だとか yMinLimit だとか、
良く分からないものがあります。

これらが、引数となります。

引数が何か、というのはこちらの
引数を使ってみよう!
をご覧下さい。


話を戻しますが、
現在のカメラの角度を「y」、
それぞれ「縦の角度限界(上、下)」

これらを引数にしています。

受け取りは順に、
y = angle
MinLimit = min
MaxLimit = max
となっています。


この関数でやっている処理は、
簡単に言えば
「縦の角度が360°を超えたら
 0に戻す」
というのをやっているだけです。

これをしないと、
500とか800までいきますからねー。



角度が -360 より下回れば360を足し、
360を上回れば 360 を引いています。

ただただ、それだけです。


そして、

Mathf.Clamp(値, 最小値, 最大値);

これで、最小と最大の間で値を制御出来ます。

今回ではカメラの角度が「値」の部分に
入っているので上下の限界角度として
制限できる、という訳です。

それを返して、yに代入しているんです。

ここまでで、一旦全部ですかね?

スポンサードリンク




全解説まとめ

簡単に今までやってきた部分を
解説していきます。

それでは、順に流していきましょう。

//使うシステムの宣言(?)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//クラス
public class CameraController : MonoBehaviour {

 public Transform target;
 public float distance = 12.0f;
 public float xSpeed = 250.0f;
 public float ySpeed = 120.0f;
 public float yMinLimit = -45f;
 public float yMaxLimit = 85f;
 private float x = 0.0f;
 private float y = 0.0f;

 void Start () {
  var angles = transform.eulerAngles;
  x = angles.y;
  y = angles.x;
 }

 void Update () {
  if (target) {
   x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
   y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

   y = ClampAngle(y, yMinLimit, yMaxLimit);

   var rotation = Quaternion.Euler(y, x, 0);
   var position = rotation * new Vector3(0.0f, 0.0f, -distance) + target.position;

   transform.rotation = rotation;
   transform.position = position;
   }
 }

 static float ClampAngle (float angle, float min, float max) {
  if (angle < -360) { angle += 360; }
  if (angle > 360) { angle -= 360; }
  return Mathf.Clamp(angle, min, max);
 }
}


システム宣言は、
「今からこの機能を使いますよ」
と、コンピュータに知らせます。

クラスはプログラムの設計図
みたいな存在ですね。
この中にコードを書きます。

変数宣言です。
  1. カメラの中心となるターゲット
  2. ターゲットからのカメラの距離
  3. カメラの横移動の速さ
  4. カメラの縦移動の速さ
  5. カメラの限界角度(上)
  6. カメラの限界角度(下)
  7. 横の入力 など
  8. 縦の入力 など


Start関数
初期角度として
x. y に代入しています。

Update関数
target が設定されていれば
マウス入力によって
カメラのx, y に反映
y には
上記の処理 + 上限までの制限

カメラの角度・位置を
あらかじめ作っておき、
その後にゲーム内に反映させています。

最後の関数は、
y = ・・・ の所で
実行しています。

限界角度を維持するのと、
カメラの角度が360から抜けない
ようにする為ですね。

終わりに

最後の方、結構走ってしまいましたが…。
分かって頂けたでしょうか?

分かって頂けたのなら幸いです……。

次回からは宣言通り、
「プレイヤーの移動」
をやっていきますね。

ではでは、また次回!



もう少しで夏休み……!
課題地獄です。


スポンサードリンク








2017年07月05日

【unity5】カメラ移動・回転 : Update関数の解説

はじめに

今回でUpdate関数の説明が終わり、
次回で最後の関数の説明が終わり......

という訳で、もうすぐで
カメラ編は終わり、となりますね。

その次からは、

「プレイヤーの移動」

の記事を書いていこうかな、と
思っています。

大事ですねー、移動。
カメラだけ動かせても楽しくないですからね(笑)


それでは、やっていきます!



スポンサードリンク



Update関数の解説


Update関数は、ここですね。
void Update () {
 if (target) {
  x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
  y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

  y = ClampAngle(y, yMinLimit, yMaxLimit);

  var rotation = Quaternion.Euler(y, x, 0);
  var position = rotation * new Vector3(0.0f, 0.0f, -distance) + target.position;

  transform.rotation = rotation;
  transform.position = position;
  }
}


この関数も処理が決まっていて、
ゲーム実行中は呼ばれ続ける関数です。

常に更新されている訳ですね。

そしていよいよ、2行目の
 if (target) { ・・・・・・
とあると思います。

if の () の中が「true」なら{ }内を実行します。

ですが、() 内の target は Transform型ですよね?
Transform型はpositionとかrotationを
扱うもの……。

それでtrueとか意味が分かりません。

ですので、分かりやすくいうと

「存在していたら」

みたいな感じでしょうか?
だいぶ分かり易くなったと思います。

ですから存在していたら {} 内を実行
なりますね。

target が設定されてなければ
何も動かない、という事になります。




その次、x, y がそれぞれあります。

ここで復習しておきましょう。
「+=」と「-=」、覚えていますか?

左の値に足す(から引く)でしたね?
これは、頭に入れておいて下さいね。



それで x, y ですが、
Start関数で何かを入れてましたよね?


そう、開始直後のカメラの角度でした。
これは始めた瞬間にカメラの向きが
0に戻らないように、
現在の角度のまま始めれるように、の
処理です。


進んで、
Input.GetAxis("Mouse X") * xSpeed * 0.02f;

となっています。

1つずつ分けて考えていくと、
Input.GetAxis("Mouse X")

マウスの横のみの動きを取得します。
縦の動きは取得しません。

これは軸とか関係ないので
直で X を取得していますね。

-1〜1の間の少数でマウスの移動を
取得する事ができます。


xSpeed

これは、初期値が設定されていたと
思います。

確か、250.0fでしたっけ。

その x に、0.02f を掛けています。

ですので…5 になるんでしょうか?



これら全てを合算がっさんして考えると、
最大のマウス入力で、5 まで取得されます。

→ -5〜5

こうですかね?

多分、こうです!(笑)

マウスの動きに対して、-5〜5の間で
カメラを動かせますね。



縦も一緒ですが、
y の方は何故か引いていますね…。

何故でしょうか?
今の僕には分かりません…。

わかり次第、追記しますね。





それの次ですが……。
 y = ClampAngle(y, yMinLimit, yMaxLimit);

これは次回の最後の関数を解説する
時に一緒に解説したいと思います。

最後の関数を実行している部分が
入っていますので。

関数が分からないと
この意味も分からない訳です。



そして、次の
var rotation = Quaternion.Euler(y, x, 0);
var position = rotation * new Vector3(0.0f, 0.0f, -distance) + target.position;

これらですが、カメラに設定するための
角度・位置を作っています。

実際にカメラに動き・回転を反映させるのは
これらの後の処理ですね。


まず作っているのが......角度ですね。

Quaternion.Euler(x, y, z);

で x, y, z にそれぞれ入れた値だけ回ります。
(ここでの x, y, z は、ただの軸を表しています。
本編の変数とは関係ありません。)

例えば、
Quaternion.Euler(10, 0, 0);

とすれば x軸 を中心に10ずつ回転します。

x軸 は横に引かれます。
それを軸にして回転するので、
縦にグルグルですね。
Document001.png
こんな感じで。



ですが、回って欲しいのは横に、です。
ですので横に回る、y が入っていますね。

横です
Document002.png

縦も同様です。

同様です
Document001.png


z軸 は奥行きの軸です。
それを軸にして動く......。

首を傾ける様な動きになってしまいます。

そんな動きは入りませんね。
ですから、z は0です。





var position = rotation * new Vector3(0.0f, 0.0f, -distance) + target.position;


これは難しそうですね......。

上の回転(var rotation...…の部分)に
新しい位置を掛けています。

これは、奥行きです。

率直にいえば、
プレイヤーからカメラまでの距離です。

「-distance」となっていますが、
これが「distance」となると、
プレイヤーの前にカメラが出ます。

写りませんね、キャラが。

ですのでキャラの後ろに出すために
マイナスを付ける、ということですね。

それで常に後ろに出してます。



なんで最後に target のポジションを
足しているか、というのは
多分カメラの中心を target に合わせる為です。

この処理がないと、プレイヤーが
何処どこはかへ
行ってしまうのではないでしょうか?
(この辺は良く分かりません…!)

残りの2つは、
カメラの位置・角度
求めた位置・角度
代入しているだけですね。

ここで、実際にカメラが動く訳です。



これでひと通り説明し終わりましたが…。
分かって頂けたでしょうか?

分からなければまたコメント下さいね。

それでは、今回はこの辺で………。

部活で疲れました…











2017年07月04日

【unity5】カメラ移動・回転 : Start関数の解説

Start関数の解説

今日はいきなり
解説から始めます!

何故なぜかって?

3行しかないですが、
内容が濃いからです!


内容が濃いというか、
すごくややこしいんです……。

また説明が難しそうですよー…

そんな訳で始めます。

スポンサードリンク





Start関数部分は、ここですね。
void Start () {
 var angles = transform.eulerAngles;
 x = angles.y;
 y = angles.x;
}


Start関数、覚えてますか?

ゲーム開始直後に、
一度だけ呼ばれる
関数ですよ。

次では、
関数内で変数の作成をしています。

これは…説明してないですよね?

関数内で変数を宣言すると、
作成した関数の中でしか使えません

書き方は、jsの方に似ていますね。
var 変数名 = 値;

これは、var で宣言します。

関数外の宣言と違うのは、
  • 値を入れなければならない
  • その関数内でしか使えない
  • var を使って宣言をする

このくらいでしょうか…?

ここで1つ。
関数内での変数宣言には、
型を指定していません


ですので、変数内に
なんでも入ってしまいます。


そうすると、バグの原因となったり
するのですが……

あんまりそんな事は起きないので
気にしなくて良いと思いますが(笑)



それで、angles という名前で
なんでも入る変数を作っています。

その変数には、

「transform.eulerAngles」

というものが入っています。

何か分かりませんよね?

この、transform.eulerAngles
角度が取得できます。

この前、Transformは回転も扱うと
お話したと思います。

その回転の中でも、角度を取得する機能を
使う、といったところでしょうか。

ですが、いきなり
transform.eulerAngles
といわれても、なんの角度取得するの?
となるので、少し補足しますね。

なんのtransformを扱うか指定しない場合、
このスクリプトが付いているオブジェクト
のtransformを扱います。

ですので、this.transform.eulerAngles;に
書き換えてみて下さい。

これでも、同じ値が取得できます。

英語でもthisには「これ」とかいう
意味がありますよね。

とまぁ、そんな感じです。



問題は次の2つですねー…。

皆さん、数学のグラフは覚えていますか?
x, y軸の事ですね。


3次元でも同じで、
縦 : y
横 : x
奥 : z
となっています。

ですが、よく見てみて下さい。
x軸に角度y、y軸に角度x
入っていますよね。

何故でしょうか?
説明しますね。



x軸には、「横の回転」
入れたいんです。

ですので、「yを軸にすると横回転が取得出来る」
という事なんですよ。

つまり、
Document002.png
こういう事です!

ですので、横の回転であるxには
yの角度を取得する必要がある訳です!



逆もまたしかり。
Document001.png

縦の回転であるyには、
xを軸にした角度を入れてやる
必要があるんですね。


今回は、この辺りでしょうかね…?

終わりに

今回は少し難しかったと思います。
大丈夫でしたでしょうか?

上手く説明出来たかどうか
分かりませんが…。

伝わっていると信じますね。

分からなければコメント下さいm(_ _)m

それでは、また次回!


スポンサードリンク








2017年06月30日

【unity5】カメラ移動・回転 : 変数の解説

はじめに

この「はじめに」の見出し、
毎度お馴染みですね!(笑)

こっちの方が始めやすいんですよね…。
まぁ、僕の気分なので変わるかもですが(笑)


実は、父もブロガーでして。
色々アドバイス貰いながら、
このブログは成り立っています!

……今更ですが、更新遅くなって
すみません…。

やっとテストが終わったぁー。

…と思いきや、次の日また別の
試験がありましてー…。

今週は地獄でした……!

そんなこんなで、
今週は遅くなりました…。





気を取り直して、前回やったカメラの
操作についてプログラムを解説して
いきたいと思います!



解説と言っておりますが、
僕も分からない所が多々あります!

なので、経験者さん教えてください……!


分かるところは僕も全力を尽くして
解説しますので!



今回は、変数部分までやって
終わりにします。

あんまり長々とやっていても、見る気が
無くなるような気がしますので…。



それでは、どうぞ!


スポンサードリンク





カメラ制御 : 解説編

さてさて、前回でソースコードは
公開しましたが、いきなり解説から始めても

「はぁ?何言ってんだコイツ」

みたいな感じになると思うので、
またソースをバンとやりたいと思います!



それでは、バン!
//使うシステムの宣言(?)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//クラス
public class CameraController : MonoBehaviour {

 public Transform target;
 public float distance = 12.0f;
 public float xSpeed = 250.0f;
 public float ySpeed = 120.0f;
 public float yMinLimit = -45f;
 public float yMaxLimit = 85f;
 private float x = 0.0f;
 private float y = 0.0f;

 void Start () {
  var angles = transform.eulerAngles;
  x = angles.y;
  y = angles.x;
 }

 void Update () {
  if (target) {
   x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
   y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

   y = ClampAngle(y, yMinLimit, yMaxLimit);

   var rotation = Quaternion.Euler(y, x, 0);
   var position = rotation * new Vector3(0.0f, 0.0f, -distance) + target.position;

   transform.rotation = rotation;
   transform.position = position;
   }
 }

 static float ClampAngle (float angle, float min, float max) {
  if (angle < -360) { angle += 360; }
  if (angle > 360) { angle -= 360; }
  return Mathf.Clamp(angle, min, max);
 }
}


はい、前回と全く同じです!
コピペしたので!



うーん、それにしても変なところで
改行が入ってしまってますね。

何か改善する手立てはないでしょうか……。
また今度、模索ですね。
(スマホだからでしょうか...?)



そんな事は置いといてですね、
コード始めに記述してある
システム宣言ですが、あれは

「今からこんなシステムを使いますよ」

と、コンピュータに知らせてます。


最低限、あの3つは
入れておいた方が良いでしょう。

とは言っても、スクリプトを開けば
標準で記述済みだとは思うんですが(笑)



次は、クラスについてですね。


クラスとは、プログラム本体という
認識で良いでしょう。

スクリプトとは、

「プログラムを書く紙」

クラスは、

「スクリプトに書いてあるコードそのもの」

の事です。


うーん、この言い方だと語弊が
あるでしょうか……。

説明が難しいですね…。



まぁ、取り敢えずクラスの認識としては

「スクリプトに無ければならないもの」

といった感じでいいかと。

また良い説明の仕方があれば追記します!



クラスは、今のところ
public class クラス名 : MonoBehaviour { }


こんな感じで良いと思います。

変に解説しても意味が
分からないと思いますし…。

自分でも何を言ってるのか、
分からなくなりますし…。



それで、このクラスの中に、
この前書いた記事の変数やら関数やらを
入れていく事になるんです。


スクリプト>クラス>関数>処理(変数等)

といった感じでしょうか。

まぁ、その辺はまた
詳しい記事を書きたいと思います。





それでは、まず変数の説明からですね。


変数、もう大丈夫でしょうか?
もう一度確認したい方は、
こちらのunityでのプログラミング基礎知識 1
をご覧下さい。


変数を1つずつピックアップして解説していきます。


まず1つ目の
public Transform target;

ですが、「Transform」型が入ってますね?

これは基礎知識編では解説していません。


という訳でTransformの
説明をしていきます。

Transformとは、
  • 位置(position)
  • 回転(rotation)
  • 大きさ(scale)

のプロパティを扱っています。

オブジェクトの移動とかに
使えそうですね。

ここで無駄に説明しておくと、
もし型がGameObjectであれば
「Transform」という概念はありません。

ですから、もし

GameObject target;

このように、target は GameObjerct であるという
宣言ならば、少し工夫が要ります。

target.transform.position・・・

と、target の transform の中の position を扱え!
ってシステム言わなきゃいけないんですね。

ですが、ここでは target が Transform だと
言ってありますので、
target.position でいけます。





話を戻しますが、
public float distance = 12.0f;


これはカメラとプレイヤーとの距離です。

型は少数ですね。
distanceという名前で変数が作られてます。

初期値は12となっていて、
プレイヤーとカメラの距離が
12mという事です!

その次の
public float xSpeed = 250.0f;
public float ySpeed = 120.0f;


この2つですが、それぞれマウスを動かした時の
カメラが動く速さです。

縦に動く時、横に動く時速さを設定しています。
ここの変数を使ってスピードを調節したり出来ます。

public float yMinLimit = -45f;
public float yMaxLimit = 85f;


この2つでは縦方向に動く上限を設定しています。
360°クルクル回転しないようにですね。

private float x = 0.0f;
private float y = 0.0f;


これは、カメラの動きに関わります。
マウスの動きの取得や、取り出した値に
スピードを掛けたりと......

それが縦、横でそれぞれあるだけですね。

まぁ、後日に解説記事を出していくので
その時にでも詳しく解説していきます。



では、変数はこれで終わりですね。
今回はこれで終わりにします!

後は、雑談をお楽しみ下さい。

終わりに (雑談)

今回は変数のみだったので
簡単だったと思います。

ですが、おそらく次回から難しくなってくると
思いますが、その分しっかり解説していきます!



ところで、スマホでも見やすいように
文の改行を多くして見たんですがどうでしょう?

あとは、これも読みやすいように
スペースを多く取ってます。

まだ慣れませんねー。
これから頑張ります......。


それでは、この辺で。



スポンサードリンク








2017年06月28日

【unity5】カメラ移動・回転させる方法

はじめに

さて、unity5を使ってカメラアングルを変えたり、回転させる方法を紹介します。
今回からはARPG製作に入ります。



ただ、完全にARPGを作っていても面白くないのでたまに関係ない記事出します。
まあ、カテゴリーは別にするのでゲーム開発に支障はないと思いますが。



プログラミングが分からない、という方はこちらからからご覧下さい。
unityでのプログラミング基礎知識 1



さてさて、
ARPGはアクションロールプレイングゲームの略、というのを
どこかで話した気がします。
「アクション」と付いているからには操作性は大切ですよね。

と言いつつも、そんなガチでは作りません。
そんな事していたら、このシリーズとても長くなってしまいます(笑)

大体、10〜20記事程度でやっていきたいと思います。
プログラミングの基礎を交えながら、という感じですねー。

まぁ所詮、高校生 + 独学の組み合わせですので、
改善点があればコメントでご指摘お願いしますm(_ _)m





取り敢えず今回は、実際に動かすだけにしたいと思います。
今週はテストでして、疲れてます......。


まだ3日目が終わっただけです......。
あと2日...土曜日もテストなんですよねー......鬱です。





取り敢えず、第1回!
カメラのコントロール、スタート!




【スポンサードリンク】



カメラコントローラー

まず、一旦ソースコード(プログラム丸ごと)を載せます。
これをカメラに取り付けてtargetをドラック&ドロップだけで動きますよ(笑)





それでは、ぽん。

//使うシステムの宣言(?)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//クラス
public class CameraController : MonoBehaviour {

 public Transform target;
 public float distance = 12.0f;
 public float xSpeed = 250.0f;
 public float ySpeed = 120.0f;
 public float yMinLimit = -45f;
 public float yMaxLimit = 85f;
 private float x = 0.0f;
 private float y = 0.0f;

 void Start () {
  var angles = transform.eulerAngles;
  x = angles.y;
  y = angles.x;
 }

 void Update () {
  if (target) {
   x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
   y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

   y = ClampAngle(y, yMinLimit, yMaxLimit);

   var rotation = Quaternion.Euler(y, x, 0);
   var position = rotation * new Vector3(0.0f, 0.0f, -distance) + target.position;

   transform.rotation = rotation;
   transform.position = position;
   }
 }

 static float ClampAngle (float angle, float min, float max) {
  if (angle < -360) { angle += 360; }
  if (angle > 360) { angle -= 360; }
  return Mathf.Clamp(angle, min, max);
 }
}

以上がソースになります。




これをコピーして、unity画面に戻ります。
「Project」で右クリック>Create>C# Script でスクリプトを作成します。
名前は「CameraController」として下さい。

003.jpg



この「スクリプト」というのに、プログラムを書いていくんです。
という訳で、作ったCameraControllerスクリプトを開いて記述済の文字を全部消し、上のソースコードを貼り付けます。

004.jpg




そしたら、保存してください。
Windowsの場合はCtrl + S で保存できます。



Macは持っていないのでよく分かりませんが......
左上の「ファイル」から保存出来ると思います。

Windowsでもできます。
(いま手元にパソコンが無いので確認できませんが......)







unity側に戻りまして、カメラがグルグルする支点を作りましょう。
ヒエラルキーのウィンドウで右クリック>3D Object>Capsule で作成します。

005.jpg



支点の作成は以上で、次は「Main Camera」を選択してください。
そしたらインスペクタの下の方に「Add Component」というボタンがあると思いますのでそこで「CameraController」と検索します。

006.jpg


出てきたスクリプトをカメラに追加し、スクリプトにtargetというものがあると思います。
そこの右側の空欄にヒエラルキーの「Capsule」をD&D(ドラッグ&ドロップ)します。

007.jpg





あとは、実行です!
上の方にある、「右向き三角1」を押してください。



実行されれば、カメラがカプセルの周りをマウスに合わせて動くと思います!
はい、出来ました!


という訳なので、今回はこの辺で。
解説は、次回に回したいと思います。





あーぁ、明日もテストだ......
ちなみに英語、保健、国語bです......
......頑張ってきます。



それでは皆さん、また次回。





【スポンサードリンク】








検索
プロフィール
ピノまっちゃさんの画像
ピノまっちゃ
どうも、ピノまっちゃ(PinoMatcha)です!
ゲーム制作をちょこまか頑張ってる大学生で、プログラミングも独学です。
ですので実力は全然ですが、最善を尽くして頑張っております!

名前の由来はピノの抹茶味が好きだからじゃなくて、ピノと抹茶が好きだからです!


更新 : 不定期!
プロフィール
新着記事
最新のコメント
更新事項
2018/8/2 定期更新への変更の報告に追記しました。

2018/5/10 「続きを読む」機能の使い方がやっと分かりました。

2017/9/14 プレイヤーを動かす:関数の解説の一部を書き直しました。

2017/8/1 【unity5】カメラ移動・回転させる方法に多数の画像を追加しました。
カテゴリーアーカイブ
YouTubeチャンネル
Fantiaリンク
よければ応援お願いします!

Pixivアカウント
現在、調整中です…
×

この広告は30日以上新しい記事の更新がないブログに表示されております。