在 Unity 中双向旋转门

2024-04-20

我在 Unity 中创建了一扇打开和关闭的门。我可以通过打电话打开那扇门Interact().

现在我想创建一扇始终远离玩家打开的门。就像酒吧的门一样。如果玩家在房间前面,门就会旋转到房间,如果玩家在房间里,门就会旋转出去。

目前我创建了一个布尔值opensAwayFromPlayer。如果这是真的,则开门时目标旋转应该是固定的。

[SerializeField]
private Vector3 targetRotation; // rotation angles

[SerializeField]
private float duration; // rotation speed

[SerializeField]
private bool closeAgain; // close the door again?

[SerializeField]
private float waitInterval; // close the door after x seconds

[SerializeField]
private Vector3 pivotPosition; // Vector3 of the pivot

[SerializeField]
private bool opensAwayFromPlayer; // door can open both directions

[SerializeField]
private Transform playerTransform; // Player Object

private Vector3 defaultRotation; // store the rotation when starting the game
private bool isActive = false;

Transform doorPivot; // the pivot point to rotate around

private void Start()
{
    doorPivot = new GameObject().transform; // create pivot
    doorPivot.position = pivotPosition; // place the pivot before parenting!
    transform.SetParent(doorPivot); // make the door being a child of the pivot
    defaultRotation = doorPivot.eulerAngles;
}

private IEnumerator DoorRotation()
{
    if (isActive)
        yield break;

    isActive = true;

    float counter = 0;
    Vector3 defaultAngles = doorPivot.eulerAngles;
    Vector3 openRotation = transform.eulerAngles + targetRotation;

    while (counter < duration)
    {
        counter += Time.deltaTime;
        LerpDoor(defaultAngles, openRotation, counter); // open the door
        yield return null;
    }

    if (!closeAgain)
        Destroy(this);

    yield return new WaitForSeconds(waitInterval); // wait some seconds

    while (counter > 0)
    {
        counter -= Time.deltaTime;
        LerpDoor(defaultAngles, openRotation, counter); // close the door
        yield return null;
    }

    isActive = false;
}

private void LerpDoor(Vector3 defaultAngles, Vector3 targetRotation, float counter)
{
    doorPivot.eulerAngles = Vector3.Lerp(defaultAngles, targetRotation, counter / duration);
}

private bool PlayerIsBehindDoor() // is the player in front of or behind the door?
{
    Vector3 doorTransformDirection = transform.TransformDirection(Vector3.forward); // door direction
    Vector3 playerTransformDirection = playerTransform.position - transform.position; // player direction
    return Vector3.Dot(doorTransformDirection, playerTransformDirection) < 0; // return player is in front or behind the door
}

public void Interact() // start the rotation
{
    StartCoroutine(DoorRotation());
}

正如你在这里看到的

if (opensAwayFromPlayer) // door can open both directions?
{
   if (PlayerIsBehindDoor()) // Player is behind the door? (in the room)
   {
       // openRotation = ; // open to the other direction
       // closeRotation = ; // close / back to the default rotation 
   }
}

我不知道如何计算它的不同旋转。仅将旋转设置为负值是行不通的。

当我将门向另一个方向旋转 90 度时,它没有向后旋转,而是向后旋转 270 度,同时保持另一个方向。


这应该是最终的脚本。您可以通过将脚本拖动到游戏对象上并调用该方法来测试它Interact()

 [SerializeField]
    private Vector3 targetRotation;

    [SerializeField]
    private float duration;

    [SerializeField]
    private bool closeAgain;

    [SerializeField]
    private float waitInterval;

    [SerializeField]
    private Vector3 pivotPosition;

    [SerializeField]
    private bool opensAwayFromPlayer;

    private Vector3 defaultRotation;

    private bool isActive = false;

    private Transform doorPivot;

    private Transform playerTransform;

    private void Start()
    {
        playerTransform = Globals.GetPlayerObject().transform;
        doorPivot = new GameObject().transform;
        doorPivot.position = pivotPosition;
        transform.SetParent(doorPivot);
        defaultRotation = doorPivot.eulerAngles;
    }

    private IEnumerator DoorRotation()
    {
        if (isActive)
            yield break;

        isActive = true;

        float counter = 0;
        Vector3 defaultAngles = doorPivot.eulerAngles;

        if (PlayerIsBehindDoor())
            targetRotation = -targetRotation;

        Vector3 openRotation = transform.eulerAngles + targetRotation;

        while (counter < duration)
        {
            counter += Time.deltaTime;
            LerpDoor(defaultAngles, openRotation, counter);
            yield return null;
        }

        if (!closeAgain)
            Destroy(this);

        yield return new WaitForSeconds(waitInterval);

        while (counter > 0)
        {
            counter -= Time.deltaTime;
            LerpDoor(defaultAngles, openRotation, counter);
            yield return null;
        }

        isActive = false;
    }

    private void LerpDoor(Vector3 defaultAngles, Vector3 targetRotation, float counter)
    {
        doorPivot.eulerAngles = Vector3.Lerp(defaultAngles, targetRotation, counter / duration);
    }

    private bool PlayerIsBehindDoor()
    {
        Vector3 doorTransformDirection = transform.TransformDirection(Vector3.forward);
        Vector3 playerTransformDirection = playerTransform.position - transform.position;
        return Vector3.Dot(doorTransformDirection, playerTransformDirection) < 0;
    }

    public void Interact()
    {
        StartCoroutine(DoorRotation());
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Unity 中双向旋转门 的相关文章

随机推荐

  • 在Scala中,“视图”有什么作用?

    具体来说 我在这里查看问题1 http pavelfatin com scala for project euler http pavelfatin com scala for project euler 列出的代码如下 val r 1 u
  • DotNetOpenAuth 的来源在哪里?主要的 Sourceforge 链接仅包含示例和 ApplicationBlock

    现在 DNOA 可以做到回电报告 http www dotnetopenauth net openid dotnetopenauth e2 80 99s e2 80 9ccall home e2 80 9d reporting 我想调查源头
  • 使用 Jersey 在 REST 服务中上传多个文件

    这里有很多建议使用的链接multipart form data以及如何在此处上传文件 无法真正找到一个用于通过 CURL 命令上传的多个文件的组合以及接受 REST 服务的文件FormDataMultiPart 目前服务中的代码如下所示 j
  • 解析aspx文件中的控件并将其转换为xml

    我需要解析 aspx 文件 来自磁盘 而不是浏览器上呈现的文件 并列出页面上存在的所有服务器端 asp net 控件 然后从中创建一个 xml 文件 哪一个是最好的方法 另外 有没有可用的库 例如 如果我的 aspx 文件包含
  • 在一个响应中返回多个响应数据

    在我的科目表中 我按学期和月份列出了所有学生的课程以及每个月的分数 id 4 this is the subject id userid 1 name bio semester 3 semester month 5 the month po
  • MVC 部分视图模型不刷新

    我有一个部分视图正在加载到 asp net MVC 3 中的 jQuery 模式中 问题是视图未正确刷新 以下是事件的顺序 1 主视图有一个表格 列出了不同的事件记录 表的每一行上都有一个链接来显示事件详细信息 2 当单击此表上的链接时 部
  • name='' 的无效表单控件不可聚焦

    在 Google Chrome 中 某些客户无法进入我的付款页面 当尝试提交表单时 我收到此错误 name 的无效表单控件不可聚焦 这是来自 JavaScript 控制台 我读到问题可能是由于隐藏字段具有必需的属性 现在的问题是我们使用 n
  • 将 dotnet core 应用程序安排为具有数据访问层的 3 层

    我的典型 NET 4 5X Web 应用程序结构至少有 3 层 Web 项目 NET Web 应用程序 域 业务逻辑项目 类库 和数据访问项目 类库 Web项目引用了业务层 业务层又引用了数据访问层 我喜欢这种方法 因为我的 Web 项目没
  • TypeScript 中的语音识别和语音合成

    我能够通过创建如下接口在 TypeScript 中运行 SpeechRecognition 并且工作正常 namespace CORE export interface IWindow extends Window webkitSpeech
  • Java 写入 Windows Server 2016 时文件上次修改时间未更新

    我在 Windows Server 2016 上有一个 Java 10 应用程序 它不断使用 java util logging 写入文件 在 Windows 文件资源管理器中 上次修改 和 大小 列不会更新 按 F5 不会更新详细信息 操
  • 当我们手动将tomcat作为Windows服务运行时,如何更改tomcat的java_opts?

    我在控制台上手动运行 tomcat 6 作为 Windows 服务 我需要在启动之前更改 java opts 我怎么做 另外 有没有办法可以动态查看日志 我知道这是一个旧线程 但需要纠正一些假设 仅供参考 当将 tomcat 作为服务运行时
  • 替换数据框中的重复列

    我有一个data frame in pyspark 该数据框有一些带有特殊字符的列 cols df schema names cols abc test test abc eng test abc test reps def col ren
  • JSON 模式中的小数精度

    我想让我的 JSON 架构验证发送到我的 REST api 的小数位数不超过两位 从我在最新的 JSON Schema RFC v4 中看到的情况来看 不允许这样做 V1 有一个 maxDecimals 验证器 有谁知道为什么被删除 我有一
  • 如何从 Asp Label.Text 加载航路点坐标

    我在其中硬核值的第一个代码
  • 未使用重定向设置实例变量

    什么会导致我的实例变量 product 无法为重定向设置 传递 Product 是一个 ActiveModel 对象 而不是 ActiveRecord 更具体地说 product 变量没有出现在redirect to new service
  • VSCode 文件夹结构

    我想更改文件夹结构 如果您在文件夹 utils 中看到我有另一个名为 mocks 的文件夹 我想要的是更改结构以按文件夹查看1个文件夹 类似这样 就像只有 1 个文件的 services 文件夹一样 我有相同的结构 另一个文件夹中有 1 个
  • 如何从继承的 FromBody 模型中获取正确的类型?

    正文的帖子有几种不同的 XML 传入 所有 XMLS 几乎都是相同的 因此我首先添加一个基类 其他 XMLS 继承自该基类 这是模型 XmlInclude typeof TextMsg XmlRoot xml public class Ba
  • 检查属性是否用特定注释修饰 - Typescript

    如何确定特定属性是否用特定注释修饰 例如这个类 class A DecoratedWithThis thisProp number 我怎么知道thisProp装饰有DecoratedWithThis 我的用例 我使用另一个文件中的类来生成属
  • Android 指纹原始数据

    Android 的指纹传感器实现是否支持直接访问原始指纹数据 即手指上的实际图案 我并不是指用于解锁设备和付款的存储的安全指纹 而是指在扫描手指时按需获取原始数据 如果没有 为什么不呢 Android API 的作用not允许直接访问原始指
  • 在 Unity 中双向旋转门

    我在 Unity 中创建了一扇打开和关闭的门 我可以通过打电话打开那扇门Interact 现在我想创建一扇始终远离玩家打开的门 就像酒吧的门一样 如果玩家在房间前面 门就会旋转到房间 如果玩家在房间里 门就会旋转出去 目前我创建了一个布尔值