脚本附加到两个游戏对象.

一个是碰撞区域,碰撞器足够大,因此当游戏开始时,玩家已经在碰撞区域内,然后当他离开该区域时,一切都正常.

问题是,当我用collider将对象附加到另一个游戏对象上时,但这次collider变小了,他在更大的collider内,所以现在玩家正在进入更小的collider,而不是第一次退出.但我想在这两种情况下产生相同的效果.

如果玩家退出对撞机,他会减速等待,然后转身,向后移动.

两个对撞机区域的屏幕截图.左边的小棋子是玩家先入后出的棋子.当玩家在更大的对撞机区域时,游戏开始.

Colliders areas

还有 playbook :

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.Characters.ThirdPerson;

public class DistanceCheck : MonoBehaviour
{
    public Transform targetToRotateTowards;
    public Transform colliderArea;
    public float lerpDuration;
    public float rotationSpeed;
    [TextArea(1, 2)]
    public string textToShow;
    public GameObject descriptionTextImage;
    public TextMeshProUGUI text;
    public ThirdPersonUserControl thirdPersonUserControl;

    private Animator anim;
    private float timeElapsed = 0;
    private float startValue = 1;
    private float endValue = 0;
    private float valueToLerp = 0;
    private bool startRotating = false;
    private bool slowOnBack = true;
    private bool exited = false;
    private Vector3 exitPosition;
    private float distance;

    void Start()
    {
        anim = transform.GetComponent<Animator>();
    }

    private void FixedUpdate()
    {
        if (startRotating)
        {
            transform.rotation = Quaternion.RotateTowards(transform.rotation,
    Quaternion.LookRotation(targetToRotateTowards.position - transform.position),
    rotationSpeed * Time.deltaTime);
        }

        if (exitPosition != new Vector3(0, 0, 0) && slowOnBack)
        {
            distance = Vector3.Distance(transform.position, exitPosition);
        }

        if (distance > 5 && slowOnBack)
        {
            slowOnBack = false;
            StartCoroutine(SlowDown());
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.name == colliderArea.name)
        {
            exited = true;
            slowOnBack = true;
            exitPosition = transform.position;
            thirdPersonUserControl.enabled = false;
            descriptionTextImage.SetActive(true);
            text.text = textToShow;
            StartCoroutine(SlowDown());
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.name == colliderArea.name)
        {
            exited = false;
            startRotating = false;
            text.text = "";
            descriptionTextImage.SetActive(false);
        }
    }

    IEnumerator SlowDown()
    {
        timeElapsed = 0;

        while (timeElapsed < lerpDuration)
        {
            valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
            anim.SetFloat("Forward", valueToLerp);
            timeElapsed += Time.deltaTime;

            yield return null;
        }

        if (exited)
        {
            yield return new WaitForSeconds(3f);

            startRotating = true;
            StartCoroutine(SpeedUp());
        }

        if (slowOnBack == false)
        {
            thirdPersonUserControl.enabled = true;
        }
    }

    IEnumerator SpeedUp()
    {
        timeElapsed = 0;

        while (timeElapsed < lerpDuration)
        {
            valueToLerp = Mathf.Lerp(endValue, startValue, timeElapsed / lerpDuration);
            anim.SetFloat("Forward", valueToLerp);
            timeElapsed += Time.deltaTime;

            yield return null;
        }
    }
}

我现在面临两个问题:

  • 较小的碰撞器,玩家先输入后退出,较大的碰撞器,玩家先退出后进入,所以我需要以某种方式更改脚本中的OnTriggerExit/Enter行为逻辑.但是,如何作出逻辑?

  • 也许最好将脚本设置为仅在播放器对象上,并使其具有一定的通用性,以便我可以拖动到多个碰撞器,并在每个碰撞器中产生效果.问题是如何 for each 碰撞器区域创建文本字段?现在,因为我将脚本附加到每个碰撞器对象,所以我有一个colliderArea变量,但如果我想使脚本仅附加到播放器,我需要将colliderArea变量更改为List<Transform> collidersAreas,然后如何为列表中的每个碰撞器区域创建文本字段/区域?

推荐答案

我想我可以通过创建两个标签来实现这一点,NoExitNoEntry.创建标签后,您可以在放置碰撞器的游戏对象上设置标签.然后,您可以判断OnTriggerEnterOnTriggerExit中的标签,并相应地采取行动.

我无法确定您所编写的功能是针对哪种情况的,或者两者都是针对哪种情况的——一切看起来都很混乱.最终,您应该使用像RepositionPlayer这样的函数,将它们移回违反禁止进入或禁止退出规则之前的状态,然后是某种OnPlayerRepositioned事件,恢复它们的控制.

我将让您自行划分您的功能,但一般来说,我希望执行以下操作:

private void OnTriggerExit(Collider other)
{
    if (other.tag == "NoExit")
    {
        RepositionPlayer();
    }
    else if(other.tag == "NoEntry")
    {
        OnPlayerRepositioned();
    }
}

private void OnTriggerEnter(Collider other)
{
    if (other.tag == "NoExit")
    {
        OnPlayerRepositioned();
    }
    else if(other.tag == "NoEntry")
    {
        RepositionPlayer();
    }
}

我也不清楚你想做什么来重新定位球员,但看起来像是:

private void RepositionPlayer()
{
    // Stuff that needs to happen to reposition the player
    exited = true;
    slowOnBack = true;
    exitPosition = transform.position;
    thirdPersonUserControl.enabled = false;
    descriptionTextImage.SetActive(true);
    text.text = textToShow;
    StartCoroutine(SlowDown());
}

private void OnPlayerRepositioned()
{
    // stuff you need to do to clear the "repositioning" status
    exited = false;
    startRotating = false;
    text.text = "";
    descriptionTextImage.SetActive(false);
}

像这样拆分逻辑可以更容易地阅读和维护.

Csharp相关问答推荐

将XPS转换为PDF C#

如何将Kafka消息时间戳转换为C#中的日期和时间格式?

MongoDB.NET-将数据绑定到模型类,但无法读取整数值

Mongo作为.NET中Testcontainers的副本集

实体框架核心中的ComplexType和OwnsOne有什么不同?

C#-从基类更新子类

如何使用自定义负载均衡器管理Ocelot负载均衡器中的多线程和批读取

BlockingCollection T引发意外InvalidOperationException

将内置的OrderedEumable&Quot;类设置为内部类有什么好处?

岛屿和框架中的自定义控件库.Navigate-AccessViolationException

如何将默认区域性更改为fr-FR而不是en-US?

将字符串类型日期输入(yyyy-mm-ddthh:mm:ss)转换为MM/dd/yyyy格式

Maui:更改代码中的绑定字符串不会更新UI,除非重新生成字符串(MVVM)

从HTML元素获取 colored颜色

使用postman 测试配置了身份的.NET 6应用程序

Avalonia MVVM数据模板

";如何在C#中基于多个属性有效地对自定义对象列表进行排序?

在Visual Studio中检测源代码文件中的特定单词或模式?

无法使用SignalR[ABP]验证Flutter应用程序

如何使用MediaInfo库在C#/.NET中提取封面艺术?