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

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

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

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

Unity3D

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

Q&A

2回答

388閲覧

プレイヤーが敵から離れたときや敵が倒れた時に自動でロックオンを非表示にする方法

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity3D

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

0グッド

0クリップ

投稿2019/10/14 15:02

カメラのスクリプトは
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class CameraControllerVer : MonoBehaviour
{
public GameObject player;
public GameObject mainCamera;
public float rotate_speed;
private const int ROTATE_BUTTON = 2;
private const float ANGLE_LIMIT_UP = 60f;
private const float ANGLE_LIMIT_DOWN = -5f;
private LockOnTargetDetector lockOnTargetDetector;
[SerializeField]
public GameObject lockOnTarget;
protected LockonCursor lockonCursor;

void Start() { mainCamera = Camera.main.gameObject; player = GameObject.FindGameObjectWithTag("Player"); lockOnTargetDetector = player.GetComponentInChildren<LockOnTargetDetector>(); lockonCursor = GameObject.FindObjectOfType<LockonCursor>(); } void LateUpdate() { transform.position = player.transform.position; rotateCmaeraNaturalAngle(); if (Input.GetMouseButton(ROTATE_BUTTON)) { rotateCmaeraAngle(); } if (Input.GetButtonDown("Fire2")) { if (lockOnTarget == null) { // ロックオンターゲット取得 GameObject target = SetTargetClosestScreenCenter(); if (target != null) { lockOnTarget = target; lockonCursor.OnLockonStart(target.transform); } else { // 視点リセット iTween.RotateTo(gameObject, iTween.Hash( "rotation", player.transform.eulerAngles, "time", 0.5f )); } } else { // 既にターゲットが設定されていた場合は解除 lockOnTarget = null; lockonCursor.OnLockonEnd(); } } if (lockOnTarget) { lockOnTargetObject(lockOnTarget); } else { rotateCmaeraNaturalAngle(); if (Input.GetMouseButton(ROTATE_BUTTON)) { rotateCmaeraAngle(); } } float angle_x = 180f <= transform.eulerAngles.x ? transform.eulerAngles.x - 360 : transform.eulerAngles.x; transform.eulerAngles = new Vector3( Mathf.Clamp(angle_x, ANGLE_LIMIT_DOWN, ANGLE_LIMIT_UP), transform.eulerAngles.y, transform.eulerAngles.z ); } private void rotateCmaeraNaturalAngle() { Vector3 angle = new Vector3( Input.GetAxis("Angles X") * rotate_speed, Input.GetAxis("Angles Y") * rotate_speed, 0 ); transform.eulerAngles += new Vector3(angle.y, angle.x); } private void rotateCmaeraAngle() { Vector3 angle = new Vector3( Input.GetAxis("Mouse X") * rotate_speed, Input.GetAxis("Mouse Y") * rotate_speed, 0 ) ; transform.eulerAngles += new Vector3(angle.y, angle.x); } private void lockOnTargetObject(GameObject target) { transform.LookAt(target.transform, Vector3.up); } protected GameObject SetTargetClosestScreenCenter() { float search_radius = 15f; var hits = Physics.SphereCastAll( player.transform.position, search_radius, player.transform.forward, 0.01f, LayerMask.NameToLayer("LockonTarget") ).Select(h => h.transform.gameObject).ToList(); hits = FilterTargetObject(hits); if (0 < hits.Count()) { float min_target_distance = float.MaxValue; GameObject target = null; foreach (var hit in hits) { Vector3 targetScreenPoint = Camera.main.WorldToViewportPoint(hit.transform.position); float target_distance = Vector2.Distance( new Vector2(0.5f, 0.5f), new Vector2(targetScreenPoint.x, targetScreenPoint.y) ); Debug.Log(hit.gameObject + ": " + target_distance); if (target_distance < min_target_distance) { min_target_distance = target_distance; target = hit.transform.gameObject; } } return target; } else { return null; } } protected List<GameObject> FilterTargetObject(List<GameObject> hits) { return hits .Where(h => { Vector3 screenPoint = Camera.main.WorldToViewportPoint(h.transform.position); return screenPoint.x > 0 && screenPoint.x < 1 && screenPoint.y > 0 && screenPoint.y < 1; }) .Where(h => { foreach (var component in h.GetComponents<Component>()) { if (component is Enemy) { return true; } } return false; }) .ToList(); }

}
です。
ちなみに敵の位置を設定し距離でif文をかいたところNUllエラーになります。
どうすれば自動でロックオンを非表示にできるでしょうか?
回答よろしくおねがいします!

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

文の最後に
////////←のついている箇所が主な修正部分です

C#

1//Edited by kanotoP (2019/10/16-17:09) 2using System;//////// 3using System.Collections; 4using System.Collections.Generic; 5using UnityEngine; 6using System.Linq; 7 8public class CameraControllerVer : MonoBehaviour{ 9 public GameObject player; 10 public GameObject mainCamera; 11 public Single rotate_speed; 12 const Int32 ROTATE_BUTTON = 2; 13 const Single ANGLE_LIMIT_UP = 60f; 14 const Single ANGLE_LIMIT_DOWN = -5f; 15 const Single EYESIGHT = 10f;////////離れられる距離の最大 16 private LockOnTargetDetector lockOnTargetDetector; 17 [SerializeField]public GameObject lockOnTarget; 18 protected LockonCursor lockonCursor; 19 20 void Start(){ 21 mainCamera = Camera.main.gameObject; 22 player = GameObject.FindGameObjectWithTag("Player"); 23 lockOnTargetDetector = player.GetComponentInChildren<LockOnTargetDetector>(); 24 lockonCursor = GameObject.FindObjectOfType<LockonCursor>(); 25 } 26 27 ///<summary>Updateの後に呼び出されるメソッドです。呼び出し間隔に規定はありません</summary> 28 void LateUpdate(){ 29 transform.position = player.transform.position; 30 rotateCmaeraNaturalAngle(); 31 if (Input.GetMouseButton(ROTATE_BUTTON)){ 32 rotateCmaeraAngle(); 33 } 34 35 ////////lockOnTargetの座標を弄りたいならこの場所で 36 ////////lockOnTarget.transform.position = ≪新しい座標≫; 37 ////////としてください 38 39 if (lockOnTarget == null && Input.GetButtonDown("Fire2")){//////// 40 // ロックオンターゲット取得 41 GameObject target = SetTargetClosestScreenCenter(); 42 if (target != null){ 43 lockOnTarget = target; 44 lockonCursor.OnLockonStart(target.transform); 45 } 46 else{ 47 // 視点リセット 48 iTween.RotateTo(gameObject, iTween.Hash("rotation", player.transform.eulerAngles, "time", 0.5f)); 49 } 50 } 51 if (lockOnTarget != null && (Input.GetButtonDown("Fire2") || Vector3.Distance(lockOnTarget.transform.position, transform.position) > EYESIGHT /*|| "lockOnTargetが死んでいるか"の真偽値*/ )){//////// 52 // ロックオンターゲット解除 53 lockOnTarget = null; 54 lockonCursor.OnLockonEnd(); 55 } 56 if (lockOnTarget/*提示ソースには書かれていませんでしたが多分lockOntarget!=nullなのではないですか?*/) lockOnTargetObject(lockOnTarget);//////// 57 else{ 58 rotateCmaeraNaturalAngle(); 59 if (Input.GetMouseButton(ROTATE_BUTTON)) rotateCmaeraAngle(); 60 } 61 Single angle_x = 180f <= transform.eulerAngles.x ? transform.eulerAngles.x - 360 : transform.eulerAngles.x; 62 transform.eulerAngles = new Vector3( Mathf.Clamp(angle_x, ANGLE_LIMIT_DOWN, ANGLE_LIMIT_UP), transform.eulerAngles.y, transform.eulerAngles.z); 63 } 64 65 private void rotateCmaeraNaturalAngle(){ 66 Vector3 angle = new Vector3(Input.GetAxis("Angles X") * rotate_speed, Input.GetAxis("Angles Y") * rotate_speed, 0); 67 transform.eulerAngles += new Vector3(angle.y, angle.x); 68 } 69 70 private void rotateCmaeraAngle(){ 71 Vector3 angle = new Vector3(Input.GetAxis("Mouse X") * rotate_speed, Input.GetAxis("Mouse Y") * rotate_speed, 0) ; 72transform.eulerAngles += new Vector3(angle.y, angle.x); 73 } 74 75 private void lockOnTargetObject(GameObject target){ 76 transform.LookAt(target.transform, Vector3.up); 77 } 78 79 protected GameObject SetTargetClosestScreenCenter(){ 80 Single search_radius = 15f; 81 var hits = Physics.SphereCastAll(player.transform.position, search_radius, player.transform.forward, 0.01f, LayerMask.NameToLayer("LockonTarget")).Select(h => h.transform.gameObject).ToList(); 82 hits = FilterTargetObject(hits); 83 if (0 < hits.Count()){ 84 Single min_target_distance = Single.MaxValue; 85 GameObject target = null; 86 foreach (var hit in hits){ 87 Vector3 targetScreenPoint = Camera.main.WorldToViewportPoint(hit.transform.position); 88 Single target_distance = Vector2.Distance(new Vector2(0.5f, 0.5f), new Vector2(targetScreenPoint.x, targetScreenPoint.y)); 89 Debug.Log(hit.gameObject + ": " + target_distance); 90 if (target_distance < min_target_distance){ 91 min_target_distance = target_distance; 92 target = hit.transform.gameObject; 93 } 94 } 95 return target; 96 } 97 else{ 98 return null; 99 } 100 } 101 102 protected List<GameObject> FilterTargetObject(List<GameObject> hits){ 103 return hits.Where(h => { 104 Vector3 screenPoint = Camera.main.WorldToViewportPoint(h.transform.position); 105 return screenPoint.x > 0 && screenPoint.x < 1 && screenPoint.y > 0 && screenPoint.y < 1; 106 }).Where(h => { 107 foreach (var component in h.GetComponents<Component>()){ 108 if (component is Enemy){ 109 return true; 110 } 111 } 112 return false; 113 }).ToList(); 114 } 115}

投稿2019/10/16 08:23

KanazawaKureha

総合スコア368

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

提示コードが長すぎるので、やり方だけ書いておきます。

LateUpdateメソッド内に

C#

1//前略 2 3bool WasLiving=false; 4 5//中略 6 7LateUpdate(){ 8if(!/*ターゲットが生きているかどうかのフラグ*/&&WasLiving){ 9//ロックオンを解除する処理 10}//前回は生きていたのに、今は生きていない→つまり死んだときの処理 11 12if(lockOnTarget!=null&&(Vector3.Distance(player,lockOnTarget)>/*強制的にロックオンを解除するプレイヤーとターゲットの距離(定数)*/)){ 13//ロックオンを解除する処理 14}//距離が離れ過ぎたときの処理 15 16//中略 17 18WasLiving=/*ターゲットが生きているかどうかのフラグ*/; 19}

これで大丈夫だと思いますが、もしダメなら
・ソースコードは「`」×3で囲み、インデントを入れてください。
・メソッドや単位処理にそれぞれ何をしているのかコメントをもっと付けてください。
・ターゲットが倒れるというのは具体的に、”どの変数がどうなることを指すのか”を教えてください。

投稿2019/10/14 15:48

KanazawaKureha

総合スコア368

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/10/15 02:49 編集

とりあえず先に距離設定を行いたかったので設定しようとしたら Vector3 tmp=GameObject.Find("lockOnTarget").transform.position; LateUpdate() { if (lockOnTarget != null && Vector3.Distance(tmp, transform.position) > 10f) { lockOnTarget = null; lockonCursor.OnLockonEnd(); } } を追加しましたが NullReferenceException: Object reference not set to an instance of an object がでます。
KanazawaKureha

2019/10/15 02:22

エラーメッセージにはエラー箇所も記載されていると思いますが、どの箇所にエラーが発生しているのでしょうか?
退会済みユーザー

退会済みユーザー

2019/10/15 02:49 編集

Vector3 tmp=GameObject.Find("lockOnTarget").transform.position; ところです
KanazawaKureha

2019/10/15 11:01 編集

その箇所を Vector3 tmp; lockOnTarget=GameObject.Find(“lockOnTarget”); if(lockOnTarget!=null)tmp=lockOnTarget.transform.position; else tmp=null; と書き換えれば、その部分は解決です。 しかし、また他のところでエラーが発生するかも知れませんから、エラー箇所をif(≪nullになってそうなフィールド≫!=null){...}で囲んでみて下さい。
退会済みユーザー

退会済みユーザー

2019/10/15 11:59 編集

Cannot convert null to 'Vector3' because it is a non-nullable value type というエラーがでました else tmp = null;というところです
KanazawaKureha

2019/10/15 15:17

すみません、こちらのミスです。tmp=Vector3.zero;としたら動くと思います。(もし動作したら念のため座標0,0,0に異常がないか確認して下さい)
退会済みユーザー

退会済みユーザー

2019/10/16 00:42

すみませんもう一回まとめてもらってもよろしいでしょうか? 実はロックオンターゲット取得が消えたりして、こんがらがっています。
KanazawaKureha

2019/10/16 08:24

新たな回答を追加しました。 繰り返し言うようですが、インデントは入れて、```で文を囲みましょう
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問