zoukankan      html  css  js  c++  java
  • 通过射线与物体的交互

    1.鼠标平面拖拽物体

    Plane movePlane;
    float fixedDistance=2f;
    float hitDist, t;
    Ray camRay;
    Vector3 startPos, point, corPoint;
    
    void OnMouseDown (){
        startPos = transform.position; // save position in case draged to invalid place
        movePlane = new Plane(-Camera.main.transform.forward,transform.position); // find a parallel plane to the camera based on obj start pos;
    }
    
    void OnMouseDrag (){
        camRay = Camera.main.ScreenPointToRay(Input.mousePosition); // shoot a ray at the obj from mouse screen point
    
        if (movePlane.Raycast(camRay,out hitDist)){ // finde the collision on movePlane
            point = camRay.GetPoint(hitDist); // define the point on movePlane
            t=-(fixedDistance-camRay.origin.y)/(camRay.origin.y-point.y); // the x,y or z plane you want to be fixed to
            corPoint.x=camRay.origin.x+(point.x-camRay.origin.x)*t; // calculate the new point t futher along the ray
            corPoint.y=camRay.origin.y+(point.y-camRay.origin.y)*t;
            corPoint.z=camRay.origin.z+(point.z-camRay.origin.z)*t;
            transform.position = corPoint; 
        }
    }

    2.当射线碰撞目标为boot类型的物品 ,执行拾取操作(仅作参考)

        // Update is called once per frame
        void Update () 
        {
            if(Input.GetMouseButton(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//从摄像机发出到点击坐标的射线
                RaycastHit hitInfo;
                if(Physics.Raycast(ray,out hitInfo))
                {
                    Debug.DrawLine(ray.origin,hitInfo.point);//划出射线,只有在scene视图中才能看到
                    GameObject gameObj = hitInfo.collider.gameObject;
                    Debug.Log("click object name is " + gameObj.name);
                    if(gameObj.tag == "boot")//当射线碰撞目标为boot类型的物品 ,执行拾取操作
                    {
                        Debug.Log("pick up!");
                    }
                }
            }
        }

    3.重置物体位移方法,脱卡需要放到摄像机下

        public static void ResetPosition(GameObject ModelSelf, GameObject target, Vector3 parentOffset)
        {
            if (target == Camera.main.gameObject)
            {
                ModelSelf.transform.parent = target.transform;
                ModelSelf.transform.localPosition = Vector3.zero + parentOffset;
                ModelSelf.transform.localRotation = Quaternion.identity;
            }
            else
            {
                ModelSelf.transform.parent = target.transform;
                ModelSelf.transform.localPosition = Vector3.zero;
                ModelSelf.transform.localRotation = Quaternion.identity;
            }
        }

    4实例,小球找同颜色父物体

      

    完整代码

    using System.Collections;
    using UnityEngine;
    
    public class DragMeOnPlane : MonoBehaviour
    {
        Plane movePlane;
        float fixedDistance = 1f; //y aixs offset
        float hitDist, t;
        Ray cameraRay;
        Vector3 startPos, point, corPoint;
        public float xLimit = 3f;  //默认限制区域为3*3平面
        public float zLimit = 3f;
    
        public Transform initPosition;      //初始位置
        public Transform targetPosition;    //目标位置
    
        bool isFindParent = false;
    
        void OnMouseDown()
        {
            startPos = transform.position; // save position in case draged to invalid place
            movePlane = new Plane(-Camera.main.transform.forward, transform.position); // find a parallel plane to the camera based on obj start pos;
        }
    
        void OnMouseDrag()
        {
            cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition); // shoot a ray at the obj from mouse screen point
    
            if (movePlane.Raycast(cameraRay, out hitDist))
            {
                if (!isFindParent)
                {
                    // finde the collision on movePlane
                    point = cameraRay.GetPoint(hitDist); // define the point on movePlane
                    t = -(fixedDistance - cameraRay.origin.y) / (cameraRay.origin.y - point.y); // the x,y or z plane you want to be fixed to
    
                    var tempX = cameraRay.origin.x + (point.x - cameraRay.origin.x) * t;   // calculate the new point t futher along the ray
                    var tempZ = cameraRay.origin.z + (point.z - cameraRay.origin.z) * t;
                    corPoint.x = Mathf.Clamp(tempX, -xLimit, xLimit);
                    corPoint.z = Mathf.Clamp(tempZ, -zLimit, zLimit);
                    corPoint.y = cameraRay.origin.y + (point.y - cameraRay.origin.y) * t;
    
                    transform.position = corPoint; 
                }
                else
                {
                    transform.localPosition = Vector3.zero;
                }
            }
        }
    
        void OnTriggerEnter(Collider game)//测试是否触发触发器
        {
            print("Enter " + game.name);
    
            if(game.name.Equals(targetPosition.name))
            {
                isFindParent = true;
                Utility.ResetPosition(gameObject, targetPosition.gameObject, Vector3.zero);
            }
            else
            {
                isFindParent = true;
                Utility.ResetPosition(gameObject, initPosition.gameObject, Vector3.zero);
                StartCoroutine(ResetIsFindParent());
            }
        }
    
        IEnumerator ResetIsFindParent()
        {
            yield return new WaitForSeconds(1f);
            isFindParent = false;
        }
    }

     5物体碰撞知识参考 http://m.manew.com/thread-30342-1-1.html

  • 相关阅读:
    SQL 07: 外连接 (左连接和右连接查询)
    010 利用多线程使socket服务端可以与多个客户端同时通讯
    056 文件修改的两种方式
    009 模拟一个简单抢票小程序代码
    055 文件的高级应用
    054 with管理文件操作上下文
    008 通过开启子进程的方式实现套接字服务端可以并发的处理多个链接以及通讯循环(用到了subprocess模块,解决粘包问题)
    053 文件的三种打开模式
    052 绝对路径和相对路径
    051 基本的文件操作
  • 原文地址:https://www.cnblogs.com/JimmyCode/p/7428689.html
Copyright © 2011-2022 走看看