我正在按照这个YouTube系列制作一个Unity 3D Mario游戏。 (https://www.youtube.com/watch?v=vjL3S5dKLN4&index=6&list=PLZ1b66Z1KFKgm4QrzZ11jfaeHVaWHSHW7)
因此,我试图像在Mario游戏中一样重新创建“ going down the pipe”脚本。我创建了一个 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,而 waiting_pipe_animation 是唯一无法达到的变量。
4。更新 -所以基本上主要的问题是这个功能:
yield return new WaitForSeconds(2);
如果将其放在 void函数中,我会得到:
主体不能是迭代器块,因为void不是迭代器 界面类型。
如果我将动画设置为 true ,并且从未将其设置回 false ,则它可以正常工作-但效果不理想,因为显然动画永远存在。
答案 0 :(得分:2)
1。。函数OnTriggerEnter
和OnTriggerExit
不返回IEnumerator,也不是协程。
private void OnTriggerEnter(Collider col)
{
StoodOn = 1;
}
private void OnTriggerExit(Collider col)
{
StoodOn = 0;
}
2。。如果角色将具有多个动画,建议您在动画之间创建过渡,并创建变量来控制它。有一些有用的功能,例如SetFloat,SetInteger,SetBool,SetTrigger等。如果没有,那么像您一样启用和禁用动画器就可以了。
3。。正如Okeme Christian所说,必须使用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 :(得分:1)
您不能将协程称为函数。相反,您可以像这样启动协程
StartCoroutine("Fade");
协程名称是“淡入淡出”的地方,因此,在这种情况下,您将像这样启动它
StartCoroutine("WaitPipeAnimation")