实现一个大多数的游戏场景中,靠近门之后,按下“F”键开门,再按下“F”键关门的效果。
这里要利用到触碰体(Trigger)和查找场景中物体的知识。
首先搞一个门出来,弄一个Cube随便捏扁就有了,不多说。
先大概的想想门是怎么开的。是绕它的一条左边(也可以是右边),做旋转。
可如果我们直接对门的transform组件中的rotate设置旋转,会变成什么样。
很明显,大家可以想到,会绕着门的中心点做旋转,这无疑不是我们想要的效果。
那么,怎么改变它的中心旋转呢。unity是不能直接改变物体的中心点的。
其实也很简单,我们只需要多加一个门轴(door shaft)就好了啊,我们可以新建一个空物体,名为doorshaft。然后把门(door)变成门轴的子物体,这样门轴旋转会带动门旋转,就能体现出门绕一边旋转的效果了。
ps:按住ctrl左键点击两个物体,
,Pivot会使中心点在前一个物体上面,Center则是会在两个物体中间。
这里基本上实现了门的打开,接下来要做的是“靠近门才能开关门”。
没错,触碰体(Trigger)正适合做这样的事情。这里可以参考一下 uinty之碰撞体,触碰体,刚体 里的触碰体的解说。
触碰体在由物体进入它的collide范围之后,调用void OnTriggerEnter(Collider collider)方法,离开的时候调用 void OnTriggerExit(Collider collider)。
我们用一个空物体来做这个事情。新建一个空物体(命名为DoorTrigger),然后赋给他一个Box Collide,然后勾选
Is Trigger,再Edit Collide捏成差不多的大小,再把DoorTrigger摆放到合适位置就Ok了。
像下面这个就差不多了。
搞两个脚本,分别赋给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中的属性方法实现开门了。