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

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

ただいまの
回答率

90.51%

  • Unity

    4021questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity3D

    1299questions

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

Unityです。次のスクリプトにてオフセットを使用したいです。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 278

anyokayuiyo

score 10

Unityです。次のスクリプトにてオフセットを使用したいのですがどう修正すればよいでしょうか。
回答よろしくお願いいたします。
※オフセットとはTransform objectToUse;のスタート位置のオフセットです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// © 2017 TheFlyingKeyboard
// theflyingkeyboard.net
//Moves object between two points
public class MoveBetweenTwoPoints : MonoBehaviour {
    [SerializeField] private float moveSpeed;
    [SerializeField] private GameObject pointA;
    [SerializeField] private GameObject pointB;
    [SerializeField] private bool reverseMove = false;
    [SerializeField] private Transform objectToUse;
    [SerializeField] private bool moveThisObject = false;
    private float startTime;
    private float journeyLength;
    private float distCovered;
    private float fracJourney;
    void Start()
    {
        startTime = Time.time;
        if (moveThisObject)
        {
            objectToUse = transform;
        }
        journeyLength = Vector3.Distance(pointA.transform.position, pointB.transform.position);
    }
    void Update()
    {
        distCovered = (Time.time - startTime) * moveSpeed;
        fracJourney = distCovered / journeyLength;
        if (reverseMove)
        {
            objectToUse.position = Vector3.Lerp(pointB.transform.position, pointA.transform.position, fracJourney);
        }
        else
        {
            objectToUse.position = Vector3.Lerp(pointA.transform.position, pointB.transform.position, fracJourney);
        }
        if ((Vector3.Distance(objectToUse.position, pointB.transform.position) == 0.0f || Vector3.Distance(objectToUse.position, pointA.transform.position) == 0.0f)) //Checks if the object has travelled to one of the points
        {
            if (reverseMove)
            {
                reverseMove = false;
            }
            else
            {
                reverseMove = true;
            }
            startTime = Time.time;
        }
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

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

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

Start内でpointA(もしくはpointB)とobjectToUseの相対位置を保存しておいて、それを移動時や反転判定の際に加減算するというのを試してみましたが、こういう意図でしょうか?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// © 2017 TheFlyingKeyboard
// theflyingkeyboard.net
//Moves object between two points
public class MoveBetweenTwoPoints : MonoBehaviour {
    [SerializeField] private float moveSpeed;
    [SerializeField] private GameObject pointA;
    [SerializeField] private GameObject pointB;
    [SerializeField] private bool reverseMove = false;
    [SerializeField] private Transform objectToUse;
    [SerializeField] private bool moveThisObject = false;
    private float startTime;
    private float journeyLength;
    private float distCovered;
    private float fracJourney;
    private Vector3 offset;
    void Start()
    {
        startTime = Time.time;
        if (moveThisObject)
        {
            objectToUse = transform;
        }
        journeyLength = Vector3.Distance(pointA.transform.position, pointB.transform.position);
        offset = objectToUse.position - pointA.transform.position; // offsetをpointAからの相対位置とする
        // offset = objectToUse.position - pointB.transform.position; // offsetをpointBからの相対位置とする
    }
    void Update()
    {
        distCovered = (Time.time - startTime) * moveSpeed;
        fracJourney = distCovered / journeyLength;
        if (reverseMove)
        {
            objectToUse.position = Vector3.Lerp(pointB.transform.position, pointA.transform.position, fracJourney) + offset; // offsetを加算
        }
        else
        {
            objectToUse.position = Vector3.Lerp(pointA.transform.position, pointB.transform.position, fracJourney) + offset; // offsetを加算
        }
        // offsetを減算
        if ((Vector3.Distance(objectToUse.position - offset, pointB.transform.position) == 0.0f || Vector3.Distance(objectToUse.position - offset, pointA.transform.position) == 0.0f)) //Checks if the object has travelled to one of the points
        {
            if (reverseMove)
            {
                reverseMove = false;
            }
            else
            {
                reverseMove = true;
            }
            startTime = Time.time;
        }
    }
}

フィールドを追加してオフセット移動をオン・オフできるようにしたり、pointApointBのどちらを基準にするかを切り替えられるようにしたりするともっと便利になりそうですね。

[追記]

目的の動きを達成するには移動方法を変えてしまうのが手っ取り早そうですね。MoveTowardsが便利なように思います。
だいぶ元のコードから変わってしまいましたが、下記のようなパターンではどうでしょうか。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// © 2017 TheFlyingKeyboard
// theflyingkeyboard.net
//Moves object between two points
public class MoveBetweenTwoPoints : MonoBehaviour {
    [SerializeField] private float moveSpeed;
    [SerializeField] private GameObject pointA;
    [SerializeField] private GameObject pointB;
    [SerializeField] private Transform objectToUse;
    [SerializeField] private bool moveThisObject = false;
    private Transform destination; // 現在の目的地
    void Start()
    {
        if (moveThisObject)
        {
            objectToUse = transform;
        }
        destination = pointA.transform; // pointAを最初の目的地に設定
    }
    void Update()
    {
        objectToUse.position = Vector3.MoveTowards(objectToUse.position, destination.position, moveSpeed * Time.deltaTime); // 目的地に向かって移動、ただし最大移動距離は移動速度×フレーム時間を超えないようにする
        if (Vector3.Distance(objectToUse.position, destination.position) == 0.0f) //Checks if the object has travelled to one of the points
        {
            destination = destination == pointA.transform ? pointB.transform : pointA.transform; // 現在の目的地がpointAなら次の目的地をpointBに、さもなくば次の目的地をpointAに設定
        }
    }
}

すみませんが今はUnityが手元になく、コンパイルが通るかすら未確認のコードです。うっかりした間違いがあるかもしれませんので、うまく動かないようでしたらお知らせください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/31 11:14

    回答ありがとうございます。
    こちらのスクリプトを試してみました。
    Point Bをスタート地点にした場合、開始時はPoint Bにoffset分足された位置からスタートする事ができましたが、Point Aをoffset分突き抜けた部分が折り返し地点となってしまっているようです。
    しかも、こちらの意図したスタート地点であるPoint Bにオブジェクトが戻ることはありませんでした。Point Bにoffsetを足した位置がスタート地点になっているようです。
    あくまでPoint AとPoint Bを行き来できるようにしたいです。offsetを足した場合は、Point AとPoint Bに収まる事を想定しています。

    キャンセル

  • 2017/12/31 11:56 編集

    確認しますが、下記のような感じの流れでしょうか?

    - objectToUseの初期位置はそのままobjectToUseの位置。
    - スタートすると、objectToUseはpointAへ向かって動き出す。
    - pointAへ到達すると、次にobjectToUseはpointBへ向かって動き出す。
    - pointBへ到達すると、次にobjectToUseはpointAへ向かって動き出す。
    - 以降、objectToUseはpointAとpointBの間を往復し続ける。

    それと、もう一点確認したいのですが、pointAやpointBはプレイ中に位置が変化しうるでしょうか?もしobjectToUseの移動中にpointAやpointBの位置が変化したとしても、誘導ミサイルのようにpointAやpointBの動きに追従して、そちらに向かっていく動きであるべきでしょうか。

    キャンセル

  • 2017/12/31 12:13

    上記の流れで問題ないです。
    point Aとpoint Bはプレイ中に位置は変化しません。

    キャンセル

  • 2017/12/31 14:10

    上記の追記ありがとうございます。うまく往復移動しているようです。

    キャンセル

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    Unityでのナビゲーションラインの実装について

    unityでナビゲーションラインを実装したいと思っています。 画像中央の青いラインみたいなもの、プレイヤーから特定のオブジェクトに対して線を引き、方向を教える。 現在LineRe

  • 解決済

    unityでのキャラクターの復活

    unityで特定のオブジェクトにプレイヤーが触れた時プレイヤーがDestroyさせ、3秒後に初期位置で復活させるといった スクリプトを書きたいのですが、キャラクターをDestro

  • 解決済

    Unity 画面揺れ

    Unityで2Dのランゲームを作っています。キャラクターがダメージを受けた時に画面を揺らしたいのですが、どのようにすればいいかわからず困っています。 海外の方のブログ?から引っ張

  • 解決済

    Unity3dのTerrain上に作った木の座標の求め方

    前提・実現したいこと Unityを始めたばかりの者です。 HierarchyビューにあるTerrainに、木を作るブラシで木をたくさん作りましたが、それらの木の座標を求める

  • 解決済

    unity 画面内に同じものを表示しない

    unityでランダムでキャラクターを表示していくものなのですが、画面内に同じキャラクターが表示されてしまうのでされないようにしたいです。 キャラクターは一定時間でCloneされ一

  • 解決済

    オブジェクトを自動で動かし、指定の場所まで来たら動きを止める方法

    リザルト画面でプレイ中にかかった時間と残ったHPを表示させ、 それに応じた評価を表示させる 1)リザルト画面になる クリア時間→HP→ランクの順に表示させたい 2)画面外か

  • 解決済

    Cubeオブジェクトを指定された位置から位置まで行ったり来たりと自動で動かしたい

    スーパーマリオのゲーム等でよく縦(x軸)や横(y軸)にブロック等が自動で行ったり来たりするコードを書いたのですが「行ったり」は出来てもまた最初の位置に戻る「来たり」が上手くできませ

  • 解決済

    型が違うというエラーが出た時の対処方法

    あるオブジェクトの座標を常に取得したいと思い、 Unityで対象のポイントへ等速で動かす(テラシュールブログ) こちらを参考に、 Vector3 "変数名"; ->

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

  • Unity

    4021questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity3D

    1299questions

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