目標
2.5D上を動く球を制御するクラスと周辺の設計!
目次
- InputSystem使う
- rbの数値変更をする
- 重力変更する
本音
もし気が向いたら更新しに、戻りにきます。今は、画像とコードでなんとか理解してみてください。
InputSystemにMove2Dを追加
ValueとAxisを選択する。
Trigger BehaviorにReleaseを含めることで静止もちゃんと判定する。
Bindingを追加
Add positive/negative bindingで2D入力制御する。
筆者はnegativeにAキーを、positiveにDキーを採択。
コードを書く
頑張って解釈してみてください。
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
}
}
まとめ
結果を見てみると意外と簡単ですね!数値調整などは自力で頑張ってください。
お疲れ様でした。