【问题标题】:triggerzone reads the same object every frametriggerzone 每帧读取同一个对象
【发布时间】:2019-03-22 16:57:19
【问题描述】:

Trigger-zone 每一帧都读取相同的对象,它不应该那样做,它会搞乱游戏。它不会一直发生,我不知道为什么
抱歉代码乱七八糟,我不太有条理。 没有多少cmets(如果有的话)我总是忘记把它们放进去。 我现在只是在打字,试图让它让我发帖

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;
        }

    }

}

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    每当某物进入触发对撞机时,你就开始了你的协程。尝试检查输入的对象是否是您要查找的对象。如果它是您的播放器并且对象被标记为“播放器”,您可以检查:

    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());
        }
    }
    

    【讨论】:

    • 很高兴能帮上忙!
    猜你喜欢
    • 2020-12-05
    • 2016-08-17
    • 1970-01-01
    • 2013-11-09
    • 2020-12-06
    • 2022-12-29
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多