门窗吸附功能,是一个没有难度的小功能,但是如果想要实现的话,在脑子里猛一下却想不起来怎么实现,今天正好实现这个功能,所以记录一下。
分为两个脚本,分别为控制门移动的脚本,墙检测的脚本。
具体功能如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DoorAtt : MonoBehaviour
{
public static bool isMoveModelX = true;
public static bool isMoveModelZ = true;
public static bool isMove = false;
private Vector3 prePos;
private Vector3 curPos;
private Vector3 intervalPos;
private void Update()
{
if (isMove)
{
var vpos = Camera.main.WorldToScreenPoint(transform.position);
var vmouse = Input.mousePosition;
vmouse.z = vpos.z;
curPos = Camera.main.ScreenToWorldPoint(vmouse);
intervalPos = curPos - prePos;
transform.position += new Vector3(isMoveModelX ? intervalPos.x : 0, 0, isMoveModelZ ? intervalPos.z : 0);
prePos = curPos;
}
}
private void OnMouseDown()
{
isMove = !isMove;
var vpos = Camera.main.WorldToScreenPoint(transform.position);
var vmouse = Input.mousePosition;
vmouse.z = vpos.z;
prePos = Camera.main.ScreenToWorldPoint(vmouse);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WallAtt : MonoBehaviour
{
private List<string> interactiveTag = new List<string>(); //可以呗吸附的物体的tag
private Transform curModel = null; //目前被吸附的物体
private Vector3 dis;
private void Start()
{
interactiveTag.Add("Door");
var rigibody = transform.GetComponent<Rigidbody>();
if (rigibody == null)
{
rigibody = gameObject.AddComponent<Rigidbody>();
}
rigibody.isKinematic = true;
var vcollider = gameObject.AddComponent<BoxCollider>();
if (vcollider != null)
{
vcollider.isTrigger = true;
}
}
private void Update()
{
if (curModel != null)
{
if (DoorAtt.isMove)
{
if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1))
{
curModel = null;
DoorAtt.isMoveModelX = true;
DoorAtt.isMoveModelZ = true;
return;
}
var vModelPos = Camera.main.WorldToScreenPoint(curModel.position);
var vdis = vModelPos - (Input.mousePosition + dis);
if (Mathf.Abs(vdis.x) > 50 || Mathf.Abs(vdis.y) > 50)
{
Vector3 vePos = Camera.main.WorldToScreenPoint(curModel.position);
Vector3 mosPos = Input.mousePosition;
mosPos.z = vePos.z;
Vector3 WorldPos = Camera.main.ScreenToWorldPoint(mosPos);
var vNewPos = new Vector3(WorldPos.x, curModel.position.y, WorldPos.z);
curModel.transform.position = vNewPos;
DoorAtt.isMoveModelX = true;
DoorAtt.isMoveModelZ = true;
}
}
else
{
curModel = null;
}
}
}
private void OnTriggerEnter(Collider other)
{
if (interactiveTag.Contains(other.tag))
{
curModel = other.transform;
curModel.rotation = Quaternion.Euler(curModel.eulerAngles.x, transform.eulerAngles.y, curModel.eulerAngles.z); //物体的角度变成和墙壁一样的角度
if (transform.eulerAngles.y > 0)
{
curModel.position = new Vector3(transform.position.x, curModel.position.y, curModel.position.z);
DoorAtt.isMoveModelX = false;
DoorAtt.isMoveModelZ = true;
}
else
{
curModel.position = new Vector3(curModel.position.x, curModel.position.y, transform.position.z);
DoorAtt.isMoveModelX = true;
DoorAtt.isMoveModelZ = false;
}
var vModelPos = Camera.main.WorldToScreenPoint(curModel.position);
var vMousePos = Input.mousePosition;
dis = vModelPos - vMousePos;
}
}
private void OnTriggerExit(Collider other)
{
if (curModel != null)
{
curModel = null;
}
}
}