我正在关注创建 Unity 3D Mario 游戏的这个 youtube 系列。 ( https://www.youtube.com/watch?v=vjL3S5dKLN4&index=6&list=PLZ1b66Z1KFKgm4QrzZ11jfaeHVaWHSHW7 )
所以我正在尝试重新创建像马里奥游戏中那样的“顺着管道往下走”的脚本。我创建了一个 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 函数 中,我会得到:
The body cannot be a iterator block because void is not a iterator interface type.
如果我将动画设置为 true 并且永远不会将其设置回 false,它会起作用 - 但不像预期的那样,因为显然动画会永远持续下去。
最佳答案
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”。
关于c# - unity c#马里奥游戏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55082914/