code ソーシャル

Unityアプリcodetips(57)

スポンサーリンク

//tips

//一部が透過するsubcamの描画修正

カメラの描画の前後関係は深度情報に基づいて行われる。

すでに手前にレンダリングされている場合はレンダリングしない、そうでなければレンダリングして深度情報も更新し、基本的には遠くにあるオブジェクトから順に描画される。

マテリアルの Render Queue の数字が小さいと先、大きいと後の描画順になる。

http://klabgames.creative.blog.jp.klab.com/archives/22266460.html

Subcameraをプレイヤーの子要素から外し、ステージ全体の描画に変更。

subcameraカメラ操作が不要になったので、操作ボタンの非表示化、操作ボタンに関係する表示スクリプトの変更、テキスト変更。

//playstage = PlayerPrefs.SetInt設置場所確認

Unityで動作確認していた際にplaystage = PlayerPrefs.SetInt設置場所がどこか分からなくなったので確認。

Stageselect画面のボタンに下記が実行されるように組み込まれており、ボタンを押して、押したボタンの番号を前回のplaystageとして記録していた。

public void PlayStage(int No)
{

PlayerPrefs.SetInt("playstage", No);

}

なので、unityのstageごとの動作確認を行い、stageselect画面に戻ってきても、そのstage情報は記録されないことになる。

//goalの位置移動

Goalの位置をゲーム進行中に移動させる。

このゲームの難易度に影響するものに視野の確保がある。そのためゴールも視野外に突如移動する可能性を示唆する。

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

public class TrickGoal : MonoBehaviour
{

[SerializeField] GameObject test;
[SerializeField] GameObject test1;

int count = 0;

void Update()
{

if (Input.anyKeyDown)
{
count++;
}

if (count == 0)
{
//ゲームオブジェクト表示→非表示
test.SetActive(true);
test1.SetActive(false);
}

if (count == 6)
{
//ゲームオブジェクト表示→非表示
test.SetActive(false);
test1.SetActive(true);
}

}
}

//goalとgameoverの時間差の解消

Goalのシーンへ移行する場合、Invoke("Goal", 0.0f);で、gameoverのシーンへ移行する場合、Invoke("Over", 1);とすると、被弾中に強引にgoalすることでgoalsceneへと移行することができる。

プレイヤーの移動を止めるためthis.Player.SetActive(false);をFadeover();発生タイミングで実行する。

以前まではカメラが子要素にあったため制御が難しかったが、既にカメラは両方とも子要素から外れているためthis.Player.SetActive(false);を組み込んでもゲーム進行に影響は出なくなった。

ただ、下記のエラー自体は発生している。
NullReferenceException: Object reference not set to an instance of an object

スクリプトを消してもエラーが出続けたがunityを再起動したら治った。

このエラーが気持ち悪いので、操作ボタンの方を押せなくする方法も考えた。

下記を追加して操作してみたところ若干のタイムラグがあるのとenemyごとにボタンを設定するのが面倒なので保留にした。

using UnityEngine.UI;

[SerializeField] Button Bleft;
[SerializeField] Button Bright;
[SerializeField] Button Bup;
[SerializeField] Button Bdown;

Bleft.interactable = false;
Bright.interactable = false;
Bup.interactable = false;
Bdown.interactable = false;

結局、一番簡単なInvoke("Goal", 1);にすることで処理をした。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GoalController : MonoBehaviour
{
[SerializeField] GameObject Fade;

GameObject Player;

public int stageNo;

void Start()
{

this.Player = GameObject.Find("Player");

}

void Update()
{

Vector3 p1 = transform.position;
Vector3 p2 = this.Player.transform.position;

 

if (p1 == p2)
{
Fadeover();

if (Player != null)
{
Invoke("Goal", 1.0f);

}
}

}

void Goal()
{
if (PlayerPrefs.GetInt("CLEAR,0") < stageNo)
{
PlayerPrefs.SetInt("CLEAR", stageNo);
}
SceneManager.LoadScene("Goal");
}
void Fadeover()
{
Fade.SetActive(true);
}

}

//enemyの遠距離攻撃設定

遠距離の攻撃を行うenemyを作成する。

Instantiateを使用する必要もなかったので、enemyとbullet、bullet判定のオブジェクトを分けて作成した。

Enemyは動かす必要がなかったので、汎用性がある、当たり判定はあるが、その場から動かないスクリプトをアタッチ。

bulletは、このシーン用に、カウントごとに場所移動をするスクリプトをアタッチした。

Playerのy座標が-0.5であるため、bulletと当たり判定用の空オブジェクトであるbulletに分けて作成した。

Bullet2つのスクリプトは同じものをアタッチしてあるが、当たり判定用の初期位置はy=-0.5となっている。

これは座標一致で当たり判定とする設定のため。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class EnemyCBullet : MonoBehaviour
{
[SerializeField] GameObject Fade;

GameObject Player;
//Animator anim;

Vector3 MOVEX = new Vector3(1.0f, 0, 0);
Vector3 MOVEY = new Vector3(0, 1.0f, 0);
Vector3 MOVEZ = new Vector3(0, 0, 1.0f);

 

Vector3 target; // 入力受付時、移動後の位置を算出して保存

private int count = 0;

void Start()
{
target = transform.position;

this.Player = GameObject.Find("Player");

}

void Update()
{
if (Input.anyKeyDown)
{
count++;

if (count == 1)
{
target = transform.position + MOVEZ;

}

if (count == 2)
{

target = transform.position + MOVEZ;

}

if (count == 3)
{

target = transform.position + MOVEZ;

 

}
if (count == 4)
{

target = transform.position + MOVEZ;

}

if (count == 5)
{

target = transform.position + MOVEZ;

}

if (count == 6)
{

target = transform.position + MOVEZ;

}

if (count == 7)
{

target = transform.position - MOVEZ * 6;
count = 0;

}

}

 

Move();

Vector3 p1 = transform.position;
Vector3 p2 = this.Player.transform.position;

 

if (p1 == p2)
{
Fadeover();

if (Player != null)
{
Invoke("Over", 1);

}
}

}
void Move()
{
this.transform.position = target;
}
void Over()
{
SceneManager.LoadScene("GameOver");
}
void Fadeover()
{
Fade.SetActive(true);
}

}

Forで短縮しても良いが、カウントごとに修正を入れる変形版を別シーンで作成する可能性が高いため、現在は全て記載している。

//enemyの大規模攻撃への対応

Enemyの大規模攻撃は攻撃の発生をコントロールするスクリプトと攻撃発生時に衝突判定を与えるスクリプトの二つを利用する。

攻撃発生時に衝突反応を与えるスクリプトは、enemyがその場から動かないスクリプトをそのまま流用できる。エフェクトにこのスクリプトをアタッチした空オブジェクトを子要素として追加すれば良い。

発生をコントロールするスクリプトは下記とした。

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

public class Enemymany : MonoBehaviour
{
[SerializeField] GameObject fire1;
[SerializeField] GameObject fire2;
[SerializeField] GameObject fire3;
[SerializeField] GameObject fire4;
[SerializeField] GameObject fire5;
[SerializeField] GameObject fire6;

int count = 0;

void Update()
{

if (Input.anyKeyDown)
{
count++;
}

if (count == 0)
{
//ゲームオブジェクト表示→非表示
fire1.SetActive(true);
fire2.SetActive(true);
fire3.SetActive(true);
fire4.SetActive(true);
fire5.SetActive(true);
fire6.SetActive(true);
}

if (count == 3)
{
//ゲームオブジェクト表示→非表示
fire1.SetActive(false);
fire2.SetActive(false);
fire3.SetActive(false);
fire4.SetActive(false);
fire5.SetActive(false);
fire6.SetActive(false);
}

if (count == 6)
{
count = 0;
}
}
}

人気の記事

1

コロナによる需要変化 コロナパンデミックの影響で、人々は外に出られなくなり、自宅で過ごす時間が増えました。 この自粛ムードの中、下記のようなビジネスの需要変化が引き起こされています。 【利用者減少】 ...

2

米国レストランの決済時に毎日お世話になっていた「Square」のビジネスモデルについて本日はふれていきたいと思います。 「Square」とは、ネットにつながったモバイル端末と専用のカードリーダーを用意 ...

3

無料でネットショップを開けるアプリとして多くの人に驚きを与えたBASE株式会社が、2019年10月25日東証マザーズに上場しました。2020年2月時点で90万店を超えるショップを抱えるまでに成長してい ...

4

2011年にサービスを開始してから圧倒的な成長率を誇るインテリア通販サイト 【FLYMEe/フライミー】を皆さんご存じでしょうか。 「自分のイメージするインテリア、本当に欲しいインテリアがどこにあるの ...

5

ナイキのSNKRSが、なぜこれほどまでに人気なのか?調べてみました。 きっかけは米国での友達との会話。彼は自分のシューズをみせて、「これ20万円もしたんだぜ。」と語ってくれました。 あまり靴に興味がな ...

-code, ソーシャル
-,

Copyright© BUSINESS HACKER , 2020 All Rights Reserved Powered by AFFINGER5.