Игра Unity c # mario - PullRequest
       5

Игра Unity c # mario

1 голос
/ 10 марта 2019

Я слежу за этой серией YouTube, которая создает игру Unity 3D Mario.(https://www.youtube.com/watch?v=vjL3S5dKLN4&index=6&list=PLZ1b66Z1KFKgm4QrzZ11jfaeHVaWHSHW7)

Итак, я пытаюсь воссоздать сценарий «идти по трубе», как в игре Mario.Я создаю Animator и пытаюсь запустить анимацию, используя скрипт C # при нажатии клавиши.

1.Проблема: Эти ребята пишут свои скрипты на Javascript, и, очевидно, моя версия Unity больше не поддерживает js, поэтому мне нужно написать это на C # (и я предпочитаю писать на C #).

В основном мне нужночтобы преобразовать этот JS в C #:

var PipeEntry : GameObject;
var StoodOn : int;


function OnTriggerEnter (col : Collider) {
    StoodOn = 1;
}

function OnTriggerExit (col : Collider) {
    StoodOn = 0;
}


function Update () {
    if (Input.GetButtonDown("GoDown")) {
        if (StoodOn == 1) {
            //GameObject.Find("FPSController").GetComponent("FirstPersonController").enabled=false;
            transform.position = Vector3(0, -1000, 0);
            WaitingForPipe();
        }
    }
}

function WaitingForPipe () {
    PipeEntry.GetComponent("Animator").enabled=true;
    yield WaitForSeconds(2);
    PipeEntry.GetComponent("Animator").enabled=false;
    //GameObject.Find("FPSController").GetComponent("FirstPersonController").enabled=true;
}

2.МОЙ КОД

Мой скрипт сейчас выглядит так:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 
using UnityStandardAssets.Characters.FirstPerson;

public class PipeEntry : MonoBehaviour
{
    public GameObject pipe_entry;
    public int StoodOn;
    public int has_run = 0;
    public int waiting_pipe = 0;
    public int waiting_pipe_animation = 0;

    IEnumerator OnTriggerEnter(Collider col)
    {
        StoodOn = 1;
        yield return StoodOn;
    }

    IEnumerator OnTriggerExit(Collider col)
    {
        StoodOn = 0;
        yield return StoodOn;
    }

    IEnumerator WaitPipeAnimation()
    {
        waiting_pipe_animation = 1;
        yield return new WaitForSeconds(2);

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetButtonDown("PipeDown"))
        {
            if (StoodOn == 1)
            {
                // Freeze player
                //GameObject.Find("Player").GetComponent<FirstPersonController>().enabled = false;
                transform.position = new Vector3(0, -1000, 0);
                WaitingForPipe();
                has_run = 1;
            }
        }
    }

    public void WaitingForPipe()
    {
        pipe_entry.GetComponent<Animator>().enabled = true;
        WaitPipeAnimation();
        pipe_entry.GetComponent<Animator>().enabled = false;
        waiting_pipe = 1;
        //GameObject.Find("Player").GetComponent<FirstPersonController>().enabled = true;
    }

    // Start is called before the first frame update
    void Start()
    {

    }
}

3.Факты

  • Анимация работает хорошо, если запускается непосредственно из Unity, поэтому скрипт не работает.

  • Я установил некоторые отладочные переменныедля которых также устанавливается значение 1, когда сценарий прерывается, а wait_pipe_animation является единственным, который не достигает.

4.ОБНОВЛЕНИЕ - Таким образом, основная проблема заключается в этой функции:

yield return new WaitForSeconds(2);

Если я помещаю ее в void функцию , я получаю это:

Тело не может быть блоком итератора, потому что void не является типом интерфейса итератора.

Если я установил анимацию на true и никогда не установлю обратно на false это работает - но не так, как ожидалось, потому что, очевидно, анимация идет вечно.

Ответы [ 2 ]

2 голосов
/ 10 марта 2019

1. Функции OnTriggerEnter и OnTriggerExit не возвращают IEnumerator и не являются сопрограммами.

private void OnTriggerEnter(Collider col)
{
    StoodOn = 1;
}

private void OnTriggerExit(Collider col)
{
    StoodOn = 0;
}

2. Если у персонажа будет более одной анимации, я предлагаю вам создать переходы между анимациями и создать переменные для управления им. Есть несколько полезных функций, таких как SetFloat , SetInteger , SetBool , SetTrigger и так далее. Если нет, то включение и отключение аниматора, как вы сделали, будет в порядке.

3. Как заявил Окем Кристиан, для вызова сопрограммы необходимо использовать StartCoroutine("WaitPipeAnimation").

4. pipe_entry.GetComponent<Animator>().enabled = false; должно быть внутри функции WaitPipeAnimation, потому что весь код, кроме него, будет по-прежнему выполняться в одном кадре. Таким образом, в основном вы активируете и деактивируете аниматор в одном кадре и не сможете увидеть анимацию.

IEnumerator WaitPipeAnimation()
{
    waiting_pipe_animation = 1;
    yield return new WaitForSeconds(2);
    pipe_entry.GetComponent<Animator>().enabled = false;
}

Если вы хотите лучше понять, как это работает, проверьте этот код ниже:

void Start()
{
    StartCoroutine("CoroutineTest");
    Debug.Log("3");
}

IEnumerator CoroutineTest()
{
    Debug.Log("1");
    yield return new WaitForSeconds(5f);
    Debug.Log("2");
}

Обратите внимание, что порядок печати в консоли будет "1", "3", "2".

1 голос
/ 10 марта 2019

Вы не можете вызвать сопрограмму как функцию. Вместо этого вы запускаете сопрограмму, как это

   StartCoroutine("Fade"); 

Где Fade - это имя сопрограммы, так что в вашем случае вы начнете это так

   StartCoroutine("WaitPipeAnimation")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...