Задать вопрос
@WalloutDay

Ошибка в коде Character Controller Unity 2D, что делать?

Написал код для управления персонажем на android, всё работает. Но вот проблемка(
1-при зажатии кнопка (gui imagine) работает только как один клик и что бы персонаж шёл дальше, нужно снова кликать. Как сделать или что изменить в скрипте что бы при зажимании кнопки он шёл до того момента пока я её не отпущу?
2-Анимация персонажа. Когда персонаж стоит проигрывается анимация idle (т.к. переменная "Speed" в окне аниматор стоит на "0.0"). Как только он начинает двигаться анимация меняется на walk (т.к. переменная "Speed" в окне аниматор переходит на "1.0"), НО как только кнопка перестает действовать, т.е. мы её отпускаем (но пока что она сама отпускается), то переменная не меняется. Как было 1.0 так и осталась, только иногда через пару секунд возвращается на 0.0. Помогите что делать?
Вот скрипт.

using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;

public class CharacterController2 : MonoBehaviour {
	
	public float maxSpeed = 10f;
	bool facingRight = true;
	
	Animator anim;
	// Use this for initialization
	void Start () {
		anim = GetComponent<Animator> ();

	}
	
	// Update is called once per frame
	void FixedUpdate () {

	}

	public void Walk(int InputAxis)
	{
		float move = Input.GetAxisRaw ("Horizontal");

		move = InputAxis;
		
		anim.SetFloat ("Speed", Mathf.Abs (move));
		
		GetComponent<Rigidbody2D>().velocity = new Vector2 (move * maxSpeed, GetComponent<Rigidbody2D>().velocity.y);

		if (move > 0 && !facingRight) 
			Flip ();
		else if (move < 0 && facingRight)
			Flip ();

	}
	
	void Flip() {
		facingRight = !facingRight;
		Vector3 theScale = transform.localScale;
		theScale.x *= -1;
		transform.localScale = theScale;
	}
}
  • Вопрос задан
  • 1545 просмотров
Подписаться 1 Оценить Комментировать
Решения вопроса 1
Руководство Unity

1) Вам нужно почитать статью Unity3D Best Practices
(не запрашивайте объекты при каждом нажатии/кадре, кэшируйте их в полях класса; двигать объект с rigidbody нужно только в FixedUpdate и т.д.)

1.1) Что бы кэшировать элементы текущего объекта используйте Awaik() { ... }. Что бы обратиться к другим объектам используйте Start() { ... /* другие объекты уже будут созданы, поэтому вы их тут точно найдете */ }.

2) Что бы персонаж шел постоянно при зажатой кнопке, сделайте флаг (true/false). Нажали кнопку, через Event Trigger вызвали событие PointerDown (или любое другое в своем скрипте, все на ваше усмотрение), в нем флаг выставили в true, в FixedUpdate у нас условие if ( this._move ) { ... } персонаж пошел. Отжали кнопку PointerUp, флаг выставили в false, персонаж перестал идти. Вся суть в том что движение происходит только в FixedUpdate, вам нужно только переключать флаг включен или выключен из других методов/метода. На кнопку можно навесить любой скрипт и вызвать из него открытый метод.

3) По анимации не понял. Для состояния вкл/выкл лучше использовать bool, SetBool вроде, и это значит что значение нужно задавать в коде самому, оно не вернется в false пока вы сами этого не пожелаете (для таких целей используется триггер).

Пройдите бесплатный курс на MVA по разработке 2D и 3D игр.

Многие вещи я и сам регулярно забываю, приходится перечитывать постоянно т.к. использую редко.
Если вы серьезно решили заняться разработкой игр и вообще программированием то нужно учить English и еще один из популярных для развития мышления, https://www.busuu.com/enc/ бесплатно.
90% всех вопросов уже решены, нужно только уметь искать. Раньше тратил на это кучу времени, теперь относительно быстро решаются даже сложные вопросы.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@vovo801
Freelance Unity3d/C# Developer
Input.GetAxisRaw ("Horizontal");
Это надо делать в Update или FixedUpdate.
public void Walk(int InputAxis)
  {
    float move = Input.GetAxisRaw ("Horizontal");

    move = InputAxis;


Тут получается Вы Axis значение получили. а потом перекрыли его аргументом из метода InputAxis. Так Ваша переменная move будет всегда равна InputAxis.

Еще - в примере кода не видно где Вы вызываете метод Walk()
Без собственно вызова этого метода ничего не будет работать.

Я бы попробовал так:
void FixedUpdate () {
           Walk(Input.GetAxis("Horizontal"));
  }


А строку
float move = Input.GetAxisRaw ("Horizontal");
из метода Walk можно смело удалять, все равно вы потом move присваиваете значение InputAxis.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы