Skip to content

Instantly share code, notes, and snippets.

@kuma360
Last active June 19, 2018 04:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kuma360/144d1145aca2fca10a08dd690a8b2636 to your computer and use it in GitHub Desktop.
Save kuma360/144d1145aca2fca10a08dd690a8b2636 to your computer and use it in GitHub Desktop.
「#Unity1Week」で作った「ポートアイランド付近連続殺人事件」( https://unityroom.com/games/portopia )のソースコードです。
//「#Unity1Week」で作った「ポートアイランド付近連続殺人事件」(https://unityroom.com/games/portopia)のソースコードです。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
public class rootScript : MonoBehaviour {
//背景
public GameObject _back;
//キャラクター
public GameObject _actor;
//選択肢のところにでる白い枠
public Image _hover;
//背景の画像リスト
public Sprite[] _backList;
//キャラクターの画像リスト
public Sprite[] _actorList;
//音データ
public AudioSource[] _se;
//選択肢テキスト
private Text _commandBox;
//本文テキスト
private Text _messageBox;
//本文の表示速度
private static readonly float MESSAGE_SPEED = 10;
//シナリオの進行管理
private int _senarioStep = -1;
//シナリオの中の項目のステップ管理
private int _senarioSubStep = 0;
//シナリオ切替時には0以外を設定。
private int _senarioNext = 0;
//本文を読み進めるときはtrueにする。
private bool _read = false;
//カレントになってるシナリオの情報
private String[] _currentSenaio = null;
//本文として表示するメッセージ
private String _targetMessage = "";
//前フレームで表示したメッセージ
private String _lastMessage = "";
//メッセージを一文字ずつ表示するためのタイマー
private float _messageTimer = 0;
//現在居る場所を管理(使ってない)
private String _nowPosition = "";
//メッセージ表示が完了したらtrue
private bool _compMessage = false;
//選択肢のリスト
private List<String> _command = new List<String>();
//選択肢表示欄をリフレッシュしたいときはtrue
private bool _commandRefresh = false;
//TOP選択肢からどれを選んだか。
private int _topCommandSelect = -1;
//SUB選択肢からどれを選んだか。
private int _subCommandSelect = -1;
//特定のシナリオを読んだかどうか管理するためのフラグ。2進数のビットフラグとして使う。
private int _flg1 = 0;
private int _flg2 = 0;
void Start() {
//フォントをぼかさないようにする。選択肢用
_commandBox= GameObject.Find("Command").GetComponent<Text>();
_commandBox.font.material.mainTexture.filterMode = FilterMode.Point;
//フォントをぼかさないようにする。本文用
_messageBox = GameObject.Find("Message").GetComponent<Text>();
_messageBox.font.material.mainTexture.filterMode = FilterMode.Point;
}
//背景の絵をセットする
private void setBack(int I) {
if ( I==-1 ) {
_back.SetActive(false);
return;
}
_back.SetActive(true);
_back.GetComponent<Image>().sprite = _backList[I];
}
//キャラクターの立ち絵をセットする
private void setActor(int I) {
if ( I==-1 ) {
_actor.SetActive(false);
return;
}
_actor.SetActive(true);
_actor.GetComponent<Image>().sprite = _actorList[I];
}
//シナリオを読み進める。
private void ReadSenario() {
//readフラグが立ってたらシナリオを読む
if ( !_read ) {
return;
}
_read = false;
//サブシナリオの最後ならそこで止まる
++_senarioSubStep;
if ( _currentSenaio.Length <= _senarioSubStep ) {
return;
}
var now = _currentSenaio[_senarioSubStep];
//フラグ1が揃ったら特定のシナリオへジャンプ
if ( now.StartsWith("[flg1]")) {
var sep = now.Split(',');
_flg1 |= ToInt(sep[1]);
if ( _flg1 == 0x1F ) {
_flg1 = 0;
_senarioNext = 200;
}
_read = true;
return;
}
//フラグ2が揃ったら特定のシナリオへジャンプ
if ( now.StartsWith("[flg2]")) {
var sep = now.Split(',');
_flg2 |= ToInt(sep[1]);
if ( _flg2 == 0x1F ) {
_flg2 = 0;
_senarioNext = 300;
}
_read = true;
return;
}
//場所情報の更新
if ( now.StartsWith("[spot]") ) {
var sep = now.Split(',');
setBack(ToInt(sep[1]));
setActor(ToInt(sep[2]));
_nowPosition = sep[3];
_read = true;
return;
}
//選択肢を開始
if ( now.StartsWith("[command]") ) {
var sep = now.Split(',');
_messageTimer = 0;
_targetMessage = sep[0].Replace("[command]","");
for ( int I=1 ; I<sep.Length ; ++I ) {
_command.Add(sep[I]);
}
_topCommandSelect = -1;
_subCommandSelect = -1;
_commandRefresh = true;
return;
}
{//カレントメッセージを変更
_messageTimer = 0;
_targetMessage = now;
}
}
//_senarioNextがセットされていたら、特定のシナリオへ進む。
private void NextSenario() {
if ( 0 <= _senarioNext && _senarioStep != _senarioNext ) {
_senarioStep = _senarioNext;
_senarioSubStep = -1;
_senarioNext = -1;
_compMessage = false;
_read = true;
_currentSenaio = senarioDic[_senarioStep];
_command.Clear();
_topCommandSelect = -1;
_subCommandSelect = -1;
_commandRefresh = true;
}
}
//選択肢の表示を更新する。
private void CommandRefesh() {
if ( !_commandRefresh ) {
return;
}
_commandRefresh = false;
try {
//TOPの選択肢、SUBの選択肢、共に選択されたら、選択肢を決定したとみなす。
if ( -1!=_topCommandSelect && -1!=_subCommandSelect ) {
var tmp1 = _command[_topCommandSelect].Split('/');
var tmp2 = tmp1[_subCommandSelect+1].Split(':');
var commandValue = tmp2[1];
//戻るコマンド
if ( commandValue == "_" ) {
_topCommandSelect = -1;
_subCommandSelect = -1;
_commandRefresh = true;
return;
}
//次のシナリオへ
_senarioNext = ToInt(commandValue);
return;
}
//TOP選択肢を列挙
if (-1==_topCommandSelect)
{
String text = "";
for ( int I=0 ; I<_command.Count ; ++I ) {
var tmp = _command[I].Split('/')[0];
text += tmp + "\n";
}
_commandBox.text = text;
return;
}
{//TOP選択肢が選択されたら、SUB選択肢を列挙。
var target = _command[_topCommandSelect].Split('/');
String text = "";
for ( int I=1 ; I<target.Length ; ++I ) {
text += target[I].Split(':')[0] + "\n";
}
_commandBox.text = text;
return;
}
} catch {
_topCommandSelect = -1;
_subCommandSelect = -1;
_commandRefresh = true;
return;
}
}
private void Controll() {
int hoverPosition = -1;
{//選択肢のところにマウスがあるときは白い枠を表示
if (0<_command.Count) {
if ( 425 < Input.mousePosition.x ) {
hoverPosition = (int)(( (600 - Input.mousePosition.y) - 10 ) / 60);
}
}
if ( 6 < hoverPosition ) {
hoverPosition = -1;
}
if (0<=hoverPosition) {
var C = _hover.color;
C.a += (.5f - C.a) * .1f;
_hover.color = C;
var P = _hover.GetComponent<RectTransform>().localPosition;
P.y = (300 - (hoverPosition * 60 + 10));
_hover.GetComponent<RectTransform>().localPosition = P;
} else {
var C = _hover.color;
C.a += (0 - C.a) * .1f;
_hover.color = C;
}
}
//クリック操作
if (Input.GetMouseButtonDown(0)) {
Debug.Log("senario:"+_senarioStep+" mouse:"+Input.mousePosition);
//選択肢が表示されてないときはどこをクリックしても良い。
if ( _command.Count <= 0 ) {
if ( _compMessage ) {
_read = true;
} else {
_messageTimer = int.MaxValue;
}
return;
}
//選択肢を選ぶ操作
if ( 0<=hoverPosition ) {
//TOP選択肢
if ( -1 == _topCommandSelect ) {
_se[1].PlayOneShot(_se[1].clip);
_topCommandSelect = hoverPosition;
_commandRefresh = true;
} else
//SUB選択肢
{
_se[1].PlayOneShot(_se[1].clip);
_subCommandSelect = hoverPosition;
_commandRefresh = true;
}
}
//背景部分をクリックすると、詳細を調べられる。
var M = Input.mousePosition;
try {
foreach(var A in searchDic[_senarioStep]) {
var B = A.Split(',');
var sx = ToInt(B[0]);
var sy = ToInt(B[1]);
var ex = ToInt(B[2]);
var ey = ToInt(B[3]);
var dat = B[4];
if ( sx<M.x && M.y<sy && M.x<ex && ey<M.y ) {
_messageTimer = 0;
_targetMessage = dat;
break;
}
}
} catch {
}
}
}
//Intパース何回もやるので。
private int ToInt(String dat) {
try {
int val = 0;
int.TryParse(dat,out val);
return val;
} catch {
return 0;
}
}
//毎フレーム実行するやつ。
void Update () {
//次のシナリオへ
NextSenario();
//シナリオを読む
ReadSenario();
//コマンド更新
CommandRefesh();
{//メッセージを一文字ずつ表示。
_messageTimer += Time.deltaTime;
int value = (int)Math.Min(_targetMessage.Length,_messageTimer * MESSAGE_SPEED);
var nowMessage = _targetMessage.Substring(0,value);
_messageBox.text = nowMessage;
_compMessage = (_targetMessage.Length <= value);
if ( 0 < nowMessage.Length && nowMessage!=_lastMessage) {
_se[0].PlayOneShot(_se[0].clip);
}
_lastMessage = nowMessage;
}
//操作
Controll();
}
//メインシナリオの情報
//spot→背景とキャラ指定
//command→コマンド選択
//search→虫眼鏡コマンド
static Dictionary<int,String[]> senarioDic = new Dictionary<int,String[]>() {
{0,new String[] {
"[spot],8,4,はなくまちょう",
"ポートアイランド付近連続殺人事件",
"こんにちは、あなたの部下のアレです。\nアレって呼んでください。",
"殺人事件がおきたので現場にいきましょう。\n",
"[command]コマンドを選択してください,いどう/もどる:_/被害者の家:10"
}},
{10,new String[] {
"[spot],1,-1,被害者の家",
"ここが、ころされた富豪さんのお屋敷です。\n",
"ハーバーランドの一角にあります。\numieとかMOSAICの隣です。",
"[command]コマンドを選択してください,いどう/もどる:_/玄関ホール:20"
}},
{20,new String[] {
"[spot],10,4,玄関ホール",
"屋敷の住人に集まってもらっています。\nでも、まずは現場を確認しましょう。\n",
"[command]コマンドを選択してください,いどう/もどる:_/書斎:30"
}},
{30,new String[] {
"[spot],9,-1,書斎",
"ここが現場ですね\n",
"富豪さんは、後頭部から血を流し\n倒れていたそうです。",
"現場の状況から他殺と思われますが、\n凶器はまだ見つかっていません。",
"[command]コマンドを選択してください,いどう/もどる:_/玄関ホール:40"
}},
{40,new String[] {
"[spot],10,-1,玄関ホール",
"富豪邸玄関ホールに戻ってきました。\n",
"[command]コマンドを選択してください,みる/もどる:_/集まってる人達:50"
}},
{50,new String[] {
"[spot],10,4,玄関ホール",
"富豪邸で暮らすご家族や使用人の方がおられますね。\n",
"左から順に富豪妻子さん、富豪兄吉さん、富豪姉実さん、富豪娘子さんと、使用人のさわきふみえさんです。",
"兄吉さんと姉実さんはどちらも被害者とは血がつながっていないそうです。",
"[command]コマンドを選択してください,きく/もどる:_/義理義理なのか?:60"
}},
{60,new String[] {
"[spot],10,4,玄関ホール",
"そうですね。義理の兄と、義理の姉だそうです。",
"[command]コマンドを選択してください,きく/もどる:_/妻子:100/兄吉:110/姉実:120/娘子:130/ふみえ:140"
}},
{90,new String[] {
"[spot],10,4,玄関ホール",
"富豪邸玄関ホールです。",
"[command]コマンドを選択してください,きく/もどる:_/妻子:100/兄吉:110/姉実:120/娘子:130/ふみえ:140"
}},
{100,new String[] {
"[spot],10,1,玄関ホール",
"ああ…。あの人が殺されてしまうなんて…。\n私辛くて悲しくて…。絶対に犯人を捕まえてください。",
"[flg1],1",
"[command]コマンドを選択してください,きく/もどる:_/妻子:100/兄吉:110/姉実:120/娘子:130/ふみえ:140"
}},
{110,new String[] {
"[spot],10,5,玄関ホール",
"弟が殺されちゃうなんてね。ビックリしたよ。ほんとに。",
"[flg1],2",
"[command]コマンドを選択してください,きく/もどる:_/妻子:100/兄吉:110/姉実:120/娘子:130/ふみえ:140"
}},
{120,new String[] {
"[spot],10,0,玄関ホール",
"新しい事業を起こすって、バタバタしてた矢先だったのにね。できる男だけど、たまにタイミングが悪いんだよ。あいつはさ。",
"[flg1],4",
"[command]コマンドを選択してください,きく/もどる:_/妻子:100/兄吉:110/姉実:120/娘子:130/ふみえ:140"
}},
{130,new String[] {
"[spot],10,2,玄関ホール",
"…仕事熱心で、家族思いの自慢の父だったんです。お父さん…。",
"[flg1],8",
"[command]コマンドを選択してください,きく/もどる:_/妻子:100/兄吉:110/姉実:120/娘子:130/ふみえ:140"
}},
{140,new String[] {
"[spot],10,3,玄関ホール",
"旦那様は忙しい人でしたので、あまりお話したことはありませんでした。でも…",
"私、妻子さんや娘子さんが悲しんでる姿を見るのが辛くて…。",
"[flg1],16",
"[command]コマンドを選択してください,きく/もどる:_/妻子:100/兄吉:110/姉実:120/娘子:130/ふみえ:140"
}},
{200,new String[] {
"[spot],10,4,玄関ホール",
"どうも僕です。",
"富豪氏は新しい事業を始めようとした矢先に殺されてしまったというわけですね。",
"かなり人望もあり恨まれるような人物ではなかったみたいですが…",
"…富豪邸のあるハーバーランドには、色んなお店がありますね。",
"なにか知っている人が居るかもしれません。行ってみませんか?",
"[command]コマンドを選択してください,いどう/もどる:_/ハーバーランド:210"
}},
{210,new String[] {
"[spot],6,-1,umie",
"ハーバーランドにあるショッピングモール「umie」の前です。",
"[command]コマンドを選択してください,いどう/もどる:_/MOSAIC:220/カプリチョーザ:230/串家物語:240/バター:250/ア・デペシュ:260/元町ドリア:270"
}},
{220,new String[] {
"[spot],7,-1,MOSAIC",
"MOSAICの前です。こちらも素敵なショッピングモールですね。",
"[command]コマンドを選択してください,いどう/もどる:_/umie:210/カプリチョーザ:230/串家物語:240/バター:250/ア・デペシュ:260/元町ドリア:270"
}},
{230,new String[] {
"[spot],2,-1,カプリチョーザ",
"ここがカプリチョーザです。チェーン店ですが、美味しいイタリア料理を楽しめます。山盛りのパスタが嬉しいですね。",
"[flg2],1",
"[command]コマンドを選択してください,いどう/もどる:_/MOSAIC:220/カプリチョーザ:230/串家物語:240/バター:250/ア・デペシュ:260/元町ドリア:270"
}},
{240,new String[] {
"[spot],3,-1,串家物語",
"ここが串家物語です。リーズナブルな価格で色んな串料理を自分で揚げて楽しむことができる素敵なお店です。一口サイズのデザートも最高。",
"[flg2],2",
"[command]コマンドを選択してください,いどう/もどる:_/MOSAIC:220/カプリチョーザ:230/串家物語:240/バター:250/ア・デペシュ:260/元町ドリア:270"
}},
{250,new String[] {
"[spot],4,-1,バター",
"ここがバターです。北海道産の薫り高い発酵バターをふんだんにつかったパンケーキは一食の価値ありです。",
"[flg2],4",
"[command]コマンドを選択してください,いどう/もどる:_/MOSAIC:220/カプリチョーザ:230/串家物語:240/バター:250/ア・デペシュ:260/元町ドリア:270"
}},
{260,new String[] {
"[spot],5,-1,ア・デペシュ",
"ここがア・デペシュです。シックな雑貨や食器を取り揃えています。個性あふれる作家さんの商品を購入できるのも魅力ですね。",
"[flg2],8",
"[command]コマンドを選択してください,いどう/もどる:_/MOSAIC:220/カプリチョーザ:230/串家物語:240/バター:250/ア・デペシュ:260/元町ドリア:270"
}},
{270,new String[] {
"[spot],11,-1,元町ドリア",
"ここが神戸元町ドリアです。いやー美味しいですね。程よく色づいたホワイトソースって最高ですよね。",
"[flg2],16",
"[command]コマンドを選択してください,いどう/もどる:_/MOSAIC:220/カプリチョーザ:230/串家物語:240/バター:250/ア・デペシュ:260/元町ドリア:270"
}},
{300,new String[] {
"[spot],7,4,MOSAIC",
"どうも僕です。",
"いやー色んな物食べましたね。",
"[command]コマンドを選択してください,いどう/もどる:_/いえに帰る:310"
}},
{310,new String[] {
"[spot],0,4,いえじ",
"僕思ったんですけど…",
"全部美味しくて、雑貨も豊富で神戸って最高じゃないですか?",
"近くに引っ越したほうが良くないですか?",
"[command]あ、ポートタワー見えますね。かっこいい。,はなす/もどる:_/そうだね:320"
}},
{320,new String[] {
"[spot],0,4,いえ",
"そういえば、僕新しい事業のアイデア思いついたんですけど、一緒にやりませんか?",
"[command]成功したら、近くに土地を買って豪遊しましょうよ。,はなす/もどる:_/うん:330"
}},
{330,new String[] {
"[spot],8,4,いえ",
"それにしても、犯人全然わかんなかったですね。",
"[command]でも、今日は楽しかったんで、もう捜査やめろと命令してください。,はなす/もどる:_/捜査やめろ:340/お前じゃないの?:350",
}},
{340,new String[] {
"[spot],8,-1,いえ",
"お疲れ様でしたー。",
"ポートアイランド付近連続殺人事件",
"[command]おわり,最初から/もどる:_/やりなおす:0",
}},
{350,new String[] {
"[spot],8,4,いえ",
"あ、バレてたんですね。やべー。",
"ポートアイランド付近連続殺人事件",
"[command]おわり,最初から/もどる:_/やりなおす:0",
}},
};
//背景をクリックしたときに表示されるメッセージ
static Dictionary<int,String[]> searchDic = new Dictionary<int,String[]>() {
{0,new String[] {
"219,541,275,504,僕のとんがり部分です。チャームポイントです。",
"25,290,163,181,しげみですね。",
"25,597,163,290,閑静な住宅街です。",
"307,597,423,181,閑静な住宅街です。",
"164,597,307,181,本名はアンドレって言います。アレって呼んでください。",
}},
{10,new String[] {
"308,576,425,303,ちかくにMOSAICというショッピングモールが見えます。",
"25,576,70,509,えんとつがあるなんて凄くないですか。",
"73,521,191,443,なぞ形状。",
"110,290,266,181,かなり頑丈な鉄の門があります。指輪とかそういったたぐいのものは落ちていませんでした。",
"22,300,110,181,立派な生垣です。きちんと手入れされています。",
"260,300,422,181,立派な生垣です。きちんと手入れされています。",
}},
{20,new String[] {
"197,477,336,186,僕でーす。",
"126,552,231,460,シャンデリアがある。完全にお金持ちですね。",
"82,356,266,240,殺人現場は2階の書斎です。この階段を上がっていきましょう。",
"297,330,417,232,屋敷の住人が集まっています。",
"81,490,161,400,山の絵が飾ってあります。これは何処でしょうね?",
}},
{30,new String[] {
"45,360,230,290,机と椅子も高級そうです。",
"26,580,420,325,かなりの数の本に囲まれています。読書家なんですね。",
"162,260,195,235,1って書いてあります。",
"74,218,110,205,2って書いてあります。",
"362,212,390,190,3って書いてあります。",
"210,276,396,219,富豪さんはここで死んでいました。",
}},
{40,new String[] {
"126,552,231,460,三段重ねの高級シャンデリアですよ。綺麗ですねコレ。",
"82,356,266,240,殺人現場は2階の書斎です。",
"297,330,417,232,屋敷の住人が集まっています。",
"81,490,161,400,でっかい山の絵ですね。",
}},
{100,new String[] {
"194,370,256,278,夫をなくして、悲しそうです。",
"152,419,287,300,髪型どうなってるんでしょうか。",
"168,269,315,178,着物を着こなしています。",
}},
{110,new String[] {
"199,433,331,298,義理の兄だそうです。あまり悲しんでいる様には見えないですね。",
"168,269,315,178,ユニクロのシャツです。",
}},
{120,new String[] {
"199,433,331,298,義理の姉だそうですが、亡くなった富豪さんと一緒に仕事をすることもあったみたいです。",
"168,269,315,178,ユニクロのシャツではないです。",
}},
{130,new String[] {
"199,433,331,298,中学生くらいでしょうか。お父さんとは仲が良かったみたいですね。",
"168,269,315,178,ユニクロのシャツです。",
}},
{140,new String[] {
"199,433,331,298,メイドさんだぜ。イェー。テンション上がりますね。",
"168,269,315,178,ユニクロのシャツではないです。",
}},
{210,new String[] {
"25,344,70,229,木",
"23,577,131,264,たしかこのビルもumieの一部です。",
"127,421,370,252,umieです。オシャレですねー。",
"196,578,421,430,いい天気。",
}},
{220,new String[] {
"26,300,129,253,草",
"212,292,421,182,水面が見えますよ。いい感じですね。",
"336,572,428,444,観覧車まであるんですね。",
"25,580,302,450,MOSAICです。",
"21,456,302,316,オシャレな店が軒を連ねています。",
}},
{230,new String[] {
"37,498,96,448,カプリ照明",
"83,411,237,235,カプリ入り口",
"296,414,350,221,カプ看板",
"362,413,424,270,カプリ窓",
"279,522,422,423,カプ屋根",
}},
{240,new String[] {
"91,537,149,453,なにから食べようかなー",
"41,354,182,207,ししとう串と牛肉串ですね。",
"191,400,234,288,しいたけ串、じゃがいも串、えび串。",
"248,438,380,362,れんこん串、チーズ串ですかね。",
"278,578,421,422,デザートも楽しいんですよ。",
}},
{250,new String[] {
"265,326,424,175,牛の置物が目印になってます。",
"74,480,151,270,ここ、惣菜系パンケーキも美味しいんですよ。サーモンとアボカドのパンケーキとか。",
"197,474,328,343,店内では、数組のお客さんが食事を楽しんでいます。",
}},
{260,new String[] {
"24,475,183,318,作家さんの個性的な商品を購入できます。",
"194,387,420,267,なんだか線の細い家具が沢山取り揃えられています。",
"22,579,415,458,落ち着きのある照明がシックな空間を演出しています。",
}},
{270,new String[] {
"166,309,282,221,美味しいドリアでーっす。",
"241,568,395,317,僕です。",
}},
{300,new String[] {
"158,517,335,180,お腹いっぱいです。もう食べられないです。",
}},
{340,new String[] {
"27,572,424,181,果たして真犯人は誰だったのか。私の中にはモヤモヤとした物が残ったのだった。",
}},
{350,new String[] {
"219,541,275,504,僕のとんがり部分です。今日もキマってますね。",
"25,290,163,181,捕まっちゃうと何気ない風景も違って見えますね。ヤベー。",
"25,597,163,290,静かですねー。",
"307,597,423,181,逃げようかな。",
"164,597,307,181,犯人で御座います。ヤバイですね。",
}},
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment