0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ざっくり2.5Dの自機移動制御[Unity]

Last updated at Posted at 2025-04-25

目標

2.5D上を動く球を制御するクラスと周辺の設計!

目次

  1. InputSystem使う
  2. rbの数値変更をする
  3. 重力変更する

本音

もし気が向いたら更新しに、戻りにきます。今は、画像とコードでなんとか理解してみてください。

InputSystemにMove2Dを追加

ValueとAxisを選択する。
Trigger BehaviorにReleaseを含めることで静止もちゃんと判定する。
Screenshot 2025-04-25 at 13.59.12.png

Bindingを追加

Add positive/negative bindingで2D入力制御する。
筆者はnegativeにAキーを、positiveにDキーを採択。
Screenshot 2025-04-25 at 13.59.20.png

コードを書く

頑張って解釈してみてください。

SphereControl.cs
/*
 * Copyright (c) DeepNapEngine
 * https://github.com/TrueRyoB
 */
using UnityEngine;
using UnityEngine.InputSystem;
// using System;
// using System.Collections;
// using System.Collections.Generic;

namespace PoseQ.Core.GamePlay.RhyRhyDaDa
{
    /// <summary>
    /// Space key to jump
    /// Side key to move
    /// Kinetic features implemented
    /// </summary>
    public class SphereControl : MonoBehaviour
    {
        #region variables
        
        // references
        [Header("Stats")] 
        [SerializeField] private Rigidbody rb;
        [SerializeField] private InputActionAsset inputActionAsset;
        private InputActionMap _playerActions;
        
        // bool stats
        private bool _onGround;
        private bool _canMove = true;
        private bool _isJumping;
        
        
        // movement stats
        //private readonly float _maxSpeed = 13f;
        //private readonly float _jumpForce = 8f;
        // private readonly float _moveForce = 60f;
        private readonly float _groundCheckDistance = 1.1f;
        [SerializeField] private LayerMask playerMask;
        [SerializeField] private LayerMask groundMask;

        private LayerMask _groundMaskWithoutPlayer;

        private float _inputX;
        
        
        //for adjustment
        [Header("For adjustment")]
        [SerializeField]private float _jumpForce = 15f;
        [SerializeField]private float _maxSpeed = 10f;
        [SerializeField]private float _moveForce = 30f;
        
        #endregion

        #region Event functions
        private void Awake()
        {
            if (rb == null) Debug.LogError("rb is null");
            if (groundMask.value == 0) Debug.LogError("Bad layer");
            
            Physics.gravity = new Vector3(0,-40,0);
            _groundMaskWithoutPlayer = groundMask & ~(1 << playerMask);
        }

        private void FixedUpdate()
        {
            ApplyVelocity();
            CheckGround();
            Debug.DrawRay(transform.position, Vector3.down * _groundCheckDistance, _onGround ? Color.green : Color.red);
        }
        
        private void OnEnable() 
        {
            _playerActions = inputActionAsset.FindActionMap("Player"); 
            _playerActions.Enable(); 
            _playerActions["Move2D"].performed += Move; 
            _playerActions["Jump"].performed += Jump; 
        }
        
        private void OnDisable()
        {
            _playerActions.Disable();
        }
        
        private void OnCollisionEnter(Collision other)
        {
            switch (other.gameObject.tag)
            {
                case Constant.GameObjectTag.RhyRhyDaDa.Spike:
                    // Game Over
                    Debug.LogWarning("Game Over");
                    break;
                case Constant.GameObjectTag.RhyRhyDaDa.Slimy:
                    // Something
                    Debug.LogWarning("Slimy");
                    break;
            }
        }
        #endregion
        
        #region Actions

        private void ApplyVelocity()
        {
            Vector3 input = new Vector3(_inputX, 0, 0);
            
            // input = Camera.main!.transform.TransformDirection(input);
            // input.y = 0f;
            
            rb.AddForce(input.normalized * _moveForce);
            
            Vector3 horizontalVelocity = rb.linearVelocity;
            horizontalVelocity.y = 0f;

            if (horizontalVelocity.magnitude > _maxSpeed)
            {
                Vector3 limitedVelocity = horizontalVelocity.normalized * _maxSpeed;
                rb.linearVelocity = new Vector3(limitedVelocity.x, rb.linearVelocity.y, limitedVelocity.z);
            }
        }
        
        private void Move(InputAction.CallbackContext context) => _inputX = _canMove ? context.ReadValue<float>() : 0f;
        
        private void Jump(InputAction.CallbackContext context)
        {
            _onGround = true;//TODO:layer処理を直す
            if (!_canMove || _onGround) return; 
            
            Vector3 jumpVelocity = rb.linearVelocity;
            jumpVelocity.y = _jumpForce;
            rb.linearVelocity = jumpVelocity;
        }
        #endregion
        
        #region Methods
        private void CheckGround() => 
            _onGround = Physics.Raycast(rb.position, Vector3.down, _groundCheckDistance, _groundMaskWithoutPlayer);
        
        #endregion
    }
}

まとめ

結果を見てみると意外と簡単ですね!数値調整などは自力で頑張ってください。
お疲れ様でした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?