95831
Unityで2Dのキャラクターに左右移動を矢印キー、ジャンプをスペースキーの入力のタイミングでさせようとしています。  
ジャンプの命令にはRigidbody2DのAddForceを使っています。  
どういうタイミングか分からないのですが、かなりの確率でジャンプしない時があります。  
ジャンプ命令の後に効果音を再生するようにしているのですが、音はジャンプしてもしなくても出るのでスペースキーの入力が拾えていないというわけではないようです。  
スペースキーを押したら必ずジャンプするようにはどうしたらいいですか。

```

    public class Player : MonoBehaviour{
        [SerializeField] float moveSpeed = 3.5f;
        [SerializeField] float jumpPower = 150f;
        [SerializeField] float jumpAngle = 60f;
        public LayerMask layerBlock;
        private Rigidbody2D rb;
    
        // Start is called before the first frame update
        void Start()
        {
            rb = this.GetComponent<Rigidbody2D>();
        }
    
        // Update is called once per frame
        void Update()
        {
            //←キー　→キーで移動
            rb.velocity = new Vector2(Input.GetAxisRaw("Horizontal"),0).normalized*moveSpeed;
    
            if (rb.velocity != Vector2.zero)
            {
                if (Input.GetAxisRaw("Horizontal") != 0)
                {
                    if (Input.GetAxisRaw("Horizontal") > 0)   //右向き画像
                    {
                        transform.localScale = new Vector2(1f, 1f);
                    }
                    else   //左向き画像
                    {
                        transform.localScale = new Vector2(-1f, 1f);
                    }
                }
            }
            //ブロックに接地している時にスペースキーを押されたらジャンプ
            if (Input.GetKeyDown(KeyCode.Space))
            {   
                if (Physics2D.CircleCast(transform.position, 0.35f, transform.up * -1f, 0.15f, layerBlock))
                {
                    Jump();
                }
            }     
        }
        private void Jump()
        {
            float rad = jumpAngle * Mathf.Deg2Rad;// 角度をラジアンに変換  
            Vector3 direction;
    
            if (transform.localScale.x>0)
            {
                direction = new Vector3(Mathf.Cos(rad) , Mathf.Sin(rad), 0);
            }
            else
            {
                direction = new Vector3(-Mathf.Cos(rad) , Mathf.Sin(rad) , 0);
            }
            //ジャンプ
            rb.AddForce(direction * jumpPower, ForceMode2D.Impulse);
            GetComponent<Sound>().SoundJump();   //ジャンプ効果音
        }
    }
    
```
CC BY-SA 4.0
2023-07-28T07:12:01.160
95789
2023-08-03T00:10:54.390
2023-08-01T11:49:01.587
3060
59011
question
c# unity3d
Unityで2DのキャラクターにAddForceでジャンプさせようとしてもジャンプしない時がある
rb.velocity = new
Vector2(Input.GetAxisRaw("Horizontal"),0).normalized*moveSpeed;  
を問答無用で毎フレーム実行していますので、  
仮にジャンプして上下方向の速度を得ても、次のフレームでは上下方向の速度が0にされていそうです。
CC BY-SA 4.0
2023-08-01T07:26:42.097
95821
2023-08-01T07:26:42.097
13127
95789
answer
試してみないとわかりませんが、`Update` ではなく、`FixedUpdate` で処理すればいいんじゃないでしょうか。  
ただし、今度は `Input.GetKeyDown` が正しく動かなくなるので、自分でトリガー処理をしなければなりません。

```

        bool lastSpaceDown = false;
    
        void FixedUpdate()
        {
            //←キー　→キーで移動
            rb.velocity = new Vector2(Input.GetAxisRaw("Horizontal"),0).normalized*moveSpeed;
    
            if (rb.velocity != Vector2.zero)
            {
                if (Input.GetAxisRaw("Horizontal") != 0)
                {
                    if (Input.GetAxisRaw("Horizontal") > 0)   //右向き画像
                    {
                        transform.localScale = new Vector2(1f, 1f);
                    }
                    else   //左向き画像
                    {
                        transform.localScale = new Vector2(-1f, 1f);
                    }
                }
            }
            //ブロックに接地している時にスペースキーを押されたらジャンプ
            bool spaceDown = Input.GetKey(Keycode.Space);
            if (! lastSpaceDown && spaceDown)
            {   
                if (Physics2D.CircleCast(transform.position, 0.35f, transform.up * -1f, 0.15f, layerBlock))
                {
                    Jump();
                }
            }     
            lastSpaceDown = spaceDown;
        }
    
```

<https://qiita.com/yuji_yasuhara/items/6f50ecdd5d59e83aac99>

上記のサイトでは `AddForce(ForceMode.Impulse` は `Update` で呼んで大丈夫、と書いてあるけど、問題は
`velocity` に値を代入している点ではないかと。

例えば、`Update` → `Update` → `FixedUpdate` (及び物理演算) という流れで処理が進むことがあったとして、一回目の
`Update` でジャンプ判定が行われた場合、二回目の `Update` で `velocity` に代入することによって、一回目の `Update` の
`AddForce` で加えた力が消されてしまうのではないかな、という気がします。  
まぁあくまで気がするだけなのですが、いずれにせよ詳しく物理処理を理解しないうちは、「`Rigidbody` の移動処理は、とりあえず
`FixedUpdate` でしておけ」と考えておくのが無難な気がします。
CC BY-SA 4.0
2023-08-03T00:10:54.390
95831
2023-08-03T00:10:54.390
15473
95789
answer