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

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

新規登録して質問してみよう
ただいま回答率
85.37%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

0回答

65閲覧

動いているオブジェクトを、setparentで親オブジェクトに紐づける際に、位置ずれが発生する

kei_de

総合スコア0

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2024/11/17 08:41

編集2024/11/17 09:02

実現したいこと

動いているボールオブジェクトを、キャッチ(setparentで親(プレイヤー)オブジェクトに紐づける)際に、位置ずれが発生するため、
これを解消したいです。

前提

UnityとPUN2でドッチボールのマルチプレイゲームを作成しています。
⓵プレイヤーが、止まっているボールを拾う
②別プレイヤーに向けて投げる
③プレイヤーがボールをキャッチする
ような基本的な処理を実装しているのですが、
③の処理において、
動いているボールオブジェクトを、キャッチ(setparentで親(プレイヤー)オブジェクトに紐づける)際に、
ボールが掌に収まらず、位置ずれが発生します。

該当のソースコード

キャッチするコードは以下になります

プレイヤーオブジェクトのスクリプト

// ボールを持つ private IEnumerator HoldBall(Collision collision) { // 衝突したボールオブジェクトのView取得 ballView = collision.collider.GetComponent<PhotonView>(); // ボールのVIEWが取得できない場合 if (ballView == null) { yield break; } // ルームプロパティを取得 var roomProperties = PhotonNetwork.CurrentRoom.CustomProperties; // ボール保持者がいない場合 if ((int)roomProperties["currentBallHolderViewID"] == -1) { // 新しいボール保持者のViewIDをルームプロパティに設定 roomProperties["currentBallHolderViewID"] = photonView.ViewID; PhotonNetwork.CurrentRoom.SetCustomProperties(roomProperties); } // ボール保持者がいる場合 else { Debug.LogWarning("ボールの保持者がいるため、ボールを所持できません"); yield break; } // ボールの所有権がない場合 if (!ballView.IsMine) { // ボールの所有権をリクエスト ballView.RequestOwnership(); Debug.Log("ボールの所有権をリクエストしました"); // 所有権が付与されるまで待つ yield return new WaitUntil(() => ballView.IsMine); } // ボールのRigidbodyを取得して停止 Rigidbody ballRb = ballView.GetComponent<Rigidbody>(); ballRb.velocity = Vector3.zero; // 速度をリセット ballRb.angularVelocity = Vector3.zero; // 回転速度をリセット ballRb.isKinematic = true; // 物理演算を無効にする // 全てのクライアントに親子関係の追加を通知 ballView.RPC("SetBallToPlayer", RpcTarget.AllViaServer, photonView.ViewID); // ボールを持っているパネルを表示 photonView.RPC("UpdatePanelVisibility", photonView.Owner, true); Debug.Log($"{PhotonNetwork.LocalPlayer.UserId} が、ボールを所持しました"); }

ボールオブジェクトのスクリプト

// RPCで他のクライアントに、ボールの親子関係の追加する [PunRPC] void SetBallToPlayer(int ballHolderViewId) { Debug.Log($"ViewID:{ballHolderViewId}にボールの親子関係を設定します"); // ボールのバウンドを無効 ballCol.material.bounciness = 0f; // 対象のプレイヤーのViewを取得 ballHolderView = PhotonView.Find(ballHolderViewId); if (ballHolderView == null) { Debug.LogError($"ViewID:{ballHolderViewId} のプレイヤーが見つかりません"); } // ボールと、ボールを持っているプレイヤーの衝突を無視する(rigidbodyを無効にしても、衝突によりプレイヤーが後ずさりしてしまうため) Collider ballHolderPlayerCol = ballHolderView.GetComponent<Collider>(); Physics.IgnoreCollision(ballCol, ballHolderPlayerCol, true); // 対象のプレイヤーの右手のボーンを見つける Transform rightHandBone = ballHolderView.transform.Find("mixamorig6:Hips/mixamorig6:Spine/mixamorig6:Spine1/mixamorig6:Spine2/mixamorig6:RightShoulder/mixamorig6:RightArm/mixamorig6:RightForeArm/mixamorig6:RightHand"); if (rightHandBone == null) { Debug.LogError("右手のボーンが見つかりません"); } // 右手のボーン>ボールの親子関係を設定(ワールド座標保持) transform.SetParent(rightHandBone, true); }

位置ずれ以外は正常に動作してます。
プレイヤーやボールのオブジェクト位置の同期には
photonTransfromViewを使用しています。

試したこと

setparentの第二引数はfalse(ローカル座標)にする

// 右手のボーン>ボールの親子関係を設定(ワールド座標保持) transform.SetParent(rightHandBone, true);

の部分について、
当初、setparentの第二引数はfalse(ローカル座標)
にしていました。

その場合、
⓵プレイヤーが、止まっているボールを拾うの時には、
手のひらにボールがきっちり収まるのですが、
③プレイヤーがボールをキャッチする
の際の位置ずれが現在の5倍(肌感です)くらいになるため、

今は、true(ワールド座標保持)にしています。

setparentのあとに、transform.positionとrotationを補正する

GPTに聞くと、
setparentのあとに、transform.positionとrotationを明示的に補正するといいといわれたため、
試したのですが、

後続の②のボールを投げる処理にある

transform.SetParent(null, true)

が動かなくなった?ため、ダメでした。

RigidbodyのIntarpolate(位置補間)などは使用

ずれが大きくなっていくためダメでした

PhotonRigidbodyViewとの併用

効果なしでした。

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

Unity(2022.3.28f1)
PUN2

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問