triggerzone每帧读取同一对象

时间:2019-03-22 03:02:14

标签: c# unity3d

触发区域每帧读取相同的对象,不应该那样做,这会弄乱游戏。它不会一直发生,我也不知道为什么
对不起,代码混乱,我的组织方式不太好。 我没有多少评论(如果有的话),我总是忘记把它们放进去。 我现在输入的内容是想让我发帖

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

public class spacereader : MonoBehaviour
{
    public int spacesmoved = 0, jiff;


    void Start()
    {

    }

    void Update()
    {
        sharedscript.nummoved = spacesmoved;
        if(sharedscript.reset)
        {
        spacesmoved = 0;
        jiff = 0;
        }
    }

private void OnTriggerEnter(Collider other)
{
    Debug.Log(other.tag);
    Debug.Log(other.name);
    StartCoroutine(spotchecker(other));
    if (jiff != 2)
        jiff++;
    else if (sharedscript.ismoving)
    {
        spacesmoved++;
    }

}

private IEnumerator spotchecker(Collider other)
{
    switch (other.tag)
    {
        case "GO":

            break;
        case "MEDAVE":

            break;
        case "CHEST":

            break;
        case "BALAVE":

            break;
        case "INCOME":

            break;
        case "READING":

            break;
        case "ORIENTAL AVE":

            break;
        case "CHANCE":

            break;
        case "VERMONT":

            break;
        case "CONNAVE":

            break;
        case "INJAIL":

            break;
        case "CHARPLACE":

            break;
        case "COMPANY":

            break;
        case "STATESAVE":

            break;
        case "VIRGAVE":

            break;
        case "PENNRAIL":

            break;
        case "JAMESPLACE":

            break;
        case "TENNAVE":

            break;
        case "NEWYORKAVE":

            break;
        case "FREEPARK":

            break;
        case "KENAVE":

            break;
        case "INDIAVE":

            break;
        case "ILLAVE":

            break;
        case "BORAIL":

            break;
        case "ATLAAVE":

            break;
        case "VENTAVE":

            break;
        case "WATERWORKS":

            break;
        case "MARVGARD":

            break;
        case "GOTOJAIL":

            break;
        case "PACAVE":

            break;
        case "NORTHAVE":

            break;
        case "PENNAVE":

            break;
        case "SHORTLINE":

            break;
        case "PARKPLACE":

            break;
        case "BOARDWALK":

            break;
        case "LUXTAX":

            break;
        }
        yield return other;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class playercontroller : MonoBehaviour
{
    public List<GameObject> targets;
    public float speed, step;
    bool canmove = false;
    public List<Camera> cameras;
    public Camera diecam;
    public List<GameObject> players;
    public List<GameObject> playerreaders;
    public int[] turntarget = new int[] { 0, 0, 0, 0 };
    public int turn = 1;
    int lastturn = 0;
    bool switchit = true;
    Coroutine inin;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if(canmove)
        {
            if(!switchit || sharedscript.doubles)
            {
                foreach(GameObject s in playerreaders)
                {
                    s.SetActive(false);
                }
                foreach (Camera s in cameras)
                {
                    s.gameObject.SetActive(false);
                }
                foreach(GameObject s in players)
                {
                    Collider g = s.GetComponent<Collider>();
                    g.enabled = false;
                    Rigidbody w = s.GetComponent<Rigidbody>();
                    w.isKinematic = true;
                }
                lastturn = turn;
                switchit = true;
            }
            Collider d = players[turn].GetComponent<Collider>();
            d.enabled = true;
            Rigidbody f = players[turn].GetComponent<Rigidbody>();
            f.isKinematic = false;
            playerreaders[turn].SetActive(true);
            cameras[turn].gameObject.SetActive(true);
            diecam.gameObject.SetActive(false);
            step = speed * Time.deltaTime;
            if (players[turn].transform.position.x <= targets[turntarget[turn]].transform.position.x + .003 && players[turn].transform.position.x >= targets[turntarget[turn]].transform.position.x - .003 && players[turn].transform.position.z <= targets[turntarget[turn]].transform.position.z + .03 && players[turn].transform.position.z >= targets[turntarget[turn]].transform.position.z - .03)
            {
                if (turntarget[turn] < 3)
                {
                    turntarget[turn] ++;
                    players[turn].transform.Rotate(0, 90, 0);
                }
                else
                {
                    turntarget[turn] = 0;
                }
            }

            players[turn].transform.position = Vector3.MoveTowards(players[turn].transform.position, targets[turntarget[turn]].transform.position, speed);
        }
        if(sharedscript.nummoved >= sharedscript.total)
        {
            canmove = false;
            sharedscript.ismoving = false;
        }
        else
        {
            canmove = true;
            sharedscript.ismoving = true;
        }
        if(sharedscript.nummoved >= sharedscript.total && sharedscript.total != 0 && sharedscript.nummoved != 0 && !sharedscript.doubles && switchit)
        {
            if (turn < 3)
                turn++;
            else
                turn = 0;
            sharedscript.reset = true;
            switchit = false;
            Debug.Log("playedturn");
            sharedscript.canroll = true;
        }

    }

}

1 个答案:

答案 0 :(得分:0)

只要某物进入触发对撞机,您就开始启动协程。尝试检查输入的对象是否是您要查找的对象。如果是您的播放器并且该对象被标记为“玩家”,则可以检查以下内容:

private void OnTriggerEnter(Collider other)
{
    if(other.CompareTag("Player"))
    {
        StartCoroutine(YourCoroutine());
    }
} 

另一个原因可能是Unity冲突检测。有时它可能会很不稳定,因此在大多数情况下,最好检查一下对象是否已经碰撞。

特别是使用协程来解决此问题的一种方法是将协程存储在脚本的变量中,并检查其是否已经运行。像这样:

private Coroutine coroutine;
private void OnTriggerEnter(Collider other)
{
    if(coroutine == null)
    {
        coroutine = StartCoroutine(YourCoroutine());
    }
}

然后在OnTriggerExit或其他方式中将值设置为null:

private void OnTriggerExit(Collider other)
{
    coroutine = null;
}

我建议在此实现中还检查标签:

private Coroutine coroutine;
private void OnTriggerEnter(Collider other)
{
    if(coroutine == null && other.CompareTag("Player"))
    {
        coroutine = StartCoroutine(YourCoroutine());
    }
}