【unity】用触发器的方法做开关门(可穿过)

作者在学习Unity时遇到角色穿门问题,通过理解boxcollider和rigidbody的工作原理,发现isTrigger导致了可穿透性。通过修改门的动画脚本,实现在门开启和关闭时切换isTrigger状态,以防止角色穿透。
摘要由CSDN通过智能技术生成

学unity第四天,开始折磨了

要做一个玩家靠近时按E可以打开的门。

介绍一下我的文件结构

一个已经准备好open和close的animation的door,脚本名为DoorsController

门的资源我下载的是asset store里的这个

具体怎么创建动画等等我看了b站的这个教程【如何在Unity中实现开关门的动作效果(作者:邓嘉欣)】 https://www.bilibili.com/video/BV1mg4y197bd/?share_source=copy_web&vd_source=e9e2073763d542d266bf658aa82b61d8,就不赘述了

做完之后我发现,角色可以直接从门内穿模穿过(哪怕不开门),所以我学习了一下box collider和ridigbody的功课,发现问题出在component中的box collider(盒型触发器)上。

因为具有触发器属性的物体类似的成为了游戏里一个可以触发事件的“区域”,所以它将不再具有物理体积。所以只要isTrigger被勾选上了,物体就会变得可穿透。

因此我考虑可以在门还未进行open的animation时不可穿透,而在open之后可穿透。

所以我使用了if语句更改isTrigger的方法:

// 将门设置为触发器,允许玩家穿过
        doorCollider.isTrigger = true;

像这样。然后再加一点逻辑进去就好啦。

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

public class DoorsController : MonoBehaviour
{
    private Animator anim; // 动画控制器组件  
    private bool isOpen = false; // 记录门是否打开  
    private Collider doorCollider; // 门的碰撞体组件  

    // Start is called before the first frame update  
    void Start()
    {
        anim = GetComponent<Animator>(); // 获取动画控制器组件  
        doorCollider = GetComponent<Collider>(); // 获取门的碰撞体组件  
        // 初始设置门不是触发器  
        doorCollider.isTrigger = false;
    }

    // Update is called once per frame  
    void Update()
    {
        // 如果门是打开的且玩家按下了E键,则关闭门  
        if (isOpen && Input.GetKeyDown(KeyCode.E))
        {
            CloseDoor();
        }
        // 如果门是关闭的且玩家按下了E键,并且玩家与门发生了碰撞,则打开门  
        else if (!isOpen && Input.GetKeyDown(KeyCode.E) && IsPlayerNearDoor())
        {
            OpenDoor();
        }
    }

    private void OpenDoor()
    {
        // 触发开门动画  
        anim.SetTrigger("Open");
        // 将门设置为触发器,允许玩家穿过
        doorCollider.isTrigger = true;
        isOpen = true; // 标记门为打开状态  
    }

    private void CloseDoor()
    {
        // 触发关门动画  
        anim.SetTrigger("Close");
        // 如果之前将门设置为触发器,现在关闭时应该将其改回非触发器状态  
        doorCollider.isTrigger = false;
        isOpen = false; // 标记门为关闭状态  
    }

    // 检查玩家是否接近门(通过碰撞器检测)  
    private bool IsPlayerNearDoor()
    {
        // 假设玩家有一个名为PlayerTag的标签  
        Collider[] colliders = Physics.OverlapBox(doorCollider.bounds.center, doorCollider.bounds.size * 0.5f); // 使用门的中心和大小来检测碰撞体  
        foreach (Collider col in colliders)
        {
            if (col.CompareTag("Player")) // 检查碰撞体是否有"Player"标签  
            {
                return true; // 如果找到带有"PlayerTag"标签的碰撞体,则返回true  
            }
        }
        return false; // 如果没有找到,则返回false  
    }
}

这样就完成了,然后,如果不行的话善用debug.log()找一下哪里出问题了。

这就是今天的成果啦,祝好!

Unity中的物理触发器是一种用于检测物体之间接触的组件,它可以让我们在不影响物体移动的情况下检测到物体的接触,或者判断一个物体是否经过了某个区域[^1]。 在Unity中,我们可以通过以下步骤来使用物理触发器: 1. 添加碰撞体组件:首先,我们需要给物体添加一个碰撞体组件。可以选择使用Box Collider、Sphere Collider、Capsule Collider等不同类型的碰撞体,根据物体的形状和需求进行选择。 2. 设置触发器属性:在碰撞体组件的属性面板中,勾选Is Trigger选项。这样,碰撞体就会变成一个触发器,可以用于触发事件,并且会被物理引擎所忽略。 3. 编写触发器事件:在脚本中编写触发器事件的逻辑。可以使用OnTriggerEnter、OnTriggerStay和OnTriggerExit等函数来检测触发器的进入、停留和离开事件,并在这些事件中执行相应的操作。 下面是一个示例代码,演示了如何使用物理触发器来检测物体的接触: ```csharp using UnityEngine; public class TriggerExample : MonoBehaviour { private void OnTriggerEnter(Collider other) { Debug.Log("Trigger entered: " + other.gameObject.name); } private void OnTriggerStay(Collider other) { Debug.Log("Trigger staying: " + other.gameObject.name); } private void OnTriggerExit(Collider other) { Debug.Log("Trigger exited: " + other.gameObject.name); } } ``` 在上述示例中,当有物体进入触发器时,会在控制台输出"Trigger entered: 物体名称";当物体停留在触发器内时,会输出"Trigger staying: 物体名称";当物体离开触发器时,会输出"Trigger exited: 物体名称"。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椰椰燕麦奶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值