前回の記事はこちら
今回は、アイテムを実装していきます。
アイテムとは、具体的に、
・攻撃力上昇
・体力回復
などを想定しています。
今回は攻撃力上昇だけを作ります。
スクリプト
新しく、OffensivePowerItemという名前でスクリプトを作ります。
コードは下のようにします。
using UnityEngine;
public class OffensivePowerItem : MonoBehaviour
{
public float increaseOffensivePower = 0.1f;
}
これだけです。
次に、UnitScript.csのUnitScriptクラスにfloat型offensivePowerという変数を定義します。
public float offensivePower = 0.3f;
さらに、offensivePowerを更新するためのメソッドChangeOffensivePowerを定義します。
[PunRPC] //忘れずに
private void ChangeOffensivePower(float newOffensivePower)
{
this.offensivePower = newOffensivePower;
}
そして、アイテムとぶつかった時の処理を書く、OnTriggerStay2Dを定義します。
(すでにOnCollisionStay2Dを定義していますが、今回はこっちのメソッドを使います。
OnTrigger〜〜とOnCollision〜〜の違いは
で解説されています。)
public void OnTriggerStay2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Item"))
{
Debug.Log("Itemと衝突!!");
OffensivePowerItem offensivePowerItem = collision.gameObject.GetComponent<OffensivePowerItem>(); //アイテムのスクリプトコンポーネントを取得
offensivePower += offensivePowerItem.increaseOffensivePower; //攻撃力を上げる
photonView.RPC("ChangeOffensivePower", RpcTarget.All, offensivePower); //攻撃力を更新
PhotonNetwork.Destroy(collision.gameObject); //アイテムを破壊
}
}
全体のプログラムはこんな感じになります。↓
using Photon.Pun;
using Photon.Realtime;
using Photon.Pun.UtilityScripts;
using System.Collections;
using System.Collections.Generic;
using Tokens;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public enum Team
{
Blue,
Red,
}
public class UnitScript : MonoBehaviour
{
public double speed;
public double angle;
public string code;
public Interpreter interpreter;
public string lang;
public Team team;
private int id;
public static int nowId = 0;
private bool isStarted = false;
new public Camera camera;
public float HP = 100f;
public Slider HPSlider;
public float offensivePower = 0.3f;
public PhotonView photonView;
// Start is called before the first frame update
void Start()
{
camera = GameObject.Find("Main Camera").GetComponent<Camera>();
Vector3 rotate = transform.eulerAngles;
rotate.z = (float)angle;
transform.eulerAngles = rotate;
}
// Update is called once per frame
void FixedUpdate()
{
if (isStarted)
{
if (lang == "Garnet")
transform.position += transform.right * -(float)speed * 1.0f; //���ł͑O��right�̔���
else if (lang == "Topaz")
transform.position += transform.right * -(float)speed * 1.5f;
else if (lang == "Turquoise")
transform.position += transform.right * -(float)speed * 0.75f;
}
HPSlider.value = HP;
photonView.RPC("ChangeHPValue", RpcTarget.All, HP);
if (HP <= 0) PhotonNetwork.Destroy(this.gameObject);
}
public void Rotate(double addAngle)
{
angle += addAngle;
}
public void setCodeAndLang(string code, string lang)
{
this.code = code;
this.lang = lang;
if (lang == "Garnet")
{
interpreter = new GarnetInterpreter(id);
}
else if (lang == "Topaz")
{
interpreter = new TopazInterpreter(id);
}
else if (lang == "Turquoise")
{
interpreter = new TurquoiseInterpreter(id);
}
else
{
throw new System.Exception("Please select right language.");
}
}
public void setTeam(Team unitTeam)
{
team = unitTeam;
photonView.RPC("ChangeTeam", RpcTarget.All, unitTeam);
//Debug.Log("Team:" + Team);
}
public void start()
{
gameObject.name = "Unit" + nowId;
id = nowId;
nowId++;
isStarted = true;
StartCoroutine("ExecuteAndWait");
}
private IEnumerator ExecuteAndWait()
{
while (true)
{
interpreter.execute(code);
Vector3 rotate = transform.eulerAngles;
rotate.z = (float)angle;
transform.eulerAngles = rotate;
yield return new WaitForSeconds(0.1f);
}
}
private void OnGUI()
{
Vector3 unitPosition = new Vector3(transform.position.x, -transform.position.y, transform.position.z);
Vector2 position = camera.WorldToScreenPoint(unitPosition + new Vector3(0.5f, -0.5f, 0f));
lang = GUI.TextArea(new Rect(position + new Vector2(0, -25), new Vector2(200, 25)), lang);
code = GUI.TextArea(new Rect(position, new Vector2(200, 200)), code);
if (!isStarted)
{
if (lang == "Garnet")
{
interpreter = new GarnetInterpreter(id);
}
else if (lang == "Topaz")
{
interpreter = new TopazInterpreter(id);
}
else if (lang == "Turquoise")
{
interpreter = new TurquoiseInterpreter(id);
}
}
}
[PunRPC]
private void ChangeTeam(Team newTeam)
{
this.team = newTeam;
}
[PunRPC]
private void ChangeHPValue(float newHp)
{
this.HP = newHp;
}
[PunRPC]
private void ChangeOffensivePower(float newOffensivePower)
{
this.offensivePower = newOffensivePower;
}
public void OnCollisionStay2D(Collision2D collision)
{
Debug.Log("衝突!!!");
if(collision.gameObject.CompareTag("Unit"))
{
Debug.Log("Unitと衝突!");
Debug.Log("相手: " + collision.gameObject.GetComponent<UnitScript>().team);
Debug.Log("自分: " + this.team);
UnitScript enemy = collision.gameObject.GetComponent<UnitScript>();
if (enemy.team != this.team)
{
Debug.Log("敵Unitに衝突!!!");
this.HP -= enemy.offensivePower;
photonView.RPC("ChangeHPValue", RpcTarget.All, HP);
}
}
}
public void OnTriggerStay2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Item"))
{
Debug.Log("Itemと衝突!!");
OffensivePowerItem offensivePowerItem = collision.gameObject.GetComponent<OffensivePowerItem>();
offensivePower += offensivePowerItem.increaseOffensivePower;
photonView.RPC("ChangeOffensivePower", RpcTarget.All, offensivePower);
PhotonNetwork.Destroy(collision.gameObject);
}
}
}
OnlineManager.csのOnlineManagerクラスに次のようにパブリック変数を定義します。
public GameObject OffensivePowerItem;
最後にOnlineManager.csのOnlineManagerクラスのStartManagerメソッドの最後の方に次のコードを追加するとアイテムを生成できます。
if (photonView.IsMine)
PhotonNetwork.Instantiate(OffensivePowerItem.name, Vector3.zero, Quaternion.identity);
Unitの設定
新しく、OffensivePowerItemというプレファブを作ってください。見た目はご自由に。
このように設定してください。ただし、CircleCollider2Dは別のコライダーでも構いません。IsTrrigerにはチェックをしてください。
最後に、MainCameraにアタッチされている、OnlineManager.csのOffensivePowerItemの欄にOffensivePowerItemプレファブを突っ込めば完成です。
次回は、アイテムをCSVから読み込む処理を実装します。
次回の記事はこちら