//tips
//ダメージの付与
プレイヤーに棒を持たせて振らせることができたので、ダメージ判定も追加する。
Rodにweaponタグを設定し、下記スクリプトを追加しておく。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rodManager : MonoBehaviour
{
public float powerEnemy = 1; //攻撃力
}
Decoyを作成し、そちらにrodとの接触でダメージ判定を行うようにスクリプトを追加する。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Decoy : MonoBehaviour
{
[SerializeField]
private float hp = 3; //体力
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Weapon")
{
Debug.Log("hit Player");
hp -= other.gameObject.GetComponent<rodManager>().powerEnemy;
}
//体力が0以下になった時{}内の処理が行われる
if (hp <= 0)
{
Destroy(gameObject); //ゲームオブジェクトが破壊される
}
}
}
無事Decoyを消滅させられたのでHPも表示させる。Decoyの子要素にworldspaceのcanvasを設置し、スライダーを導入し、各値を調整。
UIは常にカメラの方を向くよう調整する必要があるので下記をcanvasに追加しておく。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HPUIRotateScript : MonoBehaviour
{
void LateUpdate()
{
// カメラと同じ向きに設定
transform.rotation = Camera.main.transform.rotation;
}
}
ここからダメージを受けた時にUI表示を更新するようにする。DecoyスクリプトにUI表示も絡めていく。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Decoy : MonoBehaviour
{
[SerializeField]
private float maxHp = 3; //体力
[SerializeField]
private float hp;
// HP表示用UI
[SerializeField]
private GameObject HPUI;
// HP表示用スライダー
private Slider hpSlider;
void Start()
{
hpSlider = HPUI.transform.Find("HPBar").GetComponent<Slider>();
hpSlider.value = 1f;
}
void Update()
{
hpSlider.value = hp / maxHp;
if (hp <= 0)
{
// HP表示用UIを非表示にする
HideStatusUI();
}
}
//HPUIを非表示にする
public void HideStatusUI()
{
HPUI.SetActive(false);
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Weapon")
{
Debug.Log("hit Player");
hp -= other.gameObject.GetComponent<rodManager>().powerEnemy;
}
//体力が0以下になった時{}内の処理が行われる
if (hp <= 0)
{
Destroy(gameObject); //ゲームオブジェクトが破壊される
}
}
}
//photonへのチャットの導入
謎の挙動は直っていないが、面白いコードを見つけたので、photonのシーンにチャットを導入していく。
空オブジェクトを作成し、ChatManagerと名付け、スクリプトをアタッチしていく。
using System.Collections.Generic;
using UnityEngine;
using System.Collections;
using Photon.Pun;
using Photon.Realtime;
[RequireComponent(typeof(PhotonView))]
public class InRoomChat : MonoBehaviourPunCallbacks
{
public Rect GuiRect = new Rect(0, 0, 250, 300);
public bool IsVisible = true;
public bool AlignBottom = false;
public List<string> messages = new List<string>();
private string inputLine = "";
private Vector2 scrollPos = Vector2.zero;
public static readonly string ChatRPC = "Chat";
public void Start()
{
if (this.AlignBottom)
{
this.GuiRect.y = Screen.height - this.GuiRect.height;
}
}
public void OnGUI()
{
if (!this.IsVisible || !PhotonNetwork.InRoom)
{
return;
}
if (Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.KeypadEnter || Event.current.keyCode == KeyCode.Return))
{
if (!string.IsNullOrEmpty(this.inputLine))
{
this.photonView.RPC("Chat", RpcTarget.All, this.inputLine);
this.inputLine = "";
GUI.FocusControl("");
return; // printing the now modified list would result in an error. to avoid this, we just skip this single frame
}
else
{
GUI.FocusControl("ChatInput");
}
}
GUI.SetNextControlName("");
GUILayout.BeginArea(this.GuiRect);
scrollPos = GUILayout.BeginScrollView(scrollPos);
GUILayout.FlexibleSpace();
for (int i = messages.Count - 1; i >= 0; i--)
{
GUILayout.Label(messages[i]);
}
GUILayout.EndScrollView();
GUILayout.BeginHorizontal();
GUI.SetNextControlName("ChatInput");
inputLine = GUILayout.TextField(inputLine);
if (GUILayout.Button("Send", GUILayout.ExpandWidth(false)))
{
this.photonView.RPC("Chat", RpcTarget.All, this.inputLine);
this.inputLine = "";
GUI.FocusControl("");
}
GUILayout.EndHorizontal();
GUILayout.EndArea();
}
[PunRPC]
public void Chat(string newLine, PhotonMessageInfo mi)
{
string senderName = "anonymous";
if (mi.Sender != null)
{
if (!string.IsNullOrEmpty(mi.Sender.NickName))
{
senderName = mi.Sender.NickName;
}
else
{
senderName = "player " + mi.Sender.UserId;
}
}
this.messages.Add(senderName + ": " + newLine);
}
public void AddLine(string newLine)
{
this.messages.Add(newLine);
}
}
コード内容の分解を行っていく。
今まで使ったことなかったが、Screen.width, heightでユーザーが見ている画面のサイズを取得することができ、このコードではそれで位置を設定している。
下記コードで画面サイズは簡単に取得できる。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScreenSizeTest : MonoBehaviour
{
private void Start()
{
Debug.Log("Screen Width : " + Screen.width);
Debug.Log("Screen height: " + Screen.height);
}
}
ちなみにRectは四角形のことでpublic Rect GuiRect = new Rect(0, 0, 250, 300);は、座標(x,y)に大きさ(width,height)の四角形を作ることを指す。
!this.IsVisible || !PhotonNetwork.InRoomは、初期ではtrueなはずのIsVisibleがtrueではないとき、または、ルームにいないときには後続の処理を実行しない。
Chatなどのスクリプトを記載する際にはフォーカスの操作も理解する必要があり、その記述がGUI.FocusControl(“”);にも現れている。
このフォーカスを外す、外さないなどで文字が消えるかどうかにも関係があるようなので、一旦フォーカス操作についても確認する。
Inputfieldを導入し、下記のスクリプトを作成。ボタンに実行させるためthis.text = “”;のみを記載しようとしたらエラーが出た。その要因はinfieldtextにアタッチしているthisの内容がClearTextコンポーネントを指し、inputfieldtextのことではないため。だから inputField = GetComponent<InputField>();で取り直す必要があった。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ClearText : MonoBehaviour
{
InputField inputField;
private void Start()
{
inputField = GetComponent<InputField>();
}
public void OnClear()
{
inputField.text = "";
//this.text = "";
}
}
このTextFieldに文字を打ったあとにボタンを押してもTextFieldの中身がクリアされていない場合があるようだが普通にクリアできるので、そういうこともあると頭に入れておく。
ここでのFocusControlはコントロール名でキーボードのフォーカスを移動させている。
FocusControlを理解する上で、重要だったのは void OnGUI()で、MonoBehaviour.OnGUI()を指し、自動的に呼び出されるものであるということ。メソッドと間違えて、呼び出しなどを行わない。
この場合UnityEngine.UI;も使用しないで呼び出せる。
using UnityEngine;
using System.Collections;
public class FocusControl : MonoBehaviour
{
void OnGUI()
{
//(new Rect(左上のx座標, 左上のy座標, 横幅, 縦幅), "テキスト", スタイル)
GUI.Label(new Rect(50, 50, 50, 50), "Hello."); //テキスト表示
if (GUI.Button(new Rect(50, 100, 100, 100), "World."))
{
Debug.Log("Hello,World!");
}
}
}
下記のようにテキストやボタンのスタイルも別途設定することができる。
public GUIStyle textStyle;
public GUIStyle buttonStyle;
void OnGUI(){
GUI.Label (new Rect (50, 50, 50, 50), "Hello.", textStyle);
GUI.Button(new Rect(50, 100, 50, 50),"World.", buttonStyle);
}
GUI.SetNextControlNameについてうまく理解できていないので下記を参考に試行中。
https://forum.unity.com/threads/simple-dynamic-list-editor.188202/#post-1512342
https://answers.unity.com/questions/799420/guifocuscontrol-guisetnextcontrolname-doesnt-work.html