前提・実現したいこと
現在、unityでカービィ64のようなWaypointをたどるタイプの疑似3Dスクロールの開発をしています
それに伴い、発射した弾丸がWaypointに沿うように移動するプログラムを開発したいのですが、本体に使っていたWaypointを辿るプログラムをそのまま使い回すと、発射した弾丸が何故か2つになり、その場で静止してしまいます(二発目以降はまっすぐにのみ飛んでいく(waypoint無視)
逆に、玉本体にプログラムを設定しなかった場合は突っかかる事はありませんが、Waypointに沿う事なくまっすぐ飛んでいきます
これはあくまで私個人の憶測なのですが、今使っているプログラムがinstanceのオブジェクトには対応していないと考えています
今後敵の操作等もプレハブで発生させたものをWaypointで管理したいのでかなり重大な問題です
WaypointをInstanceに適用することはできないのでしょうか
発生している問題・エラーメッセージ(弾丸にメソッド適用時のみ)
NullReferenceException: Object reference not set to an instance of an object LineTrace.DirectionController2d.set_direction (LineTrace.Direction value)
該当のソースコード
キャラ本体側のスクリプト
using System.Collections; using System.Collections.Generic; using UnityEngine; using LineTrace; public class nita2dmove : MonoBehaviour { public DirectionController2d controller; public float speed; private Rigidbody rb; //キャラクターのコライダ private CapsuleCollider myCollider; private bool isGrounded; private float bulletspeed = 500f;//弾速 //ジャンプ力 [SerializeField] private float jumppower = 5f; private Vector3 velocity; // Start is called before the first frame update [SerializeField] private GameObject bulletPrefab; private float power = 10f; public Transform shotpoint;//弾丸発射地点 void Start() { rb = GetComponent<Rigidbody>(); myCollider = GetComponent<CapsuleCollider>(); controller.direction = Direction.front; } // Update is called once per frame void Update() { CheckGround(); Jump(); Move(); Fire(); } private void Move() { if (Input.GetKey(KeyCode.LeftArrow)) { // 向きを設定する controller.direction = Direction.back; rb.MovePosition(transform.position + controller.forward * speed * Time.deltaTime); } else if (Input.GetKey(KeyCode.RightArrow)) { // 向きを設定する controller.direction = Direction.front; rb.MovePosition(transform.position + controller.forward * speed * Time.deltaTime); //controller.forward*speed=velocity } } private void Jump(){ if (isGrounded) { if (Input.GetButtonDown("Jump")) { isGrounded = false; rb.velocity = new Vector3(rb.velocity.x, jumppower, rb.velocity.z); } } } private void Fire() { if (Input.GetKeyUp(KeyCode.Z)) { var bulletInstance = Instantiate<GameObject>(bulletPrefab, shotpoint.position, shotpoint.rotation); bulletInstance.GetComponent<Rigidbody>().AddForce(bulletInstance.transform.position+controller.forward * bulletspeed); Destroy(bulletInstance, 5f); } } private void CheckGround() { if (isGrounded) { return; } if (Physics.CheckSphere(rb.position, myCollider.radius - 0.1f, LayerMask.GetMask("Ground"))) { isGrounded = true; velocity.y = 0f; }else{ isGrounded = false; } } }
Waypointに沿って方向転換するスクリプト
using UnityEngine; using UniRx; using UniRx.Triggers; namespace LineTrace { public class DirectionController2d : MonoBehaviour { /// <summary> /// 正面ベクトル /// </summary> public Vector3 forward { get; private set; } private Direction mDirection; /// <summary> /// 向いている方向 /// </summary> public Direction direction { get { return mDirection; } set { mDirection = value; var f = (current.GetWayPointByDirection(mDirection) - transform.position); f.y = 0F; forward = f.normalized; } } private Line current; [SerializeField] private float distance = 0.1F; [SerializeField] private bool autoRotation = false; [SerializeField] private float rotateSpeed = 30F; // Use this for initialization void Start() { var lineManager = FindObjectOfType<LineManager>(); current = lineManager.GetLineAtNearDistance(transform.position); this.UpdateAsObservable() // 目的のポイントに接近したかどうか .Where( _ => Mathf.Abs(Vector2.Distance(transform.position.XZ(), current.GetWayPointByDirection(mDirection).XZ())) < distance) .Subscribe(_ => { var next = current.GetNextLineByDirection(mDirection); current = next ?? current; direction = mDirection; }); // 目的地の方向に自動で回転する if (autoRotation) { this.UpdateAsObservable() .Where(_ => forward != Vector3.zero) .Subscribe(_ => { var arrivedForward = forward.XZ(); var cross = transform.forward.XZ().Cross(arrivedForward); var dot = Vector2.Dot(transform.forward.XZ(), arrivedForward); if (dot < 0.98F) { transform.Rotate(Vector3.down, rotateSpeed * Mathf.Sign(cross) * Time.deltaTime); } }); } } } public enum Direction { front, back, none } }
適用すると悪化する弾丸側スクリプト
using System.Collections; using System.Collections.Generic; using UnityEngine; using LineTrace; public class protbsllet : MonoBehaviour { private DirectionController2d controller; private Vector3 velocity; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } }
試したこと
玉本体の回転固定と解除
玉本体の質量の変更
Waypointの位置の変更
玉本体にスクリプトの設定と解除
補足情報(FW/ツールのバージョンなど)
シーンから弾は取り除き済み
Waypointのスクリプト等は
Unityで3D横スクロールの挙動を考える
こちらのサイト様のものをほぼそのままお借りしています
回答1件
あなたの回答
tips
プレビュー