95027


Unityのhinge jointをスクリプトから操作しようとしたところ、targetVelocityの値が変わらず、全く動きません。  
useMotorのチェックは入っていますし、エラーも出ていません。  
インスペクターで直接値をいじると動きます。

バージョンは2022.1.23f1と2021.3.22f1で試しました。

[code]

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class motor : MonoBehaviour
    
    public HingeJoint Joint;
    
    void Update()
    {
    　var Motor = Joint.motor;
    　Motor.targetVelocity= 360;
    }
    
[/code]


CC BY-SA 4.0
2023-05-28T03:58:59.623
94995
2023-05-30T13:30:18.503
2023-05-28T04:20:34.553
3060
58491
question
unity3d
hinge jointをスクリプトから操作したい


ちょっと厄介な話なのですが…。

まずは、`HingeJoint.moter` の型である [`JointMotor`
のマニュアル](https://docs.unity3d.com/ja/2022.2/ScriptReference/JointMotor.html)を見てください。  
「struct in UnityEngine」と書かれています。  
つまり、`JointMotor` は構造体(struct)なんです。

C#の構造体の説明は、自分もあまり説明ができないので、以下を見てもらいたいです。

  * [構造体 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C](https://ufcpp.net/study/csharp/resource/rm_struct/)
  * [値型と参照型 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C](https://ufcpp.net/study/csharp/oo_reference.html)

(他にも、検索して調べてみてください。結構大事な話です)

構造体は値型であり、クラスとは違います。  
例えば、以下の例。

[code]

        class Hoge {
            public int a;
        }
        
        Hoge hoge0 = new Hoge();
        hoge0.a = 1;
        Hoge hoge1 = hoge0;
        hoge1.a = 2;
        Debug.Log($"hoge0.a = {hoge0.a}, hoge1.a = {hoge1.a}.");
    
[/code]

通常クラスの代入は、同じオブジェクトを指すことになるので、ログには「hoge0.a = 2, hoge1.a = 2.」と出力されます。

[code]

        struct Hoge {
            public int a;
        }
    
        Hoge hoge0 = new Hoge();
        hoge0.a = 1;
        Hoge hoge1 = hoge0;
        hoge1.a = 2;
        Debug.Log($"hoge0.a = {hoge0.a}, hoge1.a = {hoge1.a}.");
    
[/code]

というように構造体にした場合、構造体の代入は新たなオブジェクトの作成と、各メンバの代入となります。  
つまり、以下のような感じです。

[code]

        Hoge hoge0 = new Hoge();
        hoge0.a = 1;
        Hoge hoge1 = new Hoge();
        hoge1.a = hoge0.a;
        hoge1.a = 2;
        Debug.Log($"hoge0.a = {hoge0.a}, hoge1.a = {hoge1.a}.");
    
[/code]

ですので、代入先の`hoge1`のメンバに変更を加えても、代入元の`hoge0`には変更が加わらないことになります。  
よって、ログには「hoge0.a = 1, hoge1.a = 2.」と出力されます。

どうすればいいかは、[`JointMotor`のマニュアル](https://docs.unity3d.com/ja/2022.2/ScriptReference/JointMotor.html)のサンプルコードのように、代入して値を変更した後、再度`HingeJoint.motor`に再代入すればいいでしょう。

[code]

        JointMotor motor = Joint.motor;
        motor.targetVelocity = 360;
        Joint.motor = motor;  // 再代入
    
[/code]


CC BY-SA 4.0
2023-05-30T13:30:18.503
95027
2023-05-30T13:30:18.503
15473
94995
answer