射线的吸附功能

需求:下方的四个物体需要吸附到上方的物体上,且吸附成功成为上方物体的子物体,且上方物体有且最多只能有一个子物体,吸附不成功下方物体返回到原位置。

注意:1.父物体下面的子物体的位置要考虑为localPosition

2.第九层为Plane,给Plane设置layer

3.OnMouseUp为最终状态,脑子记住这点很重要

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

public class IsXiFu : MonoBehaviour {
    private bool isMove = false;
    private Vector3 OldPos;

    private bool IsEnter = false;
    private bool IsExit = false;

    private Transform newParentTra;

	void Start () {
        OldPos = transform.position;
	}

	void Update () {
        if (isMove)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            //只和第九层检测
            if (Physics.Raycast(ray, out hit, 500f, 1 << 9))
            {
                Debug.DrawLine(ray.origin, hit.point, Color.red);
                transform.position = hit.point;
            }
        }
        
    }
    private void OnMouseDown()
    {
        Debug.Log("11111111111111111");
        Debug.Log("鼠标按下");
        isMove = true;
    }
    private void OnMouseUp()
    {
        Debug.Log("鼠标抬起");
        isMove = false;
        if (IsEnter)
        {
            Debug.Log("位置归零");
            transform.parent = newParentTra;
            transform.localPosition = new Vector3(0, 0, 0);
            //相对父级的位置用localPosition
            IsEnter = false;
            IsExit = false;
        }
        if (IsExit)
        {
            Debug.Log("回归原位置");
            transform.parent = null;
            transform.position = OldPos;
            isMove = false;
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.transform.tag == "Target")
        {
            if (other.transform.childCount==0)
            {
                IsEnter = true;
                Debug.Log("找到目标");
                newParentTra = other.transform;
            }
            else
            {
                Debug.Log("子物体已经被占用");
                IsExit = true;
            }
        }
    }

    private void OnTriggerExit(Collider other)
    {
        Debug.Log("物体拖出");
        
        IsExit = true;
    }
}

产生的问题,当鼠标按下物体的一瞬间,物体会产生小小的“震动”,这是物体的点和射线打击地面的点产生的偏差,下面我们将要求出偏差,代码如下:

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

public class IsXiFu : MonoBehaviour {
    private bool isMove = false;
    private Vector3 OldPos;

    private Vector3 screenSpace;
    private Vector3 offset;

    private bool IsEnter = false;
    private bool IsExit = false;

    private Transform newParentTra;

    //private Transform thistrans;
	// Use this for initialization
	void Start () {
        OldPos = transform.position;
        //Debug.Log(OldPos);
	}
	
	void Update () {
        if (isMove)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            //只和第九层检测
            if (Physics.Raycast(ray, out hit, 500f, 1 << 9))
            {
                Debug.DrawLine(ray.origin, hit.point, Color.red);
                //if (hit.collider.tag == "A")
                //{
                //打击点的位置
                Debug.Log("hit.point" + hit.point);
                //标签为A的位置
                Debug.Log("A的位置:" + transform.position);

                //将物体的世界坐标转换成屏幕坐标
                screenSpace = Camera.main.WorldToScreenPoint(transform.position);
                Debug.Log("hit.point的屏幕坐标" + screenSpace);
                //偏移值(世界坐标)=物体的坐标(世界坐标)-屏幕上的点的世界坐标
                offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z));
                Debug.Log("世界坐标下物体和屏幕坐标转成世界坐标的偏移量" + offset);
                
            }
        }
        
    }
    private void OnMouseDown()
    {
        Debug.Log("11111111111111111");
        Debug.Log("鼠标按下");
        isMove = true;
        //Debug.Log("鼠标按下的位置:"+Input.mousePosition);
    }
    private void OnMouseUp()
    {
        Debug.Log("鼠标抬起");
        isMove = false;
        if (IsEnter)
        {
            Debug.Log("位置归零");
            transform.parent = newParentTra;
            transform.localPosition = new Vector3(0, 0, 0);
            //相对父级的位置用localPosition
            IsEnter = false;
            IsExit = false;
        }
        if (IsExit)
        {
            Debug.Log("回归原位置");
            transform.parent = null;
            transform.position = OldPos;
            isMove = false;
        }
    }
    private void OnMouseDrag()
    {
        //屏幕上的点的坐标
        Vector3 currentScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
        Debug.Log("鼠标点击屏幕的坐标" + currentScreenSpace);
        //物体的当前位置=屏幕上的点的坐标转成世界坐标+偏移值
        Vector3 currentPos = Camera.main.ScreenToWorldPoint(currentScreenSpace) + offset;
        Debug.Log("1111鼠标点击屏幕的坐标转成世界" + currentScreenSpace);
        Debug.Log("2222应当到的位置" + currentPos);
        transform.position = currentPos;
    }
    //private void OnCollisionEnter(Collision collision)
    //{
    //    if (collision.transform.tag=="Target")
    //    {
    //        //Debug.Log("找到父亲");
    //        //Debug.Log(collision.transform.position);
    //        collision.gameObject.GetComponent<Renderer>().material.color = Color.blue;
    //        //Vector3 newVec = new Vector3(collision.transform.position.x, collision.transform.position.y * 2, collision.transform.position.z);
    //        //transform.position = newVec;
    //        Destroy(transform.GetComponent<BoxCollider>());
    //        //Destroy(collision.transform.GetComponent<BoxCollider>());
    //        transform.parent = collision.transform;
    //        transform.position = new Vector3(0, 0, 0);
    //        //Debug.Log(transform.position);
    //    }
    //}
    private void OnTriggerEnter(Collider other)
    {
        if (other.transform.tag == "Target")
        {
            if (other.transform.childCount==0)
            {
                IsEnter = true;
                Debug.Log("找到目标");
                ////Destroy(transform.GetComponent<BoxCollider>());
                newParentTra = other.transform;
            }
            else
            {
                Debug.Log("子物体已经被占用");
                IsExit = true;
            }
        }
    }

    private void OnTriggerExit(Collider other)
    {
        Debug.Log("物体拖出");
        IsExit = true;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41579634/article/details/83015888
今日推荐