Реализация шаблона команд для движения в UnityC#

Место общения программистов C#
Ответить
Anonymous
 Реализация шаблона команд для движения в Unity

Сообщение Anonymous »

Я разрабатываю игру на Unity и пытаюсь очистить код и повысить возможность повторного использования. У меня есть базовый сценарий перемещения игрока, который выглядит следующим образом:

Код: Выделить всё

using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.TextCore.Text;

//TODO - refactor this as a design pattern -- in progress
// Implementing command pattern for userInput
public class Movement : MonoBehaviour
{
private Rigidbody2D body;
private Animator anim;
[SerializeField] private readonly float speed = 5;
private bool grounded;
private void Awake()
{
// Grab references for rigidbody and animator from object
body = GetComponent();
anim = GetComponent();
anim.SetBool("grounded", true);
}

private void Update()
{
float horizontalInput = Input.GetAxis("Horizontal");

CharacterFacing(horizontalInput);

CharacterRun(horizontalInput);

Jump();
// TODO - add jumpBuffer implementation. Should use Time.Delta value.

}

private void Jump()
{
anim.SetFloat("jumpAsc", body.velocity.y);
if (Input.GetKey(KeyCode.Space) && grounded)
{
body.velocity = new Vector2(body.velocity.x, speed);
body.inertia = 30;
grounded = false;
}
if (Input.GetKeyUp(KeyCode.Space) && body.velocity.y > 0)
{
body.velocity = new Vector2(body.velocity.x, 0);
body.AddForce(5.0f * body.mass * Physics.gravity);
}
}

private void CharacterFacing(float horizontalInput)
{
// flip character left/right
if (horizontalInput > 0.01f)
transform.localScale = Vector3.one;
else if (horizontalInput < -0.01f)
transform.localScale = new Vector3(-1, 1, 1);
}
private void CharacterRun(float horizontalInput)
{
body.velocity = new Vector2(horizontalInput * speed, body.velocity.y);
anim.SetFloat("run", Math.Abs(body.velocity.x));
}

private void OnCollisionEnter2D()
{
grounded = true;
body.inertia = 10;
anim.SetBool("grounded", grounded);
}
}
И я пытаюсь преобразовать его в шаблон команды. Я переместил всю логику в класс под названием «Character», который будет использоваться в качестве родительского для подклассов Player и Enemies. Вот оно, практически без изменений:

Код: Выделить всё

using UnityEngine;
using System;

public class Character : MonoBehaviour
{
private Rigidbody2D _body;
private Animator _anim;
private int _HP;
private float _speed = 5;
private float _jumpForce;
private int _level;
private bool _grounded;

public Character()
{
_body = GetComponent();
_anim = GetComponent();
_anim.SetBool("grounded", true);
}

public void Jump()
{
_anim.SetFloat("jumpAsc", _body.velocity.y);
if (Input.GetKey(KeyCode.Space) && _grounded)
{
_body.velocity = new Vector2(_body.velocity.x, _speed);
_body.inertia = 30;
_grounded = false;
}
if (Input.GetKeyUp(KeyCode.Space) && _body.velocity.y > 0)
{
_body.velocity = new Vector2(_body.velocity.x, 0);
_body.AddForce(5.0f * _body.mass * Physics.gravity);
}
}

private void CharacterFacing(float horizontalInput)
{
// flip character left/right
if (horizontalInput > 0.01f)
transform.localScale = Vector3.one;
else if (horizontalInput < -0.01f)
transform.localScale = new Vector3(-1, 1, 1);
}

public void Run()
{
float horizontalInput = Input.GetAxis("Horizontal");
_body.velocity = new Vector2(horizontalInput * _speed, _body.velocity.y);
_anim.SetFloat("run", Math.Abs(_body.velocity.x));
}
}
Итак, теперь мой подкласс Player очищен:

Код: Выделить всё

class Player : Character
{
Character _player;
UserInput _userInput;

public Player(UserInput userInput)
{
_player = gameObject.AddComponent();
_userInput = gameObject.AddComponent();
}

}
и пользовательский ввод разделен:

Код: Выделить всё

using UnityEngine;

public class UserInput : MonoBehaviour
{
public Character _character;

public UserInput(Character character)
{
_character = character;
}
void Update()
{

if (Input.GetKeyDown(KeyCode.Space))
{
ICommand storedCommand = new JumpCommand(_character);
storedCommand.Execute();
}
if(Input.GetAxis("Horizontal") != 0)
{
ICommand storedCommand = new RunCommand(_character);
storedCommand.Execute();
}
}
}
Но теперь мой игровой персонаж не двигается. Все, что делает персонаж, это падает на землю (что говорит мне, что мой Rigidbody2D, по крайней мере, инициализируется правильно). Я не уверен, как связать все это вместе, чтобы прослушивать ввод пользователя.
Я попробовал создать объект UserInput в классе Player, надеясь, что он будет использовать функция Update() для перехвата пользовательского ввода. Я также попытался создать систему событий в Unity и прикрепить к ней свой скрипт UserInput. Такое ощущение, что я так близок, но я не знаю, как связать все это воедино.

Подробнее здесь: https://stackoverflow.com/questions/790 ... t-in-unity
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»