Unity中实现3D拾取功能及其原理
程序员文章站
2022-05-23 15:17:41
...
写在前面
3D拾取功能在实际项目开发中是一种非常常用的功能,尤其是在3D游戏中,拾取技术是必不可少的基础操作,拾取技术极大的增强了游戏的交互性。
3D拾取原理
简单的来说,3D拾取是通过屏幕上的一个点与摄像机的位置(摄像机控件原点)构成一条射线,然后与场景中物体进行相交,判断是否相交,进而进行拾取操作,这个相交判断的实际是射线与三角形的相交判断算法。在实际开发中,更多的使用包围盒等算法。想要深入了解3D拾取原理的同学,请点击。深入了解3D拾取原理。
Unity中简单实现3D拾取功能
1: 代码编写
(1) 发射一条射线: Ray ray = Camera.main.ScreenPointToRay(Touch.position);
(2) 检测撞到那个物体: Raycast hit; bool Physics.Raycast(ray, out hit);
(3) hit.transform, 获得物体的transform组件, name可以获得被碰撞的物体的名字;
(4) Camera.main获取当前我们的主Camera
(5) 如果要拾取,需要有一个碰撞器
2.源代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CatchScript : MonoBehaviour
{
private GameObject gameobj;
private bool CubeFlag = false;
private bool SphereFlag = false;
private bool CapsuleFlag = false;
public Texture2D texture;
void Start()
{
}
void Update()
{
//鼠标监听 是否点击
if (Input.GetMouseButtonDown(0))
{
//创建射线 Camera.main 只是代表tag标签为main camera 的摄像机 其可以替换为任何摄像机
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//创建碰撞体对象
RaycastHit hit;
//判断是否碰撞
if (Physics.Raycast(ray,out hit))
{
//打印拾取物体的名称
Debug.Log(hit.transform.name);
SetObj(hit.transform.name);
}
else
{
CubeFlag = false;
CapsuleFlag = false;
SphereFlag = false;
}
}
if (CubeFlag)
{
gameobj.GetComponent<Renderer>().material.mainTexture = texture;
gameobj.transform.Rotate(0, 10, 0);
}
if (SphereFlag)
{
gameobj.transform.Translate(0, 0.02f, 0);
}
if (CapsuleFlag)
{
gameobj.transform.Rotate(0, 10, 0);
}
}
void SetObj(string hitname)
{
switch(hitname)
{
case "Cube":
gameobj = GameObject.Find("Cube");
CubeFlag = true;
CapsuleFlag = false;
SphereFlag = false;
break;
case "Sphere":
gameobj = GameObject.Find("Sphere");
SphereFlag = true;
CubeFlag = false;
CapsuleFlag = false;
break;
case "Capsule":
gameobj = GameObject.Find("Capsule");
CapsuleFlag = true;
CubeFlag = false;
SphereFlag = false;
break;
default:
CubeFlag = false;
CapsuleFlag = false;
SphereFlag = false;
break;
}
}
}
3.将该脚本挂在对应摄像机上。
这样我们就在Unity中简单实现了3D拾取功能。