LoginSignup
0
0

Unityでのゲーム作り日記#13 ~アイテムの実装~

Last updated at Posted at 2024-02-19

前回の記事はこちら
今回は、アイテムを実装していきます。
アイテムとは、具体的に、
・攻撃力上昇
・体力回復
などを想定しています。
今回は攻撃力上昇だけを作ります。

スクリプト

新しく、OffensivePowerItemという名前でスクリプトを作ります。
コードは下のようにします。

OffensivePowerItem.cs
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); //アイテムを破壊
    }
}

全体のプログラムはこんな感じになります。↓

UnitScript.cs
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にはチェックをしてください。
CodeFightのコピー.png
最後に、MainCameraにアタッチされている、OnlineManager.csのOffensivePowerItemの欄にOffensivePowerItemプレファブを突っ込めば完成です。

次回は、アイテムをCSVから読み込む処理を実装します。
次回の記事はこちら

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0