次に追加する機能は少し補足的なものになります。基本的には移動処理の延長になるのですが、今後作成したコンポーネントを拡張する際に参考になると思いますので一緒にやりましょう!
今回作るもの
ダッシュ自体はなくても問題ない機能ですが、あると便利さ具合がだいぶ変わってきますね
完成図
プレイヤーに走る状態を追加することができます。走る設定は、基本の歩くスピードを何倍にするかという形で指定します。下図では歩きの速度に対して約4倍のスピードで走っています。
利用する技術について
プログラムとしてはDictionaryを利用します。あとは今後FPC拡張を行う上で重要になるFPComponent同士の連携。
- RequireComponent
- Dictionaryの利用
- FPComponent間のやり取りについて
- 立場的にはSprintはMovementが必須という関係
自分で作るときは、どちらのコンポーネントが起点になるかなどを気にしながら作成してみてください
Sprint機能の追加
スクリプトの構成上、各ソースコードを先に変更すると、一部の記述にエラーが発生することに注意してください。FPSprintの中では、後で追加するメソッドを利用しています。書いている最中にエラーが出ますので取り扱いには注意してください。
FPSprint作成
ダッシュするFPSprintクラスでは、実際に移動する処理などは実装しません。元のキャラクターの移動スピードに何倍で移動できるように変更されるかの倍率を指定します。
using UnityEngine;
[RequireComponent(typeof(FPMovement))]
public class FPSprint : FPComponentBase
{
private FPMovement movement;
[Header("Sprint")]
public float sprintSpeedScale = 2.0f;
public KeyCode sprintKey = KeyCode.LeftShift;
private void Awake()
{
movement = GetComponent<FPMovement>();
}
private void Update()
{
if (Input.GetKeyDown(sprintKey))
{
movement.AddSpeedModifier(this, sprintSpeedScale);
}
else if (Input.GetKeyUp(sprintKey))
{
movement.RemoveSpeedModifier(this);
}
}
}
Updateメソッドでは、FPMovementに未実装のものがあります。この時点ではエラーが出ますのでコメントアウトするかエラーのまま実装続けてください
FPMovementの変更
移動処理では移動スピードに関係する変数の取り扱いを少し変更します。外部から倍率を複数指定できるようにします。ただしFPComponentを継承しているクラスから1つずつ倍率を指定できるようなものを想定。Dictionaryを利用するため、新しいusingが追加されていることにも注意してください。
using System.Collections.Generic;
using UnityEngine;
public class FPMovement : FPComponentBase
{
[Header("Movement")]
[SerializeField] private float movementSpeed = 5.0f;
public float MovementSpeed => movementSpeed;
[SerializeField] private float gravity = -9.81f;
public float Gravity => gravity;
private Dictionary<FPComponentBase, float> SpeedModifiers { get; set; } = new Dictionary<FPComponentBase, float>();
public Vector3 velocity = Vector3.zero;
public Vector3 Velocity
{
get => velocity;
set => velocity = value;
}
private void Update()
{
var currentInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
Vector3 horizontalMovementVelocity = transform.TransformDirection(new Vector3(currentInput.x, 0, currentInput.y));
float speedModifier = 1.0f;
foreach (var modifier in SpeedModifiers)
{
speedModifier *= modifier.Value;
}
horizontalMovementVelocity *= movementSpeed * speedModifier;
Vector3 verticalMovementVelocity = new Vector3(0, velocity.y, 0);
if (!Controller.CharacterController.isGrounded || 0f < verticalMovementVelocity.y)
{
verticalMovementVelocity.y += gravity * Time.deltaTime;
}
else
{
verticalMovementVelocity.y = gravity * 0.1f;
}
velocity = horizontalMovementVelocity + verticalMovementVelocity;
Controller.CharacterController.Move(velocity * Time.deltaTime);
}
public void AddSpeedModifier(FPComponentBase modifier, float modifierValue)
{
// すでに同じコンポーネントが登録されている場合は上書きする
if (SpeedModifiers.ContainsKey(modifier))
{
SpeedModifiers[modifier] = modifierValue;
}
else
{
SpeedModifiers.Add(modifier, modifierValue);
}
}
public void RemoveSpeedModifier(FPComponentBase modifier)
{
if (SpeedModifiers.ContainsKey(modifier))
{
SpeedModifiers.Remove(modifier);
}
}
}
今回はFPComponentBaseを継承したクラスに対して1つずつ変数をもたせることができるようにしました。
実際に使ってみる
わかりやすくするために、以下の設定でテストしています
- FPMovement
- Movement Speed:1
- FPSprint
- Sprint Speed Scale:4
コメント