实现一个大多数的游戏场景中,靠近门之后,按下“F”键开门,再按下“F”键关门的效果。

这里要利用到触碰体(Trigger)和查找场景中物体的知识。

首先搞一个门出来,弄一个Cube随便捏扁就有了,不多说。

unity 2d 关节 unity2d开关门_ide

先大概的想想门是怎么开的。是绕它的一条左边(也可以是右边),做旋转。

可如果我们直接对门的transform组件中的rotate设置旋转,会变成什么样。

很明显,大家可以想到,会绕着门的中心点做旋转,这无疑不是我们想要的效果。

那么,怎么改变它的中心旋转呢。unity是不能直接改变物体的中心点的。

其实也很简单,我们只需要多加一个门轴(door shaft)就好了啊,我们可以新建一个空物体,名为doorshaft。然后把门(door)变成门轴的子物体,这样门轴旋转会带动门旋转,就能体现出门绕一边旋转的效果了。

ps:按住ctrl左键点击两个物体,

unity 2d 关节 unity2d开关门_ide_02

,Pivot会使中心点在前一个物体上面,Center则是会在两个物体中间。

unity 2d 关节 unity2d开关门_ide_03

unity 2d 关节 unity2d开关门_System_04

unity 2d 关节 unity2d开关门_unity 2d 关节_05

这里基本上实现了门的打开,接下来要做的是“靠近门才能开关门”。

没错,触碰体(Trigger)正适合做这样的事情。这里可以参考一下 uinty之碰撞体,触碰体,刚体 里的触碰体的解说。

触碰体在由物体进入它的collide范围之后,调用void OnTriggerEnter(Collider collider)方法,离开的时候调用 void OnTriggerExit(Collider collider)。

我们用一个空物体来做这个事情。新建一个空物体(命名为DoorTrigger),然后赋给他一个Box Collide,然后勾选

Is Trigger,再Edit Collide捏成差不多的大小,再把DoorTrigger摆放到合适位置就Ok了。

像下面这个就差不多了。

unity 2d 关节 unity2d开关门_ide_06

搞两个脚本,分别赋给DoorShaft一个名为叫Door的C#脚本,给DoorTrigger一个叫Trigger的C#脚本。

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

public class Trigger : MonoBehaviour
{
    private Door m_Door;
    private bool enterCollide = false;
    // Start is called before the first frame update
    void Start()
    {
        m_Door = GameObject.Find("Doorshaft").GetComponent<Door>();
    }


    void OnTriggerEnter(Collider collider)
    {
        Debug.Log("enter");
        enterCollide = true;
    }

    void OnTriggerExit(Collider collider)
    {
        Debug.Log("exit");
        enterCollide = false;
    }
    // Update is called once per frame
    void Update()
    {
        if (enterCollide)
        {
            if (Input.GetKeyDown(KeyCode.F))
            {
                if (m_Door.GetIsOpen())
                {
                    m_Door.CloseDoorMethod();

                }
                else
                {
                    m_Door.OpenDoorMethod();
                }
            }
        }
      
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Door : MonoBehaviour
{
    Transform tf;
    private bool isOpen = false;

    // Start is called before the first frame update
    void Start()
    {
        tf = gameObject.GetComponent<Transform>();
    }

    // Update is called once per frame
    void Update()
    {
    }

    public void OpenDoorMethod()
    {
            tf.Rotate(Vector3.up, 100);
            Debug.Log("close");
            isOpen = !isOpen;

    }
    public void CloseDoorMethod()
    {
            tf.Rotate(Vector3.up, -100);
            Debug.Log("open");
            isOpen = !isOpen;
    }

    public bool GetIsOpen()
    {
        return isOpen;
    }
    public void SetIsOpen(bool b)
    {
        isOpen = b;
    }
}

m_Door = GameObject.Find("Doorshaft").GetComponent<Door>();

这句是什么意思呢。通过GameObject的静态方法Find(String),可以在场景中找到名为“Doorshaft”的GameObject,直接调用这个GameObject中的组件Door(即Door.cs,C#脚本)。赋给m_Door;

这样就可以在触发体中获得门轴(Doorshaft)的对象了,然后在有物体进入触发体中,On TriggerEnter(Collide)被调用了的情况下,使用Door中的属性方法实现开门了。

unity 2d 关节 unity2d开关门_静态方法_07