Contents
【2DSTG制作】の動画内で表示されるコード:#11 – #20
サムネイルをクリックすると、YouTubeの動画ページに移動します。
#12:スクリプトからLive2Dモデルの色を操作
Live2Dモデルの色を操作
using Live2D.Cubism.Rendering;
CubismRenderController renderController;
void Start()
{
renderController = GetComponent<CubismRenderController>();
}
private IEnumerator HitColor()
{
renderController.OverwriteFlagForModelScreenColors = true;
yield return null;
// スクリーンで白色を合成
var screenColor = new Color(0.3f, 0.3f, 0.3f, 1.0f);
// 全てのパーツに指定した色を適用する
for (int i = 0; i < renderController.Renderers.Length; i++)
{
renderController.Renderers[i].ScreenColor = screenColor;
}
yield return new WaitForSeconds(0.03f);
// 元の色に戻す
renderController.OverwriteFlagForModelScreenColors = false;
}
#14:Animatorでポストプロセスを操作
Animator
Animator animator;
void Start()
{
animator = GetComponent<Animator>();
}
--------------------------------------
// 任意のタイミングで
// モノクロのエフェクトを適用
animator.SetTrigger("Monochrome");
// 任意のタイミングで
// モノクロのエフェクトを解除
animator.SetTrigger("Color");
#15:レーザーの実装
Laser
// オブジェクト生成から削除するまでの時間
[SerializeField] float lifeTime = 1.0f;
// 弾の攻撃力
public int power = 1;
// レーザーか否か
public bool laser;
Renderer targetRenderer;
void Start()
{
// lifeTime秒後に削除
Destroy(gameObject, lifeTime);
targetRenderer = GetComponent<Renderer>();
}
void Update()
{
// 画面に表示されなくなったら
if (!targetRenderer.isVisible) {
if (laser == false) {
// レーザー以外は削除
Destroy(gameObject);
} else {
// レーザーは攻撃力ゼロ
power = 0;
}
}
}
#16:反射レーザー
ReflectLaser
Vector2 lastVelocity = Vector2.zero;
Rigidbody2D rb2d;
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
// 次の速度の計算用にVelocityの値を保持しておく
lastVelocity = rb2d.velocity;
}
void OnCollisionEnter2D(Collision2D collision) {
// 反射する地形に接触したら
if (collision.gameObject.tag == "Terrain") {
// 接触した地形に垂直な単位ベクトル(法線ベクトル)を取得
Vector2 normalVector = collision.contacts[0].normal;
// 反射ベクトルを計算
Vector2 reflectVector = Vector2.Reflect(lastVelocity, normalVector);
// 速度を更新
rb2d.velocity = reflectVector;
}
}
#17:追尾レーザー
HomingLaser
Vector3 velocity;
// 追尾レーザーの初期位置
Vector3 position;
Vector3 acceleration;
// ターゲットが存在しない時の目標位置
Vector3 randomPos;
Transform target;
// 追尾レーザーの初期位置に最も近いオブジェクト
GameObject searchNearObj;
// 着弾までの時間
[SerializeField] float period;
void Start()
{
position = transform.position;
searchNearObj = FindClosestEnemy();
// ターゲットが存在すれば位置を取得
if (searchNearObj != null) {
target = searchNearObj.transform;
}
randomPos = new Vector3(4.0f, Random.Range(-1.5f, 1.5f), 0);
// プレイヤーの斜め後ろにレーザーを発射
velocity = new Vector3(Random.Range(-5.0f, -2.5f), Random.Range(-6.0f, 6.0f), 0);
}
void Update()
{
acceleration = Vector3.zero;
if (searchNearObj != null) {
Vector3 diff = target.position - position;
acceleration += (diff - velocity * period) * 2f / (period * period);
} else {
// ターゲットが存在しない場合は予備の目標地点に移動
Vector3 diff = randomPos - position;
acceleration += (diff - velocity * period) * 2f / (period * period);
}
period -= Time.deltaTime;
if (period < 0f) {
return;
}
velocity += acceleration * Time.deltaTime;
position += velocity * Time.deltaTime;
transform.position = position;
}
public GameObject FindClosestEnemy()
{
// EnemyのTagを持つゲームオブジェクトの配列
GameObject[] gos;
gos = GameObject.FindGameObjectsWithTag("Enemy");
// 最も近い位置に存在するEnemy
GameObject closest = null;
float distance = Mathf.Infinity;
Vector3 position = transform.position;
foreach (GameObject go in gos)
{
Vector3 diff = go.transform.position - position;
float curDistance = diff.sqrMagnitude;
if (curDistance < distance)
{
closest = go;
distance = curDistance;
}
}
// 最も近かったEnemyを返す
return closest;
}
#18:追尾レーザー(同時に複数発射)・ヒットエフェクト
画面内の敵ユニットをランダムに取得
public GameObject[] FindEnemy()
{
// EnemyのTagを持つゲームオブジェクトの配列
GameObject[] gos;
gos = GameObject.FindGameObjectsWithTag("Enemy");
// 画面内の敵ユニットを格納する配列
enemyList = new GameObject[6];
int i = 0;
foreach (GameObject go in gos)
{
// 画面外の敵ユニットは除外
if (go.transform.position.x >= 4 || go.transform.position.x <= -4)
{
continue;
}
enemyList[i] = go;
i++;
if (i >= 6)
{
i = 0;
}
}
return enemyList;
}
ヒットエフェクト
[SerializeField] GameObject hitEffect;
// ヒットエフェクトの生成
public void HitEffect()
{
Instantiate(hitEffect, transform.position, transform.rotation);
}
void OnTriggerEnter2D(Collider2D collision)
{
// 敵ユニットに当たったら
if (collision.gameObject.tag == "Enemy")
{
// SEを再生
SoundManager.instance.PlaySE();
// ヒットエフェクトを生成
HitEffect();
}
}
#19:自機狙いの追尾レーザー
HomingLaser_Enemy
// 加速度の上限
[SerializeField] float limit;
void Update()
{
var acceleration = Vector3.zero;
var diff = target.position - position;
acceleration += (diff - velocity * period) * 2f / (period * period);
// 加速度の上限値を設定する
if (acceleration.magnitude > limit)
{
acceleration = acceleration.normalized * limit;
}
period -= Time.deltaTime;
velocity += acceleration * Time.deltaTime;
position += velocity * Time.deltaTime;
transform.position = position;
}
#20:ヒットストップの実装
画面の停止+カメラの揺れ
using DG.Tweening;
void Start()
{
// 初期位置を取得
initialPos = transform.position;
}
public void SampleB()
{
// 画面の停止
Time.timeScale = 0;
// 対象を揺らす
transform.DOShakePosition(0.4f, 0.3f, 30, 90)
// timeScaleに影響されなくなる
.SetUpdate(true)
.OnComplete(() =>
{
// アニメーションが終了したら時間を元に戻す
Time.timeScale = 1;
// カメラの位置も戻す
transform.position = initialPos;
});
}
public void SampleC()
{
Time.timeScale = 0;
// 画面を強めに揺らす
transform.DOShakePosition(1.0f, 0.8f, 30, 1)
.SetUpdate(true)
.OnComplete(() =>
{
transform.position = initialPos;
// 画面をスローにする関数
SlowMotion();
});
}
void SlowMotion()
{
Time.timeScale = 0.2f;
// 3秒後にゲームオーバーの処理を実行
DOVirtual.DelayedCall(3.0f, () => GameOver())
.OnComplete(() =>
{
Time.timeScale = 1.0f;
});
}









