質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

受付中

Unity 個別採取システムをつくりたい

Satsumaimo2020
Satsumaimo2020

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

0回答

0リアクション

0クリップ

177閲覧

投稿2022/08/07 03:08

編集2022/08/07 03:17

前提

Unityで箱庭系ゲームを作っています。今は木や石などを複数のキャラクターが順番に採取できるようなシステムを作っているのですが、一人目が採取を終えるとほかのまだ採取していたキャラクターたちが止まってしまいます。エラーは出ていません。

実現したいこと

・複数のキャラクターが指定した採取物を順番に採取する。
・採取をそれぞれ個別に終わらせる。

該当のソースコード

CharacterAIController

キャラクター操作の大本のスクリプト

C#

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using System.Linq; using System; public class CharacterAIController : MonoBehaviour { public enum State { Wait, Walk, Mine } //navMeshAgent [SerializeField] protected UnityEngine.AI.NavMeshAgent navMeshAgent; //State protected State state; //Animator [SerializeField] protected Animator anim; //移動する位置 protected List<Transform> targetPositions = new List<Transform>(); //次に移動する位置 protected int nowTargetPosition = 0; //目的地 private Transform destination; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } //Stateを変更する public void SetState(State state) { this.state = state; if(state == State.Wait) { anim.SetFloat("Walk", 0f); anim.SetBool("isMining", false); // elapsedTime = 0f; } else if(state == State.Walk) { anim.SetBool("isMining", false); SetNextPosition(); navMeshAgent.SetDestination(GetDestination().position); } else if(state == State.Mine) { anim.SetBool("isMining", true); } } //Stateを参照する public State GetState() { return state; } //セッター public void SetDestination(Transform position) { destination = position; } //ゲッター public Transform GetDestination(){ return destination; } //次の場所をセットする public void SetNextPosition() { SetDestination(targetPositions[nowTargetPosition]); if(!GetDestination().GetComponent<DestructibleObjectManager>().IsPartnerSet()) { GetDestination().GetComponent<DestructibleObjectManager>().SetPartner(gameObject); } else { if(targetPositions.Any()) { RemoveList(); SetNextPosition(); } } } protected void RemoveList() { targetPositions.Remove(GetDestination()); } }

CharacterMiningManager

採取用の継承スクリプト

C#

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using System.Linq; using System; public class CharacterMiningManager : CharacterAIController { //採取中かどうか private bool isMining = false; //なんかいヒットしたか private int mineHitCount; //経過した時間 private float elapsedTime; //採掘にかかる時間 [SerializeField] private float waitTime; // Start is called before the first frame update void Start() { SetState(State.Wait); mineHitCount = 0; } // Update is called once per frame void Update() { if(isMining) { Mining(); } } //採掘処理 private void Mining() { if(state == State.Walk) { anim.SetFloat("Walk", navMeshAgent.desiredVelocity.magnitude); elapsedTime = 0; if(navMeshAgent.remainingDistance < 2.7f) { mineHitCount = 0; SetState(State.Mine); } } else if(state == State.Wait) { elapsedTime += Time.deltaTime; navMeshAgent.velocity = Vector3.zero; if(elapsedTime > waitTime) { SetState(State.Walk); } } else if (state == State.Mine) { navMeshAgent.velocity = Vector3.zero; if(mineHitCount > 4) { SetState(State.Wait); RemoveList(); BreakDown(); } } if(!targetPositions.Any()) { FinishMining(); } } //採掘開始 public void MineStart(List<Transform> mineTargets) { targetPositions = mineTargets; isMining = true; SetState(State.Wait); } private void hitMine() { mineHitCount ++; } private void BreakDown() { GetDestination().GetComponent<DestructibleObjectManager>().ItemDrop(); Destroy(GetDestination().gameObject); } private void FinishMining() { isMining = false; SetState(State.Wait); } }

Mine

選した採取物をリストに入れてCharacterMiningManagerに送るスクリプト

C#

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System.Linq; public class Mine : MonoBehaviour { //採掘画面 [SerializeField] private GameObject MinePanel; [SerializeField] // private CharacterMiningManager cMM; private CharacterMiningManager[] cMMs; //選択した木とかのリスト private List<Transform> mineTargets = new List<Transform>(); // Start is called before the first frame update void Start() { MinePanel.SetActive(true); } // Update is called once per frame void Update() { //クリックしたオブジェクトをリストに入れる if(Input.GetButtonDown("Fire1")) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if(Physics.Raycast(ray, out hit)) { if(hit.collider.CompareTag("Destructible")) { Transform hitRoot = hit.transform.parent.parent.parent; int num = mineTargets.IndexOf(hitRoot); if(num >= 0) { mineTargets.Remove(hitRoot); Destroy(hitRoot.Find("MineIcon(Clone)").gameObject); } else { mineTargets.Add(hitRoot); Icon(hitRoot); } } } } } //採取を開始する public void MineButton() { //近い順に並べる var sort = mineTargets.OrderBy(a => Vector3.Distance(a.transform.position, transform.position)).ToList(); mineTargets = sort.ToList(); foreach (var cMM in cMMs) { cMM.MineStart(mineTargets); } } }

DestructibleObjectManager

採取物にパートナー設定をするスクリプト

C#

using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestructibleObjectManager : MonoBehaviour { public GameObject ItemObject; [SerializeField] private Item item; [Header("ドロップさせるアイテムの名前")] [SerializeField] private string ItemName; //パートナーがいるかどうか private bool isPartner = false; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } public void ItemDrop() { if(item.GetItemName() == ItemName) { for(int i = 0; i < item.GetAmount(); i++){ Instantiate(ItemObject, new Vector3(transform.position.x, transform.position.y + i, transform.position.z), Quaternion.identity); } } } public void SetPartner(GameObject partner) { Debug.Log("SetPartner"); Debug.Log(partner); Debug.Log(gameObject); isPartner = true; } public bool IsPartnerSet() { Debug.Log("IsPartnerSet" + gameObject); Debug.Log(isPartner); return isPartner; } }

試したこと

Debug.Logなどを用いてisMiningやリストのnull非null、パートナーは設定できているかなどを調べたところ、パートナーは設定できているのですが、一人目が採取を終えるとほかの人のリストもnullになっていて、isMiningがfalseになってしまっていました。

補足情報(FW/ツールのバージョンなど)

Unity 2020.3.26f1

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。